Comment générer le retour haptique avec UIFeedbackGenerator

Disponible à partir d’iOS 10.0

La technologie 3D Touch introduit par Apple le 9 septembre 2014 lors de la présentation de l’Apple Watch. Puis disponible sur un iPhone, depuis la version 6S et 6S Plus. Indisponible aux développeurs jusqu’à lors.

iOS 10 introduit de nouvelles façons de générer un retour haptique en utilisant des modèles de vibration prédéfinis partagés par toutes les applications, aidant ainsi les utilisateurs à comprendre que les différents types de commentaires portent une signification particulière. Le noyau de cette fonctionnalité est fournie par UIFeedbackGenerator, mais qui est juste une classe abstraite – les trois classes qui vous intéressent vraiment sont UINotificationFeedbackGenerator, UIImpactFeedbackGenerator et UISelectionFeedbackGenerator.

Le premier de ceux-ci, UINotificationFeedbackGenerator, vous permet de générer des retours sur la base de trois événements système: erreur, le succès, et d’avertissement.

Le second, UIImpactFeedbackGenerator, vous permet de générer légère, moyenne, et des effets lourds que Apple dit fournir une « métaphore physique qui complète l’expérience visuelle. »

Enfin, UISelectionFeedbackGenerator génère une rétroaction qui doit être déclenché lorsque l’utilisateur est en train de changer leur sélection sur l’écran, par exemple se déplaçant à travers un PickerView.

A ce jour, seul le nouveau moteur Taptic trouvé dans l’iPhone 7 et iPhone 7 Plus supporte ces API. Les autres appareils ignorent silencieusement les demandes haptiques.

Pour commencer à essayer ces API, créez un modèle SingleViewApplication dans Xcode, puis remplacer le ViewController avec ce code en swift:

import UIKit

class ViewController: UIViewController {
    var i = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        let btn = UIButton()
        btn.translatesAutoresizingMaskIntoConstraints = false

        btn.widthAnchor.constraint(equalToConstant: 128).isActive = true
        btn.heightAnchor.constraint(equalToConstant: 128).isActive = true
        btn.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        btn.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

        btn.setTitle("Tap here!", for: .normal)
        btn.setTitleColor(UIColor.red, for: .normal)
        btn.addTarget(self, action: #selector(tapped), for: .touchUpInside)

        view.addSubview(btn)
    }

    func tapped() {
        i += 1
        print("Running \(i)")

        switch i {
        case 1:
            let generator = UINotificationFeedbackGenerator()
            generator.notificationOccurred(.error)

        case 2:
            let generator = UINotificationFeedbackGenerator()
            generator.notificationOccurred(.success)

        case 3:
            let generator = UINotificationFeedbackGenerator()
            generator.notificationOccurred(.warning)

        case 4:
            let generator = UIImpactFeedbackGenerator(style: .light)
            generator.impactOccurred()

        case 5:
            let generator = UIImpactFeedbackGenerator(style: .medium)
            generator.impactOccurred()

        case 6:
            let generator = UIImpactFeedbackGenerator(style: .heavy)
            generator.impactOccurred()

        default:
            let generator = UISelectionFeedbackGenerator()
            generator.selectionChanged()
            i = 0
        }
    }
}

Lorsque vous exécutez que sur votre téléphone, en appuyant sur le « Tap here ! » vous aurez les retours haptique par ordre.

Car cela peut prendre un peu de temps au système pour préparer le retour haptique, Apple recommande d’appeler la méthode prepare() avant de déclencher l’effet haptique. Si vous ne le faites pas, il y aura un léger décalage entre l’effet visuel et haptique correspondant, cela peut dérouter certains utilisateurs.

Apple demande expressément d’utiliser judicieusement le retour haptique des iPhone, afin d’éviter une mauvaise expérience utilisateur. De plus n’oubliez pas les anciens iPhone !

Cloudinary iOS SDK

Je reviens depuis un long moment d’absence avec un petit service très utile. Je vais vous présenter le SDK iOS Cloudinary. Cloudinary est un service cloud qui offre une solution pour la gestion des images. Ce service vous propose bien sûr d’uploader vos images sur le cloud et ensuite de récupérer facilement et rapidement (Cloudinary met en place un cache pour toutes vos requêtes) une image dans un format différent. Je m’explique, vous allez pouvoir récupérer votre image dans une taille différente, respectant le ratio de votre image ou en centrant dans votre image. L’api vous propose de créer un thumbnail en centrant sur le visage, puisqu’il contient un détecteur de visage automatique.

Comment installer le sdk cloudinary pour ios

Installation

Vous pouvez vous rendre sur le repository GitHub pour télécharger la dernière version du SDK (1.0.14). Attention, je leur ai proposé un fix car il faut cloner le repository en local pour ajouter dans les headers le CLLayer.h non inclus. Sans ce dernier vous n’arriverez pas à compiler.
Ou bien passer par cocoapods (non mentionné dans leur doc).

Configuration

Vous devez posséder un compte (gratuit). Si ce n’est pas encore le cas rendez-vous ici.

Il ne vous reste plus qu’a créer un objet CLCloudinary avec vos identifiants.

#import "Cloudinary.h"

CLCloudinary *cloudinary = [[CLCloudinary alloc] initWithUrl: @"cloudinary://123456789012345:abcdeghijklmnopqrstuvwxyz12@n07t21i7"];

Qui correspond de façon plus détaillé à :

CLCloudinary *cloudinary = [[CLCloudinary alloc] init];
[cloudinary.config setValue:@"n07t21i7" forKey:@"cloud_name"];
[cloudinary.config setValue:@"123456789012345" forKey:@"api_key"];
[cloudinary.config setValue:@"abcdeghijklmnopqrstuvwxyz12" forKey:@"api_secret"];

Maintenant que vous êtes connecté avec Cloudinary il ne reste plus qu’a récupérer votre première image. Imaginons que vous voulez récupérer une image qui s’appelle sample.jpg

NSString *url = [cloudinary url:@"sample.jpg"];

// http://res.cloudinary.com/n07t21i7/image/upload/sample.jpg

Mais le plus intéressant est à venir. Comme je vous l’ai dit plus haut, Cloudinary propose un service de transformation de votre image.

CLTransformation *transformation = [CLTransformation transformation];
[transformation setWidthWithInt: 100];
[transformation setHeightWithInt: 150];
[transformation setCrop: @"fill"];

NSString *url = [cloudinary url:@"sample.jpg" options:@{@"transformation": transformation}];

// http://res.cloudinary.com/n07t21i7/image/upload/c_fill,h_150,w_100/sample.jpg

Pour upload votre image vous devez faire comme suit.

Créer un object CLUploader à partir de votre CLCloudinary. Puis uploader votre image soit en NSData soit avec le pathURL.

CLUploader* uploader = [[CLUploader alloc] init:cloudinary delegate:self];
NSData *imageData = NSData *imageData = UIImageJPEGRepresentation(image, 1); // image est une UIImage
[uploader upload:imageData options:@{@"public_id": @"nom_image"}];
@interface ViewController () <CLUploaderDelegate>
@end

@implementation ViewController

...

- (void) uploaderSuccess:(NSDictionary*)result context:(id)context {
    NSString* publicId = [result valueForKey:@"public_id"];
    NSLog(@"Upload success. Public ID=%@, Full result=%@", publicId, result);
}

- (void) uploaderError:(NSString*)result code:(int) code context:(id)context {
    NSLog(@"Upload error: %@, %d", result, code);
}

- (void) uploaderProgress:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite context:(id)context {
    NSLog(@"Upload progress: %d/%d (+%d)", totalBytesWritten, totalBytesExpectedToWrite, bytesWritten);
}

@end

Tarification

Avec un compte gratuit vous allez pouvoir stocker 75,000 images et videos avec 7,500 transformations. Vous avez besoin de plus ? Le reste c’est ici.

Résumé

Je trouve se service bien complet. Le SDK malgré le peu de documentation est très simple d’intégration et d’utilisation. Je suis justement en train de l’intégrer dans l’application que je développe en ce moment.

Qu’en pensez-vous ? Allez-vous l’intégrer dans vos applications ? Dites-moi tout dans les commentaires.

Apple Watch Simulateur

Le 19 novembre 2014, Apple lança enfin son SDK pour l’Apple Watch !
Ni une ni deux, je télécharge le Xcode beta 6.2 avec iOS 8.2 et je commence une nouvelle extension Apple Watch. Juste pour voir ce que ça donne dans le simulateur, je sélectionne la target et je cherche après l’Apple Watch simulateur… il n’y en a pas ! Il faut absolument passer un device sous iOS 8.2 ! Trop tôt ! Avec ce qu’on a vu comme problème depuis la sortie du 8.0 Merci mais je vais attendre.

Bon il ne reste plus qu’une solution : Créer un simulateur pour Apple Watch !

Aussitôt dit, je l’ai fait et le propose à la communauté pour que vous aussi vous puissiez préparer vos prototypes d’applications Apple Watch !

interfacebuilder

Vous le trouverez sur mon compte GitHub : https://github.com/Jean-PhilippeDESCAMPS/AppleWatchSimulateur

N’hésitez pas a donner votre avis dans les commentaires !

Popping

Très à la mode en ce moment, j’en ai déjà fait une présentation ici, le framework pop de Facebook est très simple à prendre en main, mais certain nous montre comment l’utiliser en affichant quelques exemples.

Grâce à Popping est une collection d’exemples d’animation pour les applications iOS. La quasi-totalité d’entre elles ont été créés en utilisant le moteur d’animation pop Facebook.

 

 

FlatUIKit

On a tous eu un jour le même problème quand on est développeur, nos interfaces sont ultras moches ! (Dans 90% des cas)

Aujourd’hui, grâce au flat design on réussit un peu mieux à faire des jolies choses… Enfin, ça reste moche mais au moins c’est flat ^_^

FlatUIKit vient à notre secours : https://github.com/Grouper/FlatUIKit. Basé sur les couleurs (Flat UI Colors) et les principes du flat design.

Avec cette librairie, je ne vais pas dire fini les soucis, mais au moins fini le temps passé à custom une classe UIButton (par exemple) pour en faire un bouton flat avec des bords arrondis et un effet au touch.

68747470733a2f2f7261772e6769746875622e636f6d2f47726f757065722f466c617455494b69742f6d61737465722f4578616d706c652f524541444d45253230696d616765732f667569627574746f6e2d736d616c6c2e676966

D’autres éléments sont disponibles comme un UIPopoverController :

68747470733a2f2f7261772e6769746875622e636f6d2f47726f757065722f466c617455494b69742f6d61737465722f4578616d706c652f524541444d45253230696d616765732f667569706f706f766572636f6e74726f6c6c65722d736d616c6c2e676966

Autre Framework Paper : Shimmer

shimmer.gifAujourd’hui, on reparle d’une librairie proposer par Facebook. Après la librairie pop qui propose des animations pour iOS et OSX, je vous propose de s’arrêter sur Shimmer, ou en français scintiller. Très simple à mettre en place, quelques lignes de code, elle ne sera pas utile pour tous vos projets mais je trouvais intéressant de vous montrer tout ce que peut nous proposer Facebook en ce moment en rapport avec leur dernière application Paper

FBShimmeringView *shimmeringView = [[FBShimmeringView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:shimmeringView];

UILabel *loadingLabel = [[UILabel alloc] initWithFrame:shimmeringView.bounds];
loadingLabel.textAlignment = NSTextAlignmentCenter;
loadingLabel.text = NSLocalizedString(@"Shimmer", nil);
shimmeringView.contentView = loadingLabel;

// Start shimmering.
shimmeringView.shimmering = YES;

Très simple non ?

A part pour faire comme le lock screen d’apple, pensez-vous mettre en place un jour cette lib dans l’un de vos projets futurs ?

Framework Paper (pop)

pop.gif

Pop est un moteur d’animation extensible pour iOS et OS X. L’API permet une intégration rapide avec les bases de code existants Objective-C et permet à l’animation d’un bien sur n’importe quel objet. Ce framework est testé et approuvé par l’application Paper.

C’est ce que Facebook nous propose avec cette librairie disponible sur leur compte github. L’application Paper est aujourd’hui disponible au pays de l’oncle sam.  Apparemment, pop est également utilisée dans l’application Facebook pour toutes les animations (zoom, déplacements de photos,…)

Le code est relativement rapide à mettre en place et il est possible de lier une animation à n’importe quel objet existant. Je vous propose donc de revenir vers vous plus tard avec un projet qui incluera les superbes animations de cette lib. 

N’hésitez pas à mettre dans les commentaires les apps que vous avez développé qui utilise ce framework.

Comment résoudre le problème de distribution OTA sur son serveur

Un titre assez long mais que veut dire ce qu’il veut dire…
Depuis la mise à jour en 7.1, iOS n’accepte plus l’installation d’application en OTA si le serveur n’est pas sécurisé en SSL (https).

Alors comment résoudre ce problème sans passer à la caisse auprès de nos hosteurs préférés ?

La méthode dropbox

Je l’ai trouvé sur plusieurs forum et j’ai pu la mettre en place facilement et très rapidement avec mon application.

En gros la méthode est la même que d’habitude mais moins automatique. Pour que le téléchargement fonctionne il faut que le .plist soit sur un serveur sécurisé. Cela se passe en 3 étapes :
– créez votre ipa et votre plist
– upload votre ipa sur votre serveur
– mettre le plist sur dropbox et récupérer le lien publique (ex: )
– remplacer le lien sur votre balise a avec le lien dropbox en changeant « https://www.dropbox.com/s/zu32i0gdczec262/application.plist » par « https://dl.dropboxusercontent.com/s/zu32i0gdczec262/application.plist »

Et vous, quelles solutions avez-vous trouvé ? Dites-le dans les commentaires.

Reconnaissance des visages

En parcourant un peu le SDK iOS 5.0 je suis tombé sur une fonctionnalité très intéressante, qui pourrait être très utile dans un avenir proche.

Il est possible en utilisant le Framework Core Image de faire de la reconnaissance faciale. L’application que j’ai réalisé pour ce test est très simple, elle permet de mettre une moustache à chaque visage détecté. Voici ce que ça donne en image.

20120813-091549.jpg

Je vous l’accorde, moi je n’ai pas besoin qu’on me rajoute de moustache 😉

Problème à la validation apple d’une application iPhone à cause d’une icone

La dernière mise à jour du Lion (aka 10.7.3), disponible depuis hier, rompt la validation des icones. Avec cette mise à jour,vous ne serez pas en mesure de valider, ni soumettre votre application à travers Xcode et aussi par Application Loader. En fait, vous ne serez pas en mesure de présenter une application sur l’App Store.

Si lors de la compilation de votre application, ou en essayant de vous soumettre application, vous rencontrer ce problème:

Ne paniquez pas, enfin pas comme moi 🙂

La solution de contournement, comme décrit sur ​​le forum Apple iOS, est de télécharger la dernière version de Application Loader. Une fois que vous l’avez téléchargé, lancez Application Loader, vérifiez que la version 2.5.1 est (235). Relancez votre projet Xcode, cleaner-le et archiver-le. L’avertissement de validation icône disparait et vous êtes en mesure de soumettre des applications à nouveau.