Les extensions de partage, introduites dans iOS 8, offrent aux utilisateurs un moyen simple et pratique de partager du contenu avec d’autres entités, telles que les sites de partage social ou les services de téléchargement. Auparavant, le partage de contenu impliquait généralement de passer d’une application à une autre, par exemple, lorsque vous surfez dans Safari, si vous vouliez partager une URL, vous la copiez, basculez vers l’application que vous souhaitez enregistrer ou la partager, effectuez l’action, puis reprenez la navigation dans Safari. Avec les extensions de partage, les utilisateurs pourront désormais partager du contenu sur votre service directement depuis l’application qu’ils utilisent, qu’il s’agisse de Safari, de Photos ou d’autres applications. Cela ne se limite pas aux applications système. Toute application personnalisée qui présente une instance de la classe UIActivityViewController pourra voir votre extension de partage si vous l’avez construite pour qu’elle puisse gérer le type de fichier fourni par cette application.
Nous allons créer une extension de partage qui partage des photos sur un site de réseautage social. Pour simplifier les choses, nous utiliserons Imgur pour cela car il permet aux utilisateurs de télécharger des images de manière anonyme (sans que les images soient liées à un compte).
Comme toute autre extension, une extension de partage ne peut pas être une application autonome ; elle doit être livrée avec une application conteneur. J’ai créé un projet de démarrage qui sera notre application conteneur. Téléchargez-le pour suivre.
Fonctionnement de l’application de démonstration
L’application est une application simple appelée ImgurShare que l’utilisateur peut utiliser pour télécharger des images sur Imgur. Je vais donner les instructions pour le préparer à fonctionner sous peu, mais permettez-moi d’abord de donner un aperçu de l’application.
Sa vue racine est une vue de table qui répertorie les titres que nous donnons aux images téléchargées sur Imgur.
Pour télécharger une image, appuyez sur le bouton + dans la barre de navigation et une vue vous sera présentée qui vous permet de sélectionner une image, d’entrer un titre pour l’image et de la télécharger sur Imgur.
Après le téléchargement de l’image, lorsque vous revenez à la vue tableau, le titre de l’image téléchargée sera répertorié. Lorsque vous sélectionnez un élément dans la vue tableau, l’image téléchargée et son lien s’affichent sur Imgur. Pour rester simple, je n’ai pas inclus la fonctionnalité de modification et de suppression.
Il y a un bouton Copier l’URL dans la barre de navigation de cette vue, que vous pouvez utiliser pour copier l’URL de l’image dans le presse-papiers. Vous pouvez le tester en copiant l’URL, en ouvrant Safari et en collant le lien. Vous verrez votre image téléchargée sur Imgur.
Mise en route
Avec la vue d’ensemble de l’application, nous pouvons maintenant la configurer. Il y a quelques choses que vous devez faire pour le faire fonctionner. Tout d’abord, vous aurez besoin d’un identifiant client d’Imgur pour utiliser leur API et, deuxièmement, vous devrez configurer un groupe d’applications. Vous avez besoin d’un compte développeur pour activer les groupes d’applications. Pour qu’une extension partage des données avec son application conteneur, vous devez configurer un groupe d’applications. Cela permettra l’accès à un conteneur partagé entre l’extension et l’application conteneur.
Nous voulons que l’extension ait accès au conteneur partagé pour deux raisons: tout d’abord, tout comme l’application conteneur, chaque image téléchargée via l’extension sera enregistrée et mise à disposition pour visualisation via l’application conteneur et deuxièmement, nous utilisons une session d’arrière-plan pour le téléchargement qui nécessite que l’image soit enregistrée en premier avant le téléchargement, nous enregistrons donc une image temporaire dans le conteneur partagé qui est utilisé dans la tâche de téléchargement en arrière-plan. Nous utilisons le téléchargement en arrière-plan car les utilisateurs ont tendance à revenir à l’application hôte immédiatement après avoir terminé leur tâche dans les extensions, donc si le téléchargement est potentiellement long, nous voulons qu’il se termine même lorsque l’extension est terminée.
Pour obtenir l’id client Imgur, connectez-vous à imgur.com ou créez un compte sur imgur.com/register . Une fois connecté, cliquez sur votre nom d’utilisateur en haut à droite de l’écran et sélectionnez Paramètres.
Sélectionnez ensuite Applications dans le menu de droite.
Sélectionnez Créer le vôtre sous Applications utilisées.
Cliquez sur Enregistrer une application dans le menu de gauche et sélectionnez Enregistrer son application comme indiqué.
Sur le formulaire de demande, entrez ce que vous voulez pour le nom de la demande. Pour Type d’autorisation, sélectionnez Autorisation OAuth 2 sans URL de rappel, entrez votre adresse e-mail dans E-mail et entrez ce que vous voulez pour la description. Entrez le texte de sécurité dans la zone et soumettez le formulaire.
Après une soumission réussie, vous verrez votre identifiant client et votre secret client.
Copiez l’ID client et ouvrez UploadImageService.swift (trouvez-le dans le groupe ImgurKit) et collez-le dans l’instruction affichée.
1
|
je ne peux pas utiliser le fichier IMGURCLIENT. »
|
Pour configurer le groupe d’applications, modifiez d’abord l’identifiant du bundle de l’application. Sélectionnez ImgurShare dans le Navigateur de projet, puis sélectionnez la cible ImgurShare dans la liste cibles. Dans l’onglet Général, modifiez l’identifiant du bundle à partir de com.appcode.ImgurShare à autre chose. Vous avez besoin d’un identifiant différent car l’identifiant que vous utilisez pour votre groupe d’applications doit correspondre à l’identifiant du bundle et il doit être unique.
Ensuite, accédez à l’onglet Capacités et activez le commutateur de groupes d’applications. Ajoutez un nouveau groupe et nommez-le group.com groupImgurShare.Pour mon cas, j’ai group.com.appcoda.ImgurShare.
Création de l’extension de partage
Ouvrez AddImageViewController.fichier swift et dans la fonction shareImage (imageTitle:, imageToUpload:), modifiez l’identifiant du conteneur pour qu’il corresponde au groupe que vous avez créé.
1
|
configuration.sharedContainerIdentifier = »group.com.appcoda.ImgurShare »
|
Ouvrez ImageService.swift et faites de même pour l’instruction suivante dans la fonction tempContainerURL(image:, name:).
Faites de même pour l’instruction affichée dans la fonction getFileUrl() de la même classe.
Vous pouvez maintenant exécuter et tester l’application.
Ensuite, nous allons créer l’extension de partage. Sélectionnez le projet ImgurShare dans le Navigateur de projet, puis accédez à l’Éditeur > Ajouter une cible > iOS > Extension d’application > Extension de partage
Sur l’écran suivant, définissez le nom du produit sur ImgurUpload et laissez les champs restants définis sur leur valeur par défaut. Cliquez sur Terminer et activez le schéma ImgurUpload
Ensuite, configurez le groupe d’applications pour la cible ImgurUpload. Sélectionnez le projet ImgurShare dans le Navigateur de projets, puis sélectionnez la cible ImgurUpload. Sous l’onglet Capacités, activez le commutateur Groupes d’applications et sélectionnez le groupe que vous avez créé précédemment pour la cible ImgurShare.
Afin d’activer le partage de code entre l’extension et l’application conteneur, j’ai mis le code dans un framework. Nous devons lier cela à la cible ImgurUpload.
Avec la cible ImgurUpload sélectionnée, dans l’onglet Général, cliquez sur le bouton + sous la section Frameworks et bibliothèques liés. Sélectionnez ImgurKit.cadre dans la liste et cliquez sur Ajouter.
Avec cette configuration, regardons maintenant les fichiers générés lors de la création de l’extension. Développez le groupe ImgurUpload et vous verrez un fichier storyboard, un fichier de droits, un contrôleur de vue et un fichier plist sous le groupe Fichiers de support. Le fichier de droits dans une extension, tout comme dans l’application conteneur, est généré lorsque vous configurez des groupes d’applications. Il contient les détails de votre groupe d’applications. Tout comme dans les extensions d’action, vous pouvez utiliser un fichier JavaScript pour obtenir du contenu à partir de pages Web dans Safari. Nous n’utiliserons pas cela dans notre extension, mais pour avoir une idée de la façon d’utiliser les fichiers JavaScript pour obtenir des données de l’application hôte vers le contrôleur de vue de l’extension, vous pouvez vous référer à l’article précédent que nous avons fait sur les extensions d’action. Le processus et la mise en place sont assez similaires.
Vous pouvez utiliser le fichier storyboard pour créer une interface personnalisée (ou le faire en code), mais les extensions de partage sont livrées avec une vue de composition par défaut que nous utiliserons. Son interface est similaire à la vue de composition que vous obtenez lorsque vous partagez quelque chose sur Twitter ou Facebook.
Nous devons spécifier le type de contenu pris en charge par notre extension en définissant sa règle d’activation dans le fichier plist. Ouvrir Info.plist et développez la touche NSExtension. Développez ensuite la clé NSExtensionAttributes pour accéder à la NSExtensionActivationRule. Par défaut, il est défini sur TRUEPREDICATE, ce qui signifie que votre extension sera toujours disponible lorsque l’utilisateur souhaite partager du contenu. Vous devez modifier cela et le rendre spécifique si vous souhaitez que votre application soit approuvée par l’App Store. Changez son type en Dictionnaire et ajoutez une nouvelle paire clé-valeur. Définissez le nom de la clé sur NSExtensionActivationSupportsImageWithMaxCount, tapez sur Number et value sur 1. Cela spécifie que l’extension prend en charge le partage d’une seule image à la fois.
En regardant la classe ShareViewController, vous trouverez les talons de méthode suivants.
- isContentValid() – C’est là que l’entrée utilisateur est validée. Vous validez la saisie de texte ainsi que le contenu à partager et renvoyez true si la validation est réussie. Le bouton de publication de la vue de composition restera désactivé jusqu’à ce que true soit renvoyé.
- didSelectPost() – Ceci est appelé après que l’utilisateur a appuyé sur le bouton de publication et c’est ici que vous téléchargez le contenu partagé. Une fois le téléchargement planifié, vous devez appeler completeRequestReturningItems(, completionHandler:) afin que l’application hôte puisse débloquer son interface utilisateur. Lorsque la demande de téléchargement est terminée, elle appelle le gestionnaire de complétion qui a été passé dans l’appel de fonction mentionné précédemment.
- configurationItems–) – La vue de composition par défaut de l’extension de partage vous permet de définir ce qui apparaît au bas de la vue à l’aide de cellules de vue de tableau. Pour ce faire, vous devez renvoyer un tableau d’objets SLComposeSheetConfigurationItem si vous avez des configurations à définir pour l’utilisateur. Sinon, retournez un tableau vide.
Ajoutez les importations suivantes à la classe ShareViewController.
1
2
|
importer ImgurKit
importer des services mobiles
|
Ajoutez la variable suivante à la classe. Cela contiendra l’image sélectionnée par l’utilisateur.
1
|
var selectedImage: UIImage ?
|
Ensuite, nous remplacerons viewDidLoad() pour extraire l’image des éléments de pièce jointe dans extensionContext. Lorsque l’utilisateur publie une image, elle est regroupée avec d’autres métadonnées et transmise à l’extension via l’objet extensionContext. Ajoutez ce qui suit à la classe.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
remplacer func viewDidLoad() {
super.viewDidLoad()
let content = extensionContext!.inputItems as NSExtensionItem
let contentType = kUTTypeImage as String
for attachment in content.attachments as {
if attachment.hasItemConformingToTypeIdentifier(contentType) {
attachment.loadItemForTypeIdentifier(contentType, options: nil) { data, error in
if error == nil {
let url = data as NSURL
if let imageData = NSData(contentsOfURL: url) {
self.selectedImage = UIImage(données: ImageData)
}
} autre {
let alert = UIAlertController(titre: « Erreur », message: « Erreur de chargement de l’image », preferredStyle:.Alerte)
let action = UIAlertAction(titre: « Erreur », style:.Annuler) {_ dans
soi.dismissViewControllerAnimated (true, complétion: nil)
}
alerte.addAction (action)
auto.presentViewController (alerte, animé: vrai, achèvement: néant)
}
}
}
}
}
|
Ici, nous extrayons l’élément de pièce jointe dans l’objet NSItemProvider, puis vérifions si la pièce jointe est conforme au type kUTTypeImage. kUTTypeImage est une constante de chaîne définie par le système pour les identificateurs de type uniforme de base définis dans le framework MobileCoreServices. Nous l’utilisons pour identifier les types de pièces jointes.
L’image est encapsulée dans la classe NSItemProvider, nous devons donc d’abord la charger à l’aide de loadItemForTypeIdentifier(). Si cela réussit, nous chargeons l’image à partir de l’URL où elle est stockée (lorsqu’elle est extraite de NSItemProvider, les images sont enregistrées sur le disque). Nous définissons ensuite la variable selectedImage avec l’image. En cas d’erreur, l’utilisateur recevra une alerte.
Ensuite, modifiez la fonction isContentValid() comme indiqué.
1
2
3
4
5
6
7
8
9
|
si vous avez un problème, vous pouvez le faire en utilisant la méthode suivante : > Bool {
if let img= selectedImage {
if!contentText.isEmpty {
retourne vrai
}
}
retourner false
}
|
Cette vérification permet de s’assurer qu’une image est sélectionnée et que l’utilisateur saisit une entrée avant de pouvoir la publier.
Modifiez didSelectPost() comme suit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
remplacez func didSelectPost() {
laissez defaultSession=UploadImageService.sharedService.session
let defaultSessionConfig =defaultSession.configuration
let defaultHeaders=defaultSessionConfig.HTTPAdditionalHeaders
let config=NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier (« com.appcode.Je partage.bkgrdsession »)
config.sharedContainerIdentifier = « group.com.appcoda.ImgurShare »
config.HTTPAdditionalHeaders = defaultHeaders
let session = NSURLSession(configuration: config, delegate: UploadImageService.sharedService, delegateQueue: NSOperationQueue.mainQueue())
let completion: (TempImage?, NSError?, NSURL?) -> () = { image, error, tempURL in
if error == nil {
if let imageURL = image?.link {
let image = Image(imgTitle: self.contentText, imgImage: self.Sélectionnéimage!)
image.url=imageURL
laissez imageService =ImageService.sharedService
imageService.addImage (image)
imageService.Enregistrer des images()
}
si let container = tempURL {
var delError: NSError ?
si NSFileManager.defaultManager().isDeletableFileAtPath (conteneur.chemin!) {
let success=NSFileManager.defaultManager().removeItemAtPath (conteneur.chemin!, erreur: & delError)
if(!succès) {
println(« Erreur de suppression du fichier au chemin: \(erreur?.description) »)
}
}
}
} else {
println(« Error uploading image: \(error!) »)
if let container = tempURL {
var delError: NSError?
if NSFileManager.defaultManager().isDeletableFileAtPath(container.path!) {
let success = NSFileManager.defaultManager().removeItemAtPath(container.path!, error: &delError)
if(!success) {
println(« Error removing file at path: \(error?.description) »)
}
}
}
}
}
let title=contentText
UploadImageService.sharedService.uploadImage (selectedImage!, titre: titre, session: session, achèvement: achèvement)
moi-même.extensionContext ?.completeRequestReturningItems (, nil)
}
|
Remplacez l’identifiant de groupe d’applications dans la déclaration ci-dessous par le vôtre.
1
|
configuration.sharedContainerIdentifier = »group.com.appcoda.ImgurShare »
|
Ici, nous définissons la session d’arrière-plan que nous utiliserons pour le téléchargement. Nous définissons ensuite le bloc de complétion qui sera appelé lorsque la requête sera terminée. Dans le bloc d’achèvement, nous vérifions si le téléchargement a réussi et si oui, enregistrez l’image (les images enregistrées ici seront chargées dans la vue de table de l’application conteneur). Nous supprimons ensuite l’image temporaire qui avait été enregistrée sur le disque lors de la demande d’arrière-plan. Si le téléchargement a échoué, nous supprimons également l’image temporaire et ne l’enregistrons pas pour une visualisation ultérieure sur l’application conteneur. Nous voulons uniquement que l’application conteneur affiche les images qui ont été téléchargées avec succès sur Imgur.
Notez l’utilisation de contentText. Cette propriété contient le texte saisi par l’utilisateur.
Nous appelons ensuite la fonction uploadImage() dans le framework ImgurKit pour effectuer le téléchargement. Cette méthode est asynchrone et reviendra immédiatement. Lorsque le téléchargement est terminé ou échoue, le bloc d’achèvement est appelé.
Ensuite, modifiez configurationItems() comme indiqué. Nous renvoyons un tableau vide car nous n’ajouterons rien à la vue de composition de l’extension.
1
2
3
|
remplacez les éléments de configuration func() – >! {
retour
}
|
Test de l’extension de partage
Vous pouvez maintenant exécuter l’application. Assurez-vous que le schéma ImgurUpload est sélectionné. Lorsque vous êtes invité à choisir une application à exécuter, choisissez Photos. Une fois en cours d’exécution, sélectionnez une photo et appuyez sur le bouton Partager. Lors de la première exécution, vous devrez ajouter votre extension à la feuille de partage. Sélectionnez le bouton Plus à droite des autres icônes de partage et activez le commutateur de votre extension, puis sélectionnez Terminé.
De retour sur la feuille de partage, vous pourrez voir l’icône de votre extension à côté des autres icônes de partage. Sélectionnez votre extension, entrez du texte et appuyez sur Publier.
L’image sera téléchargée sur Imgur et enregistrée dans l’application conteneur. Pour le confirmer, accédez à l’écran d’accueil et ouvrez ImgurShare. Vous verrez le titre que vous avez entré pour l’image et l’image elle-même dans la vue de détail.
Si vous quittez l’application conteneur et revenez à l’application Photos pour partager une autre image, puis revenez à l’application conteneur, vous remarquerez que le tableau ne se met pas automatiquement à jour avec l’élément ajouté. Si vous sélectionnez une ligne de tableau, puis revenez à la vue table, la table sera mise à jour. Nous devons recharger les données de la table lorsque l’application revient au premier plan. Pour ce faire, ajoutez d’abord la fonction suivante à la classe ImagesTableViewController.
1
2
3
|
func refreshTable() {
tableView.Données de rechargement()
}
|
Puis dans AppDelegate.swift, ajoutez ce qui suit à la fonction applicationWillEnterForeground().
1
2
|
soit vc = ImagesTableViewController()
vc.actualiSable()
|
Maintenant, chaque fois que vous téléchargez une image via l’extension et ramenez l’application conteneur au premier plan, le tableau sera mis à jour.
Résumé
Qui conclut ce tutoriel d’extension de partage. J’espère que le guide sera utile à tous ceux qui souhaitent créer une extension de partage. Vous pouvez télécharger les fichiers du projet ici.
Remarque: Lors du partage d’un fichier via l’extension, vous remarquerez un message d’erreur dans le débogueur « Impossible d’hériter des autorisations CoreMedia de xxxx ». Cela semble être une erreur courante, et je l’ai rencontrée en travaillant avec des extensions Today, Share et action. L’extension fonctionne toujours bien malgré l’erreur. En cherchant, cela semble être courant et dans ce post Stackoverflow, quelqu’un dit que leur extension fonctionne bien et a été approuvée par Apple malgré l’erreur. Donc, il pourrait s’agir d’un bug Xcode. Je ne suis pas sûr. Vous pouvez laisser vos pensées dans le commentaire.