Blog

Adaptative Layout ou la fin du design « Pixel Perfect »

Il fut un temps où la vie de développeur iOS était simple. Au lancement de l’Apple Store, il n’y avait qu’une seule taille d’écran iPhone et une seule résolution. Aujourd’hui les choses ont bien changé, et on retrouve sur le marché des appareils aux tailles différentes : iPhone 4, iPhone 5, iPhone 7, iPhone 7 Plus, iPad mini, iPad Air, iPad Pro…

Si en terme de version iOS, le marché n’est pas aussi fragmenté que pour Android, on ne peut pas en dire autant lorsqu’il s’agit de supporter les différentes tailles d’écrans. Cela est encore plus vrai, lorsque votre application est universelle, c’est à dire, qu’elle doit fonctionner sur iPhone et iPad. Et avec l’introduction du multitasking, les choses se sont encore compliquées puisqu’une application sur iPad, peut se retrouver à devoir partager l’écran (donc réduire sa taille d’écran) avec une autre application.

Voici une image (source Apple) qui résume bien la situation:

capture-decran-2016-12-13-a-12-41-33

Selon Apple, il y’a plus de 300 combinaisons possibles. Pour faire face à ce dilemme, avec iOS 8, Apple a introduit la notion de size classes et de traits collection. Dorénavant il ne s’agit plus de raisonner en taille d’écrans, avec un design au pixel près, ce qui devenait impossible au vu des éléments précédents, mais en terme de layout, c’est à dire de bloc d’affichage (pour faire simple).

Voici ce que cela donne:

size_classes

Il existe deux notions de bloc Compact (réduit) ou Regular (normal) sur la largeur/hauteur permettant de caractériser un appareil. Ce changement est fondamental, car il ne faut plus raisonner en terme de Device (je développe pour un iPhone 5, un iPhone 6…) et donc j’établis un design pour ce device, mais en terme de layout : que donne mon design dans une vue compact/compact, compact/regular (cf image précédente)…

D’ailleurs pour une application, il n’est plus possible de savoir sur quel appareil, elle s’exécute (en terme de design) mais uniquement quelle est la configuration de size class. L’exemple le plus parlant est celui des iPads, qui fonctionne en Regular/Regular. Or un iPad PRO et un iPad Retina, n’ont pas la même taille d’écran (en terme de résolution). Si vous souhaitez concevoir un design différent (ou au pixel prés) pour un iPad Pro et un iPad Retina, ce n’est tout simplement pas envisageable, puisqu’il est impossible pour le développeur de les différencier.

Bien entendu certains diront qu’il est possible de récupérer dans le code, le type d’appareil et de faire des traitements appropriés spécifique (par exemple charger un storyboard (interface dans laquelle on crée le design de l’application)), ou pire encore de modifier des propriétés dans le code à coup de if…then…else. Je vous laisse imaginer la maintenabilité et le coût…

Voilà donc pourquoi il est temps de passer à ce que l’on appelle l’adaptative design.

Voici quelques articles (en anglais) pour approfondir le sujet:
Article
Article
 

Christophe, Freelance iOS

Se faciliter la vie en tant que freelance iOS : Awesome iOS

Lorsque l’on développe (en général) le temps est quelque chose de précieux, et si il y’a bien une chose qu’il faut éviter, c’est de ré-inventer la roue. Aussi avant de me lancer dans un développement, je regarde toujours ce qui est existe déjà. Pour cela, voici un site très pratique, recensant la liste des composants (souvent open source) existants pour iOS, le tout organisé par catégories (Location, Photos, Vidéos…). De plus, cette liste est mise à jour régulièrement avec les nouveautés de la semaine ou du mois.

Sinon  plus connu, cocoacontrols propose la même chose mais de façon moins pratique.

Enjoy.

Christophe Surbier, Freelance iOS

Upload d’une photo avec Django Rest Framewok

Extrait de mon livre : Développer un back-end pour app mobile avec Django

