Creazione di un’estensione di condivisione semplice nell’app iOS 8

Le estensioni di condivisione, introdotte in iOS 8, offrono agli utenti un modo semplice e conveniente per condividere contenuti con altre entità, come siti Web di condivisione sociale o servizi di upload. In precedenza, la condivisione di contenuti di solito comportava il passaggio da un’app all’altra, ad esempio, durante la navigazione in Safari, se si desidera condividere un URL, è necessario copiarlo, passare all’app che si desidera salvare o condividerlo, eseguire l’azione e quindi riprendere la navigazione in Safari. Con le estensioni di condivisione, gli utenti saranno ora in grado di condividere contenuti sul tuo servizio direttamente dall’app che stanno utilizzando, che si tratti di Safari, Foto o altre app. Questo non è limitato alle applicazioni di sistema. Qualsiasi applicazione personalizzata che presenta un’istanza della classe UIActivityViewController sarà in grado di vedere l’estensione di condivisione se è stata creata l’estensione in modo che possa gestire il tipo di file fornito da tale applicazione.

Stiamo per costruire un’estensione di condivisione che condivide le foto su un sito di social networking. Per semplificare le cose useremo Imgur per questo in quanto consente agli utenti di caricare le immagini in modo anonimo (senza che le immagini siano collegate a un account).

Proprio come qualsiasi altra estensione, un’estensione di condivisione non può essere un’app stand alone; deve essere fornita in bundle con un’app contenitore. Ho creato un progetto iniziale che sarà la nostra app contenitore. Scaricalo per seguire.

Come funziona l’app Demo

L’app è una semplice applicazione chiamata ImgurShare che l’utente può utilizzare per caricare immagini su Imgur. Darò le istruzioni per prepararlo per l’esecuzione a breve, ma prima permettetemi di dare una panoramica dell’app.

La sua vista principale è una vista tabella che elenca i titoli che diamo alle immagini caricate su Imgur.

Per caricare un’immagine, toccare il pulsante + nella barra di navigazione e vi verrà presentato con una vista che consente di selezionare un’immagine, inserire un titolo per l’immagine e caricare su Imgur.

Dopo aver caricato l’immagine, quando si torna alla vista tabella, verrà elencato il titolo dell’immagine caricata. Quando selezioni un elemento nella vista tabella, ti verrà mostrata l’immagine caricata e il suo link su Imgur. Per semplificare, non ho incluso la funzionalità di modifica ed eliminazione.

C’è un pulsante Copia URL sulla barra di navigazione di questa vista, che è possibile utilizzare per copiare l’URL dell’immagine negli appunti. Puoi testarlo copiando l’URL, aprendo Safari e incollando nel link. Vedrai la tua immagine caricata su Imgur.

Guida introduttiva

Con la panoramica app fuori strada, ora possiamo configurarlo. Ci sono un paio di cose che devi fare per farlo funzionare. In primo luogo, è necessario un ID client da Imgur per utilizzare la loro API e in secondo luogo, è necessario impostare un gruppo di app. È necessario un account sviluppatore per abilitare i gruppi di app. Affinché un’estensione possa condividere i dati con l’app contenitore, è necessario configurare un gruppo di app. Ciò consentirà l’accesso a un contenitore condiviso tra l’estensione e l’app contenitore.

Vogliamo che l’estensione abbia accesso al contenitore condiviso per due motivi: in primo luogo, proprio come l’app contenitore, ogni immagine caricata tramite l’estensione verrà salvata e resa disponibile per la visualizzazione tramite l’app contenitore e in secondo luogo, utilizziamo una sessione in background per il caricamento che richiede che l’immagine venga salvata prima del caricamento, quindi salviamo un’immagine temporanea nel contenitore condiviso che viene utilizzata nell’attività di caricamento in background. Usiamo il caricamento in background perché gli utenti tendono a tornare all’app host immediatamente dopo aver terminato il loro compito nelle estensioni, quindi se il caricamento è potenzialmente lungo, vogliamo che venga eseguito fino al completamento anche quando l’estensione viene terminata.

Per ottenere l’ID client Imgur, accedere a imgur.com o registrare un account su imgur.com/register. Una volta effettuato l’accesso, fare clic sul nome utente in alto a destra dello schermo e selezionare Impostazioni.

Quindi selezionare Applicazioni dal menu a destra.

Selezionare crea il tuo sotto Applicazioni utilizzate.

Fare clic su Registra un’applicazione dal menu a sinistra e selezionare Registra la loro applicazione come mostrato.

