Les Message Extensions, nouveauté iOS10, quelle valeur ajoutée ? Comment ça marche ? Cette présentation répond à vos questions et vous guide sur la manière de créer / architecturer votre extension en swift.
2. 2
Introduction
Les applis/extensions iMessage sont une nouveauté iOS10
Elles viennent s’ajouter directement dans l’application message du iDevice et
permettent tout un tas de choses. Sky is the limit !
Chose nouvelle de la part d’apple, elles peuvent être indépendantes ! Elles
peuvent donc être utilisées comme les today extensions ou être des
applications entières à elles seules.
Parmis ces extensions il y a un type particulier nommé : « sticker pack
application ». Nous ne les verrons que très succinctement puisqu’un enfant de 4
ans pourrait un faire une en 3min montre en main.
3. QUELQUES EXEMPLES :
3
Game pigeon (oui ça s’appelle vraiment comme ça)
Un set de jeux iMessage qui
rappelle un peu l’époque de MSN
Messenger avec ses jeux intégrés.
4. QUELQUES EXEMPLES :
4
Do with me : la todolist collaborative
On prend les mêmes et on
recommence, voici une Nème
application « todolist » mais cette
fois-ci entièrement intégrée à
iMessage et donc collaborative !
5. 5
SUPER MARIO RUN Stickers : Une pub idéale
Simplissime à produire, facile à
« vendre », les stickers app sont
une véritable mine d’or.
La plupart se vendent à 0,99€.
Les autres, gratuites, servent de
publicité à une autre application
(possiblement payante) comme
Mario Run ici.
QUELQUES EXEMPLES :
7. 7
Créer une sticker pack application
Nouveau projet -> Stickers pack application
Après c’est UNIQUEMENT du drag&drop
8. 8
Créer son application Message
Pour ajouter une extension Message à une application, il faut simplement le
faire depuis l’écran d’ajout d’une target. L’une des options disponible sera
« Message Extension ».
Cela créé tous les fichiers nécessaires à l’initialisation de votre extension :
• Un storyboard
• Un images.assets
• Un info.plist
• Un viewController héritant de : MSMessagesAppViewController
• Ce view controller DOIT rester le point d’entrée de votre storyboard
10. 10
Architecturer son extension Message
Le MSMessagesAppViewController sera la clé de voute de l’application.
Pour une application de cette taille, on pourra se permettre de lui confier le
gros du boulot. Cependant il est sûrement possible de factoriser, ou utiliser des
delegate pour ne pas l’encombrer.
Pourquoi est-il important :
• Il est le seul à avoir accès à l’objet : activeConversation
• Il possède des méthodes lifecycle/delegate essentielles
• Il peut demander l’affichage au format compact ou étendu
12. 12
override func willTransition(to presentationStyle: MSMessagesAppPresentationStyle)
override func willBecomeActive(with conversation: MSConversation)
Une gestion du lifeCycle inhabituelle
Deux style de présentation :
requestPresentationStyle(MSMessagesAppPresentationStyle.compact)
requestPresentationStyle(MSMessagesAppPresentationStyle.expanded)
Architecturer son extension Message
13. 13
Passer des données dans un message
Model de
données
• var1
• var2
• var3
?var1=xxx&var2=xxx&var3=xxx
toUrl()
URL (NSURL en obj-c)
Architecturer son extension Message
15. 15
Créer un message, faire passer des données et gérer son aspect
let newMessage:MSMessage = MSMessage(session : MSSession())
let newMessageLayout:MSMessageTemplateLayout = MSMessageTemplateLayout.init()
newMessageLayout.caption = "Depuis compte : (transactionOutAccount)"
newMessage.url = URL.init(string: transactionToSend.toUrl())
newMessageLayout.image = createImageForTransaction(message: "Proposition de
virement",amount: transactionToSend.amount)
newMessage.layout = newMessageLayout
16. 16
Générer une image dynamiquement pour remplir son message
UIGraphicsBeginImageContextWithOptions(toImageView.frame.size, false, UIScreen.main.scale)
toImageView.drawHierarchy(in: toImageView.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Une solution simple est de créer un contenu complet avec des views avant
d’utiliser le code suivant :
17. 17
Envoyer un message
activeConversation.insert(currentMessage, completionHandler: nil)
override func didStartSending(_ message: MSMessage, conversation: MSConversation) {
// Quand l’utilisateur appuie sur le bouton d’envoi
}
override func didCancelSending(_ message: MSMessage, conversation: MSConversation)
{
// Quand l’utilisateur supprime un message créé précédemment sans l’envoyer
}
Mais cela ne nous permet pas d’envoyer directement le message, l’utilisateur doit
compléter (s’il le veut) et envoyer par la suite.
Heureusement, nous avons de jolis méthodes delegate !
18. 18
Récupérer un(e) message/session
Pour que l’échange soit user-friendly, nous allons devoir réutiliser la même session
pour que l’utilisateur ai l’impression de faire passer un même message.
guard let activeConversation = activeConversation,
let selectedMessage = activeConversation.selectedMessage,
let session = selectedMessage.session else {
return
}
Là, je me suis assuré de la présence d’une conversation, d’un message sélectionné et de
la session à laquelle il appartient. Je vais pouvoir m’en servir pour :
let replyMessage = MSMessage(session: session)
let currentTransaction = TransactionModel.init(argumentUrl: selectedMessage.url)
• Utiliser le contenu du message sélectionné :
• Créer une réponse :
19. 19
Identifier un message
Les messages sont « signés » à l’aide d’un UDID propre à un utilisateur dans la
conversation en cours.
let senderId = selectedMessage.senderParticipantIdentifier.uuidString
let myId = conversation.localParticipantIdentifier.uuidString
if (senderId == myId){
controller = instanciateMessageViewController(withMessage: "C'est pas ton tour Jean Michel !")
}
open var remoteParticipantIdentifiers: [UUID] { get }
Pour connaître tous les participants à la conversation, MSConversation contient :
20. 20
Pour aller plus loin avec le MSMessagesAppViewController
Life cycle :
open func willBecomeActive(with conversation: MSConversation)
open func didBecomeActive(with conversation: MSConversation)
open func willResignActive(with conversation: MSConversation)
open func didResignActive(with conversation: MSConversation)
open func willSelect(_ message: MSMessage, conversation: MSConversation)
open func didSelect(_ message: MSMessage, conversation: MSConversation)
open func didReceive(_ message: MSMessage, conversation: MSConversation)
open func didStartSending(_ message: MSMessage, conversation: MSConversation)
open func didCancelSending(_ message: MSMessage, conversation: MSConversation)
open func willTransition(to presentationStyle: MSMessagesAppPresentationStyle)
open func didTransition(to presentationStyle: MSMessagesAppPresentationStyle)
Autres :
open func requestPresentationStyle(_ presentationStyle: MSMessagesAppPresentationStyle)
open func dismiss()
21. 21
Pour aller plus loin avec les MSMessage
// Si ce booléen est vrai, le message s’effacera peu après la lecture de l’interlocuteur
open var shouldExpire: Bool
// Celui qu’on ne remplis jamais alors que ça ferrait de nous des gens sympa
open var accessibilityLabel: String?
// Un récapitulatif du contenu du message pour ce qui ne le voient pas tel quel (ex : vielle version d’iOS)
open var summaryText: String?
// Si le message n’a pas été envoyé, la raison de trouve ici
open var error: Error?
22. 22
Aller plus loin avec MSConversation
func didChooseRIBSend() {
let urlpath = Bundle.main.path(forResource: "sample", ofType: "pdf")
let url:URL = URL(fileURLWithPath: urlpath!)
activeConversation?.insertAttachment(url, withAlternateFilename: "RIB de Jean-Michel POC",
completionHandler: nil)
activeConversation?.insertText("Voici mon RIB", completionHandler: nil)
}
23. 4 - DÉMO / PRÉSENTATION DU CODE
SupaBank et son extension Message pour générer un virement
entre deux de ses clients
24. MERCI POUR VOTRE ATTENTION !
AVEZ-VOUS DES QUESTIONS ?
Contact : fontaine.nicolas34@gmail.com