Realm, CoreData killer
Realm, CoreData killer
Sommaire
Je voulais partager avec vous un retour d’expérience sur ma première application IOS. Personnellement, j’apprécie ce genre d’article car je peux facilement m’identifier à celui-ci.
En ce moment, je travaille ma montée en compétence sur Swift 3/Xcode et donc comme on le sait tous, quand on apprend un nouveau langage c’est bien beau de savoir faire une boucle et des méthodes, mais il n’y a rien de mieux qu’un vrai projet pour valider ses acquis et monter en xp.
Le premier “problème", c’est de trouver une idée sur laquelle travailler. En effet, je ne suis pas très fan des to do lists que je trouve sans grand intérêt. Mais c’est là justement que ça se complique : trouver une idée est la chose la plus difficile :( (coder est tellement plus simple à côté :) ). Bon, je vous rassure après quelques jours j’ai trouvé un sujet assez intéressant. Sur mon fil d’actualité Facebook je n’arrête pas de voir un petit “jeu” de quizz concernant des calculs mentaux (je ne sais pas si vous avez déjà vu ce genre de publication mais c’est très addictif). J’ai trouvé l’idée mais...
Mais je ne vais pas faire une app sans un minimum de graphisme, non ? À ce moment là, je me dis, "autant faire une belle app pour la montrer à mon entourage…" Car il faut être honnête, la majorité des gens à qui je vais montrer cette application se contre-fiche de mon code #vieMaVieDeDev :), et par conséquent ils vont juger mon travail plus sur le côté interactif et graphique que sur mon code.
Suite à cela, je me suis encore posé une question : avec quel outil vais-je faire mon design ? Sur un photoshop, ou bien existe t-il une autre solution plus adaptée et plus simple ? C’est là que j’ai entendu parler de Sketch app. Et voilà pourquoi j’ai choisi d’utiliser cet outil pour réaliser mes maquettes :
Après avoir visionné quelques tutos vidéos pour apprendre les bases, j’ai pu réaliser les maquettes de mon application. Cependant, j’ai relevé plusieurs points très intéressants sur la partie graphique :
Aperçu de mes maquettes :
Je ne vais pas trop m’attarder sur cette partie car ce n’est pas vraiment le but de cet article. Pour la faire courte, j’ai juste mis en place un symfony 3.* avec un controller qui retourne une réponse en json. Cette réponse est un tableau de questions qui contient pour chacune des questions sa réponse et les liens d'images.
Bon on rentre enfin dans le vif du sujet !
Avant d’attaquer mon application, je me suis posé un peu (oui ça m’arrive :) ) et j’ai porté ma réflexion sur ce dont j’avais besoin, ce que j’allais utiliser, comment j’allais découper mon code…
Cocoapods :
Qu’est-ce que cocoapods ? C’est un gestionnaire de dépendance comme npm, composer, yarn…
J’ai besoin de cocoapods car je souhaite inclure deux librairies à mon projet, à savoir :
Pour ajouter les deux librairies, il vous suffit de créer un fichier Podfile à la racine de votre projet et d’ajouter ces petites lignes :
# Podfile # Uncomment the next line to define a global platform for your project # platform :ios, '9.0' platform :ios, '10.0' target 'GeniusApp' do # Comment the next line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for GeniusApp pod 'Alamofire', '~> 4.0' pod 'AlamofireImage', '~> 3.1' end
Puis de faire un :
$ pod install
Model :
Au lieu d'avoir tout mon code métier dans mes controllers (pas bien ça !!), j’ai décidé de mettre un peu de logique dans des model afin d’isoler mon code pour notamment le tester plus facilement...
Exemple :
// Model/Party.swift
import Foundation
class Party {
let BASE_SCORE = 0
let BASE_LIFE = 3
var score:Int = 0
var life:Int = 3
func addScore() {
self.score += 1
}
func getScore() -> String {
return "x \(self.score)"
}
func getLife() -> String {
return "\(self.life)"
}
func killLife() {
if isGameOver() {
return;
}
self.life -= 1
}
func isGameOver() -> Bool {
return self.life < 1
}
func resetData() {
self.life = BASE_LIFE
self.score = BASE_SCORE
}
}
ViewController :
Au lieu de vous montrer en détail mes ViewControllers, je vais vous parler de quelques parties que je trouve intéressantes.
Pour commencer, j’ai rencontré plusieurs “soucis” avec le clavier :
Ensuite, pour compliquer encore un peu plus les choses, j’ai décidé d'utiliser un clavier de type “number pad” pour améliorer l’expérience utilisateur. Toutefois, le soucis avec ce type de clavier est qu’il n’y a pas de bouton dit “return”. A noter : Si vous souhaitez que lorsque votre utilisateur clique sur le label "??" cela déclenche un événement de type touch il suffit de changer son attribut isUserInteractionEnabled = true afin de délivrer les événements de type touch et keyboard à la vue.
Je souhaite que lorsque mon utilisateur clique sur ma cellule cela déclenche l’activation de mon clavier.
// Controller/ViewController.swift
let click = UITapGestureRecognizer(target: self, action: #selector(self.showKeyboard))
cell.addGestureRecognizer(click)
Dans la méthode showKeyboard()
, je fais appel à une autre méthode addDoneButtonOnKeyboard()
qui permet d’ajouter un bouton "Envoyer" sur le clavier.
// Controller/ViewController.swift // let doneToolbar: UIToolbar = UIToolbar() func addDoneButtonOnKeyboard() { doneToolbar.barStyle = UIBarStyle.default let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil) let done: UIBarButtonItem = UIBarButtonItem(title: "Envoyer", style: UIBarButtonItemStyle.done, target: self, action: #selector(self.doneButtonAction)) var items = [UIBarButtonItem]() items.append(flexSpace) items.append(done) doneToolbar.items = items doneToolbar.sizeToFit() }
J’ai d'abord initialisé une constante de type UIToolbar pour pouvoir y accéder à un autre moment dans le code. Une fois la Toolbar initialisée, je souhaite lui ajouter le bouton "Envoyer" (UIBarButtonItem).
Cependant, il faudrait que celui-ci se situe tout à droite de la Toolbar car par défaut il se place tout à gauche. Pour y remédier, j’ai donc créé un bouton flexSpace qui ne fait rien mais qui va cependant permettre d’avoir le bouton à droite. Je n’ai plus qu'à ajouter lesdits boutons à ma Toolbar.
Attention : il ne faut pas oublier aussi d'ajouter la Toolbar au clavier via :
// Controller/ViewController.swift {UITextField}.inputAccessoryView = doneToolbar
La propriété inputAccessoryView est utilisée pour attacher une vue accessoire (ici, notre UIToolbar) au clavier qui est présentée par UITextField.
Pour résoudre le deuxième "problème", je vous avoue que j'ai opté pour la solution la plus simple mais qui marche parfaitement bien. J'ai donc créé deux méthodes qui me permettent de faire un "scroll" sur ma vue.
// Controller/ViewController.swift
if self.view.frame.origin.y < 0.0 {
if UIScreen.main.bounds.size.height < 600 {
self.view.frame.origin.y += 285
return
}
self.view.frame.origin.y += 180
}
// And
if self.view.frame.origin.y >= 0.0 {
if UIScreen.main.bounds.size.height < 600 {
self.view.frame.origin.y -= 285
return
}
self.view.frame.origin.y -= 180
}
J'ai dû rajouter un petit "hack" car sur l'Iphone 5 il me faut un plus grand scroll. C'est une des parties de mon code qui je pense demande une refacto (si vous avez des suggestions je suis bien évidemment preneur).
Extension :
Une des choses qui me plait le plus en Swift, ce sont les extensions ! J'ai donc pensé à en faire une pour la partie téléchargement d'une image depuis une url.
// Extensions/UIImageViewExtension.swift
import UIKit
import Alamofire
import AlamofireImage
extension UIImageView {
func getUIImageViewByUrl(url: String) {
Alamofire.request(url).responseImage { response in
if let image = response.result.value {
self.image = image
}
}
}
}
``
Je n'ai plus qu'à appeler celle-ci dans mon ViewController:
```swift
// Controller/ViewController.swift
cell.image.getUIImageViewByUrl(url: url)
J'ai pris énormément de plaisir à coder cette application (c'est le plus important je pense). Avant de me lancer, j'avais pas mal d'a priori et je me disais "cette partie va être dure... ; comment je vais gérer ça..." Et finalement, pour chaque problème rencontré, j'ai su trouver des solutions. Alors oui, mon application n'est pas hyper optimisée et elle demande surement une refacto générale mais j'ai tellement appris de choses qu'on ne voit pas dans un tuto :). Ce que je retiens de ma toute première application sous IOS, c'est que j'apprécie vraiment de faire du mobile, que je prends du plaisir à coder sous Swift et qu'il ne faut pas avoir peur de se lancer. Alors j'espère qu'en lisant cet article, ça va tenter certaines personnes à se lancer sur cette voie.
P.S. : Merci aux Pandas pour les relectures
Auteur(s)
Ilan Benichou
Développeur Fullstack (PHP/JS/IOS/DEVOPS), j'adore découvrir de nouvelle chose, toujours prêt à relever un challenge.
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Rendez plus robuste votre application mobile en ajoutant des tests fonctionnels
Nous allons découvrir un outil qui permet d'automatiser des tâches fastidieuses en mobile.