Nel modulo di domanda, immettere ciò che si desidera per il nome dell’applicazione. Per il tipo di autorizzazione, selezionare OAuth 2 autorizzazione senza un URL di callback, inserire il proprio indirizzo e-mail in e-mail e inserire quello che vuoi per la descrizione. Inserisci il testo di sicurezza nella casella e invia il modulo.

Dopo una presentazione riuscita, ti verrà mostrato il tuo ID cliente e il segreto del cliente.

Copiare l’ID client e aprire UploadImageService.swift (trovalo nel gruppo ImgurKit) e incollalo nell’istruzione mostrata.

1
privato lasciate imgurClientId = “IMGUR_CLIENT_ID”

Per configurare l’App di Gruppo, prima di cambiare l’app Bundle Identifier. Selezionare ImgurShare nel Navigatore progetto, quindi selezionare la destinazione ImgurShare dall’elenco destinazioni. Nella scheda Generale, modificare l’identificatore del bundle da com.appcoda.ImgurShare a qualcos’altro. Hai bisogno di un identificatore diverso perché l’identificatore che usi per il tuo gruppo di app deve corrispondere all’identificatore del bundle e deve essere univoco.

Quindi vai alla scheda Funzionalità e attiva l’interruttore Gruppi di app. Aggiungi un nuovo gruppo e chiamalo group. com Im ImgurShare. Per il mio caso, ho group. com. appcoda. ImgurShare.

Creazione dell’estensione di condivisione

Aprire AddImageViewController.file swift e nella funzione shareImage (imageTitle:, imageToUpload:), modificare l’identificatore del contenitore in modo che corrisponda al gruppo creato.

1
config.sharedContainerIdentifier = “group. com. appcoda. ImgurShare”

Apri ImageService.swift e fai lo stesso per la seguente istruzione nella funzione tempContainerURL(image:, name:).

Fai lo stesso per l’istruzione mostrata nella funzione getFileUrl() nella stessa classe.

È ora possibile eseguire e testare l’applicazione.

Successivamente creeremo l’estensione di condivisione. Seleziona il progetto ImgurShare in Project Navigator e poi vai su Editor > Aggiungi target > iOS > Estensione applicazione > Condividi estensione

Nella schermata successiva impostare il nome del prodotto su ImgurUpload e lasciare i campi rimanenti impostati sul valore predefinito. Fare clic su Fine e attivare lo schema ImgurUpload

Quindi, configurare il gruppo di app per la destinazione ImgurUpload. Selezionare il progetto ImgurShare in Project Navigator e quindi selezionare la destinazione ImgurUpload. Nella scheda Funzionalità, attiva l’opzione Gruppi di app e seleziona il gruppo creato in precedenza per la destinazione ImgurShare.

Per abilitare la condivisione del codice tra l’estensione e l’app contenitore, ho inserito il codice in un framework. Dobbiamo collegarlo al target ImgurUpload.

Con la destinazione ImgurUpload selezionata, nella scheda Generale, fare clic sul pulsante + nella sezione Framework e librerie collegati. Seleziona ImgurKit.quadro dalla lista e fare clic su Aggiungi.

Con questo set up, diamo ora un’occhiata ai file generati quando abbiamo creato l’estensione. Espandi il gruppo ImgurUpload e vedrai un file storyboard, un file entitlements, un controller di visualizzazione e un file plist nel gruppo File di supporto. Il file dei diritti in un’estensione, proprio come nell’app contenitore, viene generato quando si configurano i gruppi di app. Contiene i dettagli del tuo gruppo di app. Proprio come nelle estensioni di azione, è possibile utilizzare un file JavaScript per ottenere contenuti da pagine Web in Safari. Non useremo questo nella nostra estensione, ma per un’idea su come utilizzare i file JavaScript per ottenere i dati dall’app host al controller di visualizzazione dell’estensione, puoi fare riferimento al precedente articolo che abbiamo fatto sulle estensioni di azione. Il processo e la configurazione sono abbastanza simili.

Puoi usare il file storyboard per creare un’interfaccia personalizzata (o farlo in codice), ma le estensioni di condivisione sono dotate di una vista di composizione predefinita che useremo. La sua interfaccia è simile alla vista di composizione che si ottiene quando si condivide qualcosa su Twitter o Facebook.

Dobbiamo specificare il tipo di contenuto che la nostra estensione supporta impostando la sua regola di attivazione nel file plist. Apri Informazioni.plist ed espandere la chiave NSExtension. Quindi espandere la chiave NSExtensionAttributes per accedere a NSExtensionActivationRule. Per impostazione predefinita, questo è impostato su TRUEPREDICATE, il che significa che l’estensione verrà sempre resa disponibile quando l’utente desidera condividere contenuti. Devi cambiarlo e renderlo specifico se vuoi che la tua app sia approvata dall’App Store. Cambia il suo tipo in Dizionario e aggiungi una nuova coppia chiave-valore. Impostare il nome della chiave su NSExtensionActivationSupportsImageWithMaxCount, digitare su Number e value su 1. Specifica che l’estensione supporta la condivisione di una singola immagine alla volta.

Guardando la classe ShareViewController, troverai i seguenti stub di metodo.

  • isontentvalid() – Questo è dove l’input dell’utente viene convalidato. Convalidare l’input di testo e il contenuto da condividere e restituire true se la convalida passa. Il pulsante Post nella vista componi rimarrà disabilitato fino a quando non verrà restituito true.
  • didSelectPost() – Questo viene chiamato dopo che l’utente tocca il pulsante Post ed è qui che si carica il contenuto condiviso. Una volta pianificato il caricamento, è necessario chiamare completeRequestReturningItems(, completionHandler:) in modo che l’app host possa annullare il blocco dell’interfaccia utente. Al termine della richiesta di caricamento, chiama il gestore di completamento che è stato passato alla precedente chiamata di funzione menzionata.
  • configurationItems() – La vista di composizione predefinita dell’estensione share consente di impostare ciò che appare nella parte inferiore della vista utilizzando le celle della vista tabella. Per fare ciò, è necessario restituire un array di oggetti SLComposeSheetConfigurationItem se si dispone di configurazioni da impostare per l’utente. In caso contrario, restituire un array vuoto.

Aggiungere le seguenti importazioni alla classe ShareViewController.

1
2

importazione ImgurKit
importa MobileCoreServices

Aggiungere la seguente variabile di classe. Questo manterrà l’immagine selezionata dall’utente.

1
var selectedImage: UIImage?

Successivamente sovrascriveremo viewDidLoad () per estrarre l’immagine dagli elementi allegati in extensionContext. Quando l’utente pubblica un’immagine, viene fornita in bundle con altri metadati e passata all’estensione tramite l’oggetto extensionContext. Aggiungere quanto segue alla 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

ignorare 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 (dati: imageData)
}
} altro {
let alert = UIAlertController(titolo: “Errore”, messaggio: “Errore nel caricamento dell’immagine”, preferredStyle:.Allarme)
let action = UIAlertAction(titolo: “Errore”, stile: .Annulla) {_in
se stesso.dismissViewControllerAnimated(true, completion: nil)
}
allarme.addAction (azione)
se stesso.presentViewController(avviso, animato: vero, completamento: nil)
}
}
}
}
}

Qui si estrae l’elemento di allegato nel NSItemProvider oggetto, quindi controllare per vedere se l’allegato è conforme al tipo kUTTypeImage. kUTTypeImage è una costante stringa definita dal sistema per gli identificatori di tipo uniforme di base definiti nel framework MobileCoreServices. Lo usiamo per identificare i tipi di allegati.

L’immagine è racchiusa nella classe NSItemProvider quindi dobbiamo prima caricarla usando loadItemForTypeIdentifier (). Se questo ha successo, carichiamo l’immagine dall’URL di dove è memorizzata (quando estratta da NSItemProvider, le immagini vengono salvate sul disco). Quindi impostiamo la variabile selectedImage con l’immagine. In caso di errore, all’utente verrà mostrato un avviso.

Successivamente modificare la funzione isontentvalid() come mostrato.

1
2
3
4
5
6
7
8
9

ignorare func isContentValid() -> Bool {
se lasciate img = selectedImage{
se !contentText.isEmpty {
return true
}
}
return false
}

Questo controllo per assicurarsi che l’immagine è selezionata e i tipi di utente in input prima di poter postare.

Modificare didSelectPost () come segue.

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

ignorare func didSelectPost() {
lasciare defaultSession = UploadImageService.sharedService.session
lascia defaultSessionConfig = defaultSession.configuration
let defaultHeaders = defaultSessionConfig.HTTPAdditionalHeaders
let config = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier (“com.appcoda.ImgurShare.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.Immagine selezionata!)
immagine.url = imageURL
lascia imageService = ImageService.sharedService
imageService.addImage (image)
imageService.Salva IMMAGINI()
}
se let container = tempURL {
var delError: NSError?
se NSFileManager.defaultManager ().isDeletableFileAtPath (contenitore.percorso!) {
let success = NSFileManager.defaultManager ().removeItemAtPath (contenitore.percorso!, errore: &delError)
if(!successo) {
println (“Errore nel rimuovere il file nel percorso: \(errore?.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?.descrizione)”)
}
}
}
}
}
lasciate title = contentText
UploadImageService.sharedService.uploadImage (selectedImage!, title: title, session: session, completion: completion)
auto.extensionContext?.completeRequestReturningItems (, zero)
}

Sostituisci l’identificatore del gruppo di app nell’istruzione seguente con il tuo.

1
config.sharedContainerIdentifier = “group. com. appcoda. ImgurShare”

Qui definiamo la sessione in background che useremo per il caricamento. Definiamo quindi il blocco di completamento che verrà chiamato al completamento della richiesta. Nel blocco di completamento, controlliamo se il caricamento ha avuto successo e, in tal caso, salviamo l’immagine (le immagini salvate qui verranno caricate nella vista tabella dell’app contenitore). Abbiamo quindi eliminare l’immagine temporanea che era stata salvata su disco durante la richiesta di sfondo. Se il caricamento non è riuscito, eliminiamo anche l’immagine temporanea e non la salviamo per la visualizzazione successiva sull’app contenitore. Vogliamo solo che l’app contenitore visualizzi le immagini caricate correttamente su Imgur.

Si noti l’uso di contentText. Questa proprietà contiene l’input di testo dall’utente.

Chiamiamo quindi la funzione uploadImage () nel framework ImgurKit per eseguire il caricamento. Questo metodo è asincrono e tornerà immediatamente. Quando il caricamento viene completato o non riesce, verrà chiamato il blocco di completamento.

Avanti modificare configurationItems () come mostrato. Restituiamo un array vuoto poiché non aggiungeremo nulla alla vista di composizione dell’estensione.

1
2
3

ignorare func configurationItems() -> ! {
ritorno
}

Testare l’estensione Share

È ora possibile eseguire l’applicazione. Assicurarsi che lo schema ImgurUpload sia selezionato. Quando viene richiesto di scegliere un’app da eseguire, scegliere Foto. Una volta in esecuzione, selezionare una foto e toccare il pulsante Condividi. Alla prima esecuzione, è necessario aggiungere l’estensione al foglio di condivisione. Seleziona il pulsante Altro a destra delle altre icone di condivisione e attiva l’interruttore per l’estensione, quindi seleziona Fatto.

Torna sul foglio di condivisione, si sarà in grado di vedere l’icona dell’estensione accanto alle altre icone di condivisione. Seleziona la tua estensione, inserisci del testo e tocca Pubblica.

L’immagine verrà caricata su Imgur e salvata nell’app contenitore. Per confermare questo, passare alla schermata iniziale e aprire ImgurShare. Vedrai il titolo che hai inserito per l’immagine e l’immagine stessa nella vista dettagli.

Se lasci l’app contenitore e torni all’app Foto per condividere un’altra immagine e torni all’app contenitore, noterai che la tabella non si aggiorna automaticamente con l’elemento aggiunto. Se si seleziona una riga della tabella e si torna alla vista tabella, la tabella verrà aggiornata. Dobbiamo ricaricare i dati della tabella quando l’app torna in primo piano. Per fare questo prima aggiungere la seguente funzione alla classe ImagesTableViewController.

1
2
3

func refreshTable() {
tableView.Ricarica DATI()
}

Quindi in AppDelegate.swift, aggiungere quanto segue alla funzione applicationWillEnterForeground ().

1
2

lasciate che vc = ImagesTableViewController()
vc.refreshTable()

Ora ogni volta che carichi un’immagine tramite l’estensione e riporti l’app contenitore in primo piano, la tabella verrà aggiornata.

Sommario

Che conclude questo tutorial Estensione di condivisione. Spero che la guida sia utile a chiunque voglia creare un’estensione di condivisione. È possibile scaricare i file di progetto qui.

Nota: Quando si condivide un file tramite l’estensione, si noterà un messaggio di errore nel debugger “Impossibile ereditare le autorizzazioni CoreMedia da xxxx”. Questo sembra essere un errore comune e l’ho riscontrato quando si lavora con le estensioni Today, Share e action. L’estensione funziona ancora bene nonostante l’errore. Cercando in giro, sembra essere comune e in questo post di Stackoverflow, qualcuno dice che la loro estensione funziona bene ed è stata approvata da Apple nonostante abbia ricevuto l’errore. Quindi, potrebbe essere un bug Xcode. Non ne sono sicuro. Puoi lasciare i tuoi pensieri nel commento.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.