Il y a 2 années · 6 minutes · iOS, Mobile

WatchKit Episode III – Glances et notifications

Souvenez-vous, dans notre précédent article nous vous expliquions comment réaliser une application WatchKit avec Swift. Aujourd’hui nous allons vous montrer comment embellir celle-ci avec deux nouvelles fonctionnalités : les Glances et les notifications !

Les Glances

Les Glances sont une spécificité WatchKit : elles permettent d’afficher, au travers d’une vue unique, les informations importantes de l’application. C’est en quelque sorte une version minimale de l’application WatchKit (elle-même étant déjà une version minimale de l’application iOS…). Chaque application possède un seul et unique Glance sur lequel on ne peut configurer aucune interactivité : tout clic dessus ouvre automatiquement l’application WatchKit associée.

Pour ce tutoriel nous allons créer un Glance très simple : afficher de manière aléatoire les informations d’une station de ski. Ouvrez tout d’abord le storyboard. Celui-ci contient déjà une vue pour votre Glance. Si ce n’est pas le cas, ajoutez un Glance Interface Controller à votre storyboard pour le voir apparaître.

watchkit

Configurez-le ensuite afin d’obtenir un résultat similaire à l’image ci-dessous. Attention cependant à quelques points :

  1. Pour des raisons obscures et inconnues un Glance ne se configure pas comme les autres vues : il ne peut posséder que deux enfants (Upper et Lower) avec des formats et des tailles bien définies
  2. Dans Xcode 6.2 beta, évitez de décocher la case « Installed » pour Upper ou Lower, cela ne semble pas possible pour le moment et fait planter Xcode

watchkit

 

Créez un WKInterfaceController avec le nom GlanceController, ajoutez-y vos IBOutlets, et reliez le tout dans dans votre storyboard.

class GlanceController: WKInterfaceController {
    @IBOutlet weak var temperatureLabel: WKInterfaceLabel!
    @IBOutlet weak var titleLabel: WKInterfaceLabel!
    @IBOutlet weak var dateLabel: WKInterfaceDate!

Puis ajoutez le code pour afficher les données de la station de ski :

 private let dataSource : WebcamDataSource

    override init() {
  // (1) On récupère la liste des stations de ski
        self.dataSource = WebcamDataSource()
    }

    override func willActivate() {
        super.willActivate()

  // (2) On choisit une station de ski au hasard
        let index = Int(arc4random()) % (self.dataSource.count - 1) 
        let skiResort = self.dataSource[index]

  // (3) On met à jour le Glance
        self.titleLabel.setText(skiResort.name)
        self.temperatureLabel.setText(String(skiResort.temperature) + "°C ")
    }

Comment simuler une Glance : configuration d’un scheme

Afin de pouvoir simuler la Glance à l’aide du iOS Simulator, il nous faut une dernière mais importante étape : créer un scheme. Pour ce faire, sélectionnez “Edit Scheme” et dupliquez le scheme “SkiDemo Watch App”. Renommez-le « XebiaSkiDemo Glance » et choisissez “Glance” dans la section “Executable”.

watchkit

Lancez votre simulateur et votre Glance devrait apparaître !

Notifications

Les notifications WatchKit fonctionnent de façon similaire aux notifications interactives de iOS 8 et permettent de réagir avec une action à un événement provenant du téléphone. Dans la suite de cet article, vous comprendrez comment mettre en place cette dernière fonctionnalité de WatchKit.

Si vous n’avez pas changé la configuration lors de la création de votre Watch App (dans la deuxième partie du tutoriel), vous devriez déjà avoir un entry point « Notification » dans votre storyboard. Si ce n’est pas le cas, ajoutez simplement un Notification Interface Controller (de la même manière que pour Glance Interface Controller) à votre storyboard.

Les notifications dans WatchKit sont composées de deux vues, Static et Dynamic :

