het bouwen van een eenvoudige Share Extension in iOS 8 App

Share extensions, geà ntroduceerd in iOS 8, geven gebruikers een gemakkelijke en handige manier om content te delen met andere entiteiten, zoals social sharing websites of upload diensten. Eerder, het delen van inhoud meestal gepaard met het overschakelen van de ene app naar de andere, bijvoorbeeld, tijdens het surfen in Safari, als je wilde een URL te delen, je zou het kopiëren, overschakelen naar de app die u wilde opslaan of delen in, het uitvoeren van de actie en vervolgens hervatten surfen in Safari. Met share extensies, gebruikers zullen nu in staat zijn om content te delen met uw dienst rechtstreeks vanuit de app die ze gebruiken, of het nu Safari, Foto ‘ s of andere apps. Dit is niet beperkt tot systeemtoepassingen. Elke aangepaste toepassing die een exemplaar van de UIActivityViewController klasse presenteert zal in staat zijn om uw Delen extensie te zien als u uw extensie gebouwd, zodat het bestandstype dat door die toepassing kan omgaan.

we gaan een share-extensie bouwen die foto ‘ s deelt met een sociale netwerksite. Om het eenvoudig te maken gebruiken we Imgur voor dit omdat het gebruikers in staat stelt om beelden anoniem te uploaden (zonder dat de beelden worden gekoppeld aan een account).

net als elke andere extensie, een aandeel extensie kan niet een stand-alone app; het moet komen gebundeld met een container app. Ik heb een starter project gemaakt dat onze container app zal zijn. Download het om mee te volgen.

hoe de Demo App werkt

de app is een eenvoudige applicatie genaamd ImgurShare die de gebruiker kan gebruiken om afbeeldingen te uploaden naar Imgur. Ik zal de instructies van het krijgen van het klaar om te draaien binnenkort te geven, maar laat me eerst een overzicht van de app geven.

de rootweergave is een tabelweergave die de titels weergeeft die we geven aan de afbeeldingen die naar Imgur zijn geüpload.

om een afbeelding te uploaden, tikt u op de knop + in de navigatiebalk en u krijgt een weergave te zien waarmee u een afbeelding kunt selecteren, een titel voor de afbeelding kunt invoeren en uploaden naar Imgur.

na het uploaden van de afbeelding, wanneer u terug gaat naar de tabelweergave, wordt de titel van de geüploade afbeelding weergegeven. Wanneer u een item in de tabelweergave selecteert, wordt u de geüploade afbeelding en de link op Imgur getoond. Om het eenvoudig te houden, heb ik geen bewerken en verwijderen functionaliteit.

er is een knop URL kopiëren op de navigatiebalk van deze weergave, die u kunt gebruiken om de URL van de afbeelding naar het klembord te kopiëren. U kunt het testen door het kopiëren van de URL, het openen van Safari en plakken in de link. U ziet uw geüploade afbeelding op Imgur.

aan de slag

met het app-overzicht uit de weg, kunnen we het nu instellen. Er zijn een paar dingen die je moet doen om het aan de praat te krijgen. Ten eerste heb je een Client-ID van Imgur nodig om hun API te gebruiken en ten tweede moet je een App-groep instellen. U hebt een ontwikkelaarsaccount nodig om App-groepen in te schakelen. Om een extensie gegevens te delen met de container-app, moet u een App-Groep configureren. Dit geeft toegang tot een gedeelde container tussen de extensie en container app.

we willen dat de extensie om twee redenen toegang heeft tot de gedeelde container: ten eerste, net als de container app, elke afbeelding geüpload via de extensie zal worden opgeslagen en beschikbaar gemaakt voor het bekijken via de container app en ten tweede, We gebruiken een achtergrond sessie voor de upload die vereist dat de afbeelding eerst worden opgeslagen voor het uploaden, dus we slaan een tijdelijke afbeelding in de gedeelde container die wordt gebruikt in de achtergrond upload taak. We gebruiken achtergrond upload omdat gebruikers de neiging om terug te gaan naar de host app onmiddellijk na het voltooien van hun taak in Extensies, dus als de upload is potentieel langdurig, we willen dat het wordt uitgevoerd tot voltooiing, zelfs wanneer de extensie wordt beëindigd.

om de Imgur client id te verkrijgen, login op imgur.com of registreer een account op imgur.com/register. eenmaal ingelogd, klik op uw gebruikersnaam in de rechterbovenhoek van het scherm en selecteer Instellingen.

selecteer vervolgens Toepassingen in het menu aan de rechterkant.

Selecteer uw eigen maken onder gebruikte Apps.

klik op een toepassing registreren in het menu aan de linkerkant en selecteer hun toepassing registreren zoals weergegeven.

voer op het aanvraagformulier in wat u wilt voor de naam van de toepassing. Voor autorisatie type, selecteer OAuth 2 autorisatie zonder een callback URL, voer uw e-mailadres in e-mail en voer wat je wilt voor beschrijving. Voer de beveiligingstekst in het vak in en verzend het formulier.

na een succesvolle inzending krijgt u uw Client ID en Client secret te zien.

kopieer de Client ID en open UploadImageService.swift (zoek het in de ImgurKit groep) en plak het in het getoonde statement.

1
private let imgurClientId = “IMGUR_CLIENT_ID”

als u de App-groep wilt configureren, wijzigt u eerst de Bundelidentificatie van de app. Selecteer ImgurShare in de Projectnavigator en selecteer vervolgens het imgurshare-doel in de lijst doelen. Wijzig op het tabblad Algemeen de bundelidentificatie van com.appcoda.ImgurShare naar iets anders. U hebt een andere identifier nodig, omdat de identifier die u voor uw app-groep gebruikt, moet overeenkomen met de Bundelidentifier en uniek moet zijn.

ga vervolgens naar het tabblad mogelijkheden en schakel de schakelaar voor appgroepen in. Voeg een nieuwe groep toe en noem het group. com .. ImgurShare. voor mijn geval heb ik group.com. appcoda. ImgurShare.

aanmaken van de Share-extensie

Open AddImageViewController.swift-bestand en in de functie shareImage(imageTitle:, imageToUpload:) wijzigt u de container-ID om overeen te komen met de groep die u hebt gemaakt.

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

Open ImageService.swift en doe hetzelfde voor het volgende statement in de tempContainerURL (image:, name:) functie.

doe hetzelfde voor het statement getoond in de getFileUrl () functie in dezelfde klasse.

u kunt de app nu uitvoeren en testen.

vervolgens maken we de Share-extensie aan. Selecteer het ImgurShare-project in de Projectnavigator en ga dan naar Editor > doel toevoegen > iOS > Toepassingsextensie > Share Extension

stel op het volgende scherm de productnaam in op ImgurUpload en laat de overige velden ingesteld op hun standaard. Klik op Voltooien en activeer het imgurupload schema

vervolgens, configureer de App Groep voor de imgurupload doel. Selecteer het ImgurShare project in de project Navigator en selecteer vervolgens het imgurupload doel. Schakel op het tabblad mogelijkheden de schakelaar voor appgroepen in en selecteer de groep die u eerder hebt gemaakt voor het ImgurShare-doel.

om het delen van code tussen de extensie en container app mogelijk te maken, heb ik de code in een framework geplaatst. We moeten dit linken aan het imgurupload doel.

met het ImgurUpload-doel geselecteerd, klik op het tabblad Algemeen op de knop + onder de sectie gekoppelde Frameworks and Libraries. Selecteer ImgurKit.framework in de lijst en klik op Toevoegen.

met die set-up, laten we nu kijken naar de bestanden die zijn gegenereerd toen we de extensie. Vouw de ImgurUpload-groep uit en u ziet een storyboard-bestand, een bestand met rechten, een weergavecontroller en een plist-bestand onder de ondersteunende bestanden groep. Het bestand rechten in een extensie, net als in de container-app, wordt gegenereerd wanneer u appgroepen configureert. Het bevat details van uw app groep. Net als in Actie-extensies, kunt u een JavaScript-bestand gebruiken om inhoud van webpagina ‘ s in Safari te krijgen. We zullen niet worden met behulp van deze in onze extensie, maar voor een idee over hoe u JavaScript-bestanden te gebruiken om gegevens van de host-app te krijgen om de extensie ‘ s view controller, kunt u verwijzen naar het vorige artikel dat we deden op actie-extensies. Het proces en de opzet is vrij vergelijkbaar.

u kunt het storyboard-bestand gebruiken om een aangepaste interface te maken (of doe het in code), maar share-extensies worden geleverd met een standaard samenstelweergave die we zullen gebruiken. Het is de interface is vergelijkbaar met de compose view krijg je wanneer je iets te delen op Twitter of Facebook.

we moeten het type inhoud specificeren dat onze extensie ondersteunt door de activeringsregel in te stellen in het plist-bestand. Open Info.plist en uitbreiden van de nsextension sleutel. Breid dan de nsextensionattributes sleutel uit om aan de NSExtensionActivationRule te komen. Standaard is dit ingesteld op TRUEPREDICATE, wat betekent dat uw extensie altijd beschikbaar zal worden gesteld wanneer de gebruiker inhoud wil delen. U moet dit veranderen en maken het specifiek als u wilt dat uw app te worden goedgekeurd door de App Store. Wijzig het type in woordenboek en voeg een nieuw sleutel-waarde paar. Stel de sleutelnaam in op Nsextensionactivationsupportsimage met Maxcount, type Op nummer en waarde op 1. Hiermee geeft u op dat de extensie het delen van één afbeelding tegelijk ondersteunt.

kijkend naar de shareviewcontroller klasse, vindt u de volgende methode stubs.

  • isContentValid–) – Dit is waar gebruikersinvoer wordt gevalideerd. U valideert zowel de tekstinvoer als de inhoud die gedeeld moet worden en retourneert true als de validatie doorgaat. De Post-knop in de composeerweergave blijft uitgeschakeld totdat true wordt geretourneerd.
  • didSelectPost–) – dit wordt aangeroepen nadat de gebruiker op de knop Post tikt en het is hier dat u de content uploadt die wordt gedeeld. Zodra de upload is gepland, moet u bellen completerquestreturningitems(, completionHandler:), zodat de host app kan un-block zijn UI. Wanneer de upload verzoek wordt gedaan, het roept de voltooiing handler die werd doorgegeven aan de vorige genoemde functie aanroep.
  • configurationItems() – met de standaard samenstellingsweergave van de Share-extensie kunt u instellen wat er onderaan de weergave verschijnt met tabelweergavecellen. Om dit te doen, moet u een array van SLComposeSheetConfigurationItem objecten retourneren Als u configuraties voor de gebruiker in te stellen. Geef anders een lege array terug.

voeg de volgende invoer toe aan de ShareViewController-klasse.

1
2

importeren ImgurKit
importeren MobileCoreServices

Voeg de volgende variabele van de klasse. Dit houdt de door de gebruiker geselecteerde afbeelding vast.

1
var selecte image: UIImage?

vervolgens zullen we viewDidLoad() overschrijven om de afbeelding uit de bijlage items in extensionContext te extraheren. Wanneer de gebruiker een afbeelding plaatst, wordt deze gebundeld met andere metadata en doorgegeven aan de extensie via het object extensionContext. Voeg het volgende toe aan de klasse.

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

override 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 (data: imageData)
}
} else {
let alert = UIAlertController (titel: “Error”, bericht: “Error loading image”, preferredStyle:.Alarm)
let action = UIAlertAction (titel: “Error”, style: .Annuleren) {_in
zelf.disposviewcontrolleranimated(waar, voltooiing: nihil)
}
alarm.addactie (actie)
self.presentViewController (alert, animated: true, completion: nul)
}
}
}
}
}

hier extraheren we het bijlageitem in het object NSItemProvider en controleren we vervolgens of de bijlage voldoet aan het type kUTTypeImage. kUTTypeImage is een systeemgedefinieerde stringconstante voor Core uniform type identifiers gedefinieerd in het MobileCoreServices framework. We gebruiken het om soorten bijlagen te identificeren.

de afbeelding is verpakt in de klasse NSItemProvider, dus we moeten het eerst laden met behulp van loaditemfortypeinidentifier (). Als dit succesvol is, laden we de afbeelding van de url van waar het is opgeslagen (wanneer geëxtraheerd uit NSItemProvider, afbeeldingen worden opgeslagen op de schijf). We stellen dan de selectedImage variabele met de afbeelding. In geval van een fout wordt de gebruiker een waarschuwing getoond.

wijzig vervolgens de functie isContentValid () zoals getoond.

1
2
3
4
5
6
7
8
9

overschrijven func isContentValid() -> Bool {
als laat img = selectedImage{
als !contentText.isEmpty {
return true
}
}
return false
}

Dit controleren om ervoor te zorgen dat een afbeelding is geselecteerd en de gebruiker in sommige input, voordat ze kunnen posten.

Wijzig didSelectPost () als volgt.

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

overschrijven func didSelectPost() {
laat defaultSession = UploadImageService.sharedService.session
laat defaultSessionConfig = defaultSession.configuratie
laat defaultHeaders = defaultSessionConfig.HTTPAdditionalHeaders
let config = NSURLSessionConfiguration.backgroundsessionconfiguration with identifier (“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.selectedImage!)
afbeelding.url = imageURL
laat imageService = ImageService.sharedService
imageService.addImage (image)
imageService.saveImages()
}
if let container = tempURL {
var delError: NSError?
als NSFileManager.defaultManager ().is verwijderbaar bestand op pad (container.pad!) {
laat succes = NSFileManager.defaultManager ().removeitematpad (container.pad!, fout: &delError)
if (!succes) {
println (“Fout bij het verwijderen van bestand bij pad: \(fout?.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?.omschrijving)”)
}
}
}
}
}
let title = contentText
UploadImageService.sharedService.uploadImage (selectedImage!, title: title, session: session, completion:completion)
zelf.uitbreidingscontext?.voltooiingsverzoekterugkeer punten (, nihil)
}

Vervang de app Group identifier in de verklaring hieronder door uw eigen.

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

hier definiëren we de achtergrond sessie die we zullen gebruiken voor de upload. We definiëren vervolgens het voltooiingsblok dat zal worden aangeroepen wanneer het verzoek is voltooid. In de voltooiing blok, we controleren om te zien of de upload succesvol was en zo ja, sla de afbeelding (beelden die hier zijn opgeslagen zal worden geladen op de container app table view). We verwijderen vervolgens de tijdelijke afbeelding die op de schijf was opgeslagen tijdens het achtergrondverzoek. Als de upload mislukt, we verwijderen ook de tijdelijke afbeelding en niet opslaan voor later bekijken op de container app. We willen alleen dat de container-app afbeeldingen weergeeft die met succes zijn geüpload naar Imgur.

let op het gebruik van inhoud. Deze eigenschap bevat de tekstinvoer van de gebruiker.

we roepen dan de functie uploadImage() aan in het ImgurKit framework om het uploaden uit te voeren. Deze methode is asynchroon en zal onmiddellijk terugkeren. Wanneer de upload is voltooid of mislukt, wordt het voltooiingsblok aangeroepen.

volgende wijzig configuratieitems () zoals getoond. We geven een lege array terug omdat we niets zullen toevoegen aan de compose-weergave van de extensie.

1
2
3

override func configurationItems () – > ! {
rendement
}

het testen van de Share-extensie

u kunt nu de app uitvoeren. Zorg ervoor dat het imgurupload-schema is geselecteerd. Als u wordt gevraagd een app te kiezen die u wilt uitvoeren, kiest u foto ‘ s. Eenmaal uitgevoerd, selecteer een foto en tik op de knop Delen. Op de eerste run, moet u uw extensie toe te voegen aan de Share sheet. Selecteer de knop meer aan de rechterkant van de andere delen pictogrammen en zet de schakelaar voor uw extensie selecteer vervolgens gedaan.

terug op de Share sheet, u in staat om uw extensie pictogram naast de andere delen pictogrammen zal zijn. Selecteer uw extensie, voer wat tekst in en tik op Bericht.

de afbeelding wordt geüpload naar Imgur en opgeslagen in de container app. Om dit te bevestigen, navigeert u naar het startscherm en opent u ImgurShare. U ziet de titel die u hebt ingevoerd voor de afbeelding en de afbeelding zelf op de detailweergave.

als u de container-app verlaat en teruggaat naar de foto ‘ s-app om een andere afbeelding te delen en teruggaat naar de container-app, zult u merken dat de tabel niet automatisch wordt bijgewerkt met toegevoegd item. Als u een tabelrij selecteert en vervolgens teruggaat naar de tabelweergave, wordt de tabel bijgewerkt. We moeten de tabelgegevens herladen wanneer de app terug op de voorgrond komt. Voeg hiervoor eerst de volgende functie toe aan ImagesTableViewController klasse.

1
2
3

func refreshTable () {
tableView.reloadData()
}

dan in AppDelegate.swift, voeg het volgende toe aan de functie applicationWillEnterForeground ().

1
2

let vc = ImagesTableViewController ()
vc.verversbaar()

nu wanneer u een afbeelding uploaden via de extensie en breng de container app terug naar de voorgrond, de tabel zal worden bijgewerkt.

samenvatting

hiermee eindigt deze Share Extension tutorial. Ik hoop dat de gids komt van pas voor iedereen die een aandeel extensie te creëren. U kunt de projectbestanden hier downloaden.

Noot: Bij het delen van een bestand via de extensie, zult u een foutmelding in de debugger merken “failed to erven CoreMedia permissions from xxxx”. Dit lijkt een veel voorkomende fout te zijn, en ik heb het ondervonden bij het werken met vandaag, delen en actie-extensies. De extensie werkt nog steeds prima, ondanks de fout. Zoeken rond, het lijkt gebruikelijk te zijn en in deze StackOverflow post, iemand zegt dat hun extensie werkt prima en werd goedgekeurd door Apple ondanks het krijgen van de fout. Dus, het kan een Xcode bug zijn. Ik weet het niet zeker. U kunt uw gedachten achterlaten in de reactie.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.