En tant que développeur iOS, il m’est souvent fréquent de vouloir envoyer une photo de mon application mobile vers mon back-end, pour cela, il est possible d’utiliser Django Rest Framework, contrairement à ce que l’on peut souvent lire. Pour ce faire, rien de plus simple. Il vous suffit de définir dans votre sérialiseur, le champ de votre modèle qui contient la photo.

Par exemple:

 class AppUserSerializer(serializers.ModelSerializer):
    picture = serializers.ImageField(max_length=None, use_url=True)
    class Meta:
       model = AppUser
       fields = '__all__'

De plus, DRF (Django Rest Framework) vérifiera que le paramètre picture envoyé est bien une image, sinon il vous retournera une erreur.

Depuis votre application mobile, il suffit de poster un formulaire multi-part classique. Par exemple, en Swift voici comment faire:

 func sendPhoto() {
        let monImage = UIImage(named: "logo")!
        let imageData : Data = UIImagePNGRepresentation(monImage)! as Data!
        let headers = [
            "Authorization": "oAuth: 8rPwO5833I74M9u6TuI8KNYKfkIqlB",
            "Content-Type":"application/json"
        ]
        let parameters = [
            "email": "christophesurbier@idevotion.fr",
            "password": "80b1509ea37643250da601f2d24fe9b236b76fd3a3d7d18498d760cdd38813b2",
            "pseudo": "csurbier2",
            "firstName" : "christophe",
            "lastName":"Surbier",
            "street":"10 boulevard de magenta",
            "city":"Paris",
            "country":"France",
            "location":"{\"type\": \"Point\", \"coordinates\": [2.1711730954009556,41.384021579093975]}",
            "valide":"1"
        ]
        Alamofire.upload(
            multipartFormData: { multipartFormData in
                for (key, value) in parameters {
                    multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
                }
                // Image
                multipartFormData.append(imageData, withName: "picture", fileName: "photo.png", mimeType: "image/png")
        },
            to: "http://votrenomdedomaine/api/appuser/",
            method:.post,
            headers:headers,
            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON { response in
                        debugPrint(response)
                    }
                case .failure(let encodingError):
                    print(encodingError)
                }
        }
        )
    }

Christophe Surbier, Freelance iOS

Réalisation d’un backend dans le cloud pour application mobile (Part 2)

Update décembre 2016: Découvrez mon livre sur le développement de backend pour application mobile avec Django

Après avoir vu dans la partie 1 comment créer un backoffice et déployer rapidement dans le cloud grâce à un simple commit GIT, nous allons maintenant mettre en place la partie la plus intéressante à savoir l’API qui sera utilisée par nos applications mobile.

La première étape va être de sécuriser notre API avec oAuth2. Commençons donc par ceci.

Continue Reading…

Réalisation d’un backend dans le cloud pour application mobile (Part 1)

Update décembre 2016 : Découvrez mon livre sur le développement de backend pour application mobile avec Django

Dans ce billet nous allons voir comment mettre en place un backend dans le cloud de manière très simple, rapide et qui offrira une API sécurisée à vos applications mobiles (avec la documentation associée) et un backoffice d’administration.
Pour cela, nous allons utiliser une architecture reposant sur les services de Clever Cloud (plus d’infos ici :https://www.clever-cloud.com). Ainsi vous pouvez rester concentré sur votre coeur de métier (le développement des features de votre application), et laisser tout le reste (serveurs, montée en charge, administration, surveillance…) à la charge de Clever Cloud dont c’est le métier. Notre backend sera lui développé en Python Django.

Mais avant de rentrer dans le vif du sujet, décrivons déjà en quoi consistera notre backend. Pour faire quelque chose d’utile et de très courant, nous allons gérer des utilisateurs qui seront capables de voir les villes autour d’eux et d’en ajouter dans leur favori.

Ok?, c’est parti !

Continue Reading…