  1. Static est une version simplifiée (oui, encore une) de votre notification; elle peut uniquement contenir le message de l’alerte ainsi que des textes et des images statiques (configurés dans le storyboard).
  2. Dynamic est la “vraie” version de votre notification; elle peut être configurée comme n’importe quelle autre WKInterfaceController, c’est-à-dire avoir des IBOutlets et des ressources en provenance de votre extension.

Selon vos besoins, vous pouvez ou non fournir une interface Dynamic. La version Static est en revanche requise dans tous les cas.

Vous pouvez déjà tester vos notifications en créant un nouveau Scheme et en sélectionnant l’exécutable “Notification”.  Il se peut que vous obteniez un écran noir plutôt que votre interface Static. Si c’est le cas, décommentez la méthode handleActionWithIdentifier:forRemoteNotification: dans votre InterfaceController en insérant le code suivant :

override func didReceiveRemoteNotification(remoteNotification: [NSObject : AnyObject], withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
 completionHandler(.Default)
}

Vous devriez maintenant voir votre notification s’afficher avec du texte et des boutons. Ces données proviennent du fichier PushNotificationPayload.json, crée par défaut par Xcode et qui vous permet de tester vos notifications. Changez-y le nom de l’alerte et titre du bouton pour obtenir le résultat suivant :

Rajoutez-y ensuite une entrée qui contiendra les données à propos de la station :

"station": {
    "id": 2,
 "temperature_increase": 2
}

La prochaine étape consiste en l’implémentation du rendu visuel d’une notification de type Dynamic.

Ajoutez deux labels dans votre interface Dynamic, qui serviront à afficher le titre de l’alerte et le changement de température. Puis changez votre InterfaceController pour afficher et configurer l’interface Dynamic :

class NotificationController: WKUserNotificationInterfaceController {
    @IBOutlet weak var titleLabel: WKInterfaceLabel!
    @IBOutlet weak var temperaturesLabel: WKInterfaceLabel!

 override func didReceiveRemoteNotification(remoteNotification: [NSObject : AnyObject], withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)) {
        let aps = remoteNotification["aps"] as Dictionary<String, AnyObject>
        let stationInfo = remoteNotification["station"] as Dictionary<String, AnyObject>
        let temperatureIncrease = stationInfo["temperature_increase"] as Int

        self.titleLabel.setText(aps["alert"] as? String)
        self.temperaturesLabel.setText("+\(temperatureIncrease) °C")
        
        completionHandler(.Custom)
    }
}

Il nous reste maintenant à configurer le bouton afin que celui-ci nous emmène sur la station de ski lorsque l’on clique dessus. Pour cela, retournez dans le controller principal de votre application (MasterInterfaceController) et implémentez la méthode handleActionWithIdentifier:forRemoteNotification: avec le code suivant :

override func handleActionWithIdentifier(identifier: String?, forRemoteNotification remoteNotification: [NSObject : AnyObject]) {
 if identifier == "stationButtonAction" {
     let stationInfo = remoteNotification["station"] as Dictionary<String, AnyObject>
       let index = stationInfo["id"] as Int
        
  self.pushControllerWithName("DetailInterface", context: self.dataSource[index])
    }
}

Veillez à bien définir un identifiant pour votre DetailInterfaceController dans le storyboard. Ici nous avons choisi de le nommer “DetailInterface”.

Vous pouvez maintenant lancer votre application et profiter de votre notification dynamique. Bravo, votre application gère dorénavant les notifications !

iOS-Simulator-Screen-Shot-Apple-Watch-22-Jan-2015-11.45.48.png

watchkit

Conclusion

Notre petit tour de présentation sur WatchKit est à présent terminé. Nous espérons qu’il vous aura permis d’approfondir vos connaissances sur WatchKit et ses fonctionnalités. Vous devriez maintenant être capable de développer une application compagnon pour Apple Watch avant sa commercialisation. Alors à vos claviers !

Jean-Christophe Pastant
Consultant iOS, fervent défenseur du code de qualité.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *