Estensioni iOS in Xamarin.iOS
Creazione di estensioni nel video iOS
Le estensioni, come introdotto in iOS 8, sono specializzate UIViewControllers
che vengono presentate da iOS all'interno di contesti standard come all'interno del Centro notifiche, come tipi di tastiera personalizzati richiesti dall'utente per eseguire input specializzati o altri contesti come la modifica di una foto in cui l'estensione può fornire filtri di effetto speciali.
Tutte le estensioni vengono installate insieme a un'app Contenitore (con entrambi gli elementi scritti usando le API unificate a 64 bit) e vengono attivate da un particolare punto di estensione in un'app host. E dal momento che saranno utilizzati come integratori per le funzioni di sistema esistenti, devono essere alte prestazioni, magra e robusto.
Punti di estensione
Tipo | Descrizione | Punto di estensione | Host App |
---|---|---|---|
Azione | Editor o visualizzatore specializzato per un particolare tipo di supporto | com.apple.ui-services |
Any |
Provider di documenti | Consente all'app di usare un archivio documenti remoto | com.apple.fileprovider-ui |
App che usano un UIDocumentPickerViewController |
Tastiera | Tastiere alternative | com.apple.keyboard-service |
Any |
Fotoritocco | Modifica e modifica delle foto | com.apple.photo-editing |
editor Photos.app |
Condividi | Condivide i dati con social network, servizi di messaggistica e così via. | com.apple.share-services |
Any |
Oggi | "Widget" visualizzati nella schermata Oggi o nel Centro notifiche | com.apple.widget-extensions |
Oggi e centro notifiche |
Sono stati aggiunti altri punti di estensione in iOS 10 e iOS 12. È possibile trovare la tabella completa di tutti i tipi supportati nella Guida alla programmazione dell'estensione per le app iOS.
Limiti
Le estensioni hanno una serie di limitazioni, alcune delle quali sono universali per tutti i tipi (ad esempio, nessun tipo di estensione può accedere alle fotocamere o ai microfoni) mentre altri tipi di estensione possono avere limitazioni specifiche sull'utilizzo (ad esempio, le tastiere personalizzate non possono essere usate per campi di immissione dati sicuri, ad esempio per le password).
Le limitazioni universali sono:
- I framework dell'interfaccia utente di Health Kit e Event Kit non sono disponibili
- Le estensioni non possono usare le modalità in background estese
- Le estensioni non possono accedere alle fotocamere o ai microfoni del dispositivo (anche se possono accedere ai file multimediali esistenti)
- Le estensioni non possono ricevere dati air drop (anche se possono trasmettere dati tramite Air Drop)
- UIActionSheet e UIAlertView non sono disponibili. Le estensioni devono usare UIAlertController
- Diversi membri di UIApplication non sono disponibili: UIApplication.SharedApplication, UIApplication.OpenUrl, UIApplication.BeginIgnoringInteractionEvents e UIApplication.EndIgnoringInteractionEvents
- iOS applica un limite di utilizzo di memoria di 16 MB per le estensioni odierne.
- Per impostazione predefinita, le estensioni della tastiera non hanno accesso alla rete. Ciò influisce sul debug nel dispositivo (la restrizione non viene applicata nel simulatore), poiché Xamarin.iOS richiede l'accesso alla rete per il funzionamento del debug. È possibile richiedere l'accesso alla rete impostando il
Requests Open Access
valore nel file Info.plist del progetto suYes
. Per altre informazioni sulle limitazioni dell'estensione della tastiera, vedere la Guida alla tastiera personalizzata di Apple.
Per le singole limitazioni, vedere la Guida alla programmazione delle estensioni dell'app di Apple.
Distribuzione, installazione ed esecuzione di estensioni
Le estensioni vengono distribuite dall'interno di un'app contenitore, che a sua volta viene inviata e distribuita tramite l'App Store. Le estensioni distribuite con l'app vengono installate a quel punto, ma l'utente deve abilitare ogni estensione in modo esplicito. I diversi tipi di estensioni sono abilitati in modi diversi; diversi richiedono all'utente di passare all'app Impostazioni e abilitarli da questa posizione. Mentre altri sono abilitati al momento dell'uso, ad esempio l'abilitazione di un'estensione di condivisione durante l'invio di una foto.
L'app in cui viene usata l'estensione (in cui l'utente rileva il punto di estensione) viene definita app host, poiché è l'app che ospita l'estensione quando viene eseguita. L'app che installa l'estensione è l'app Contenitore, perché è l'app che contiene l'estensione quando è stata installata.
In genere, l'app contenitore descrive l'estensione e illustra all'utente il processo di abilitazione.
Eseguire il debug e la versione delle estensioni
I limiti di memoria per l'esecuzione delle estensioni dell'app sono significativamente inferiori ai limiti di memoria applicati a un'app in primo piano. I simulatori che eseguono iOS hanno meno restrizioni applicate alle estensioni ed è possibile eseguire l'estensione senza problemi. Tuttavia, l'esecuzione della stessa estensione in un dispositivo può causare risultati imprevisti, incluso l'arresto anomalo dell'estensione o terminare in modo aggressivo dal sistema. Assicurarsi quindi di compilare e testare l'estensione in un dispositivo prima di spedirla.
È necessario assicurarsi che le impostazioni seguenti vengano applicate al progetto contenitore e a tutte le estensioni a cui si fa riferimento:
- Compilare un pacchetto dell'applicazione nella configurazione release .
- Nelle impostazioni del progetto di compilazione iOS impostare l'opzione Comportamento del linker su Collega solo SDK framework o Collega tutto.
- Nelle impostazioni del progetto debug iOS deselezionare l'opzione Abilita debug e Abilita profilatura.
Ciclo di vita dell'estensione
Un'estensione può essere semplice come un singolo UIViewController o estensioni più complesse che presentano più schermate dell'interfaccia utente. Quando l'utente rileva un punto di estensione (ad esempio quando si condivide un'immagine), avrà la possibilità di scegliere tra le estensioni registrate per tale punto di estensione.
Se scelgono una delle estensioni dell'app, UIViewController
ne verrà creata un'istanza e inizieranno il normale ciclo di vita del controller di visualizzazione. Tuttavia, a differenza di un'app normale, che viene sospesa ma non terminata in genere quando l'utente termina l'interazione con loro, le estensioni vengono caricate, eseguite e quindi terminate ripetutamente.
Le estensioni possono comunicare con le app host tramite un oggetto NSExtensionContext . Alcune estensioni includono operazioni che ricevono callback asincroni con i risultati. Questi callback verranno eseguiti sui thread in background e l'estensione deve prendere in considerazione questo aspetto; ad esempio, usando NSObject.InvokeOnMainThread se vogliono aggiornare l'interfaccia utente. Per altri dettagli, vedere la sezione Comunicazione con l'app host di seguito.
Per impostazione predefinita, le estensioni e le app contenitore non possono comunicare, nonostante l'installazione insieme. In alcuni casi, l'app contenitore è essenzialmente un contenitore "shipping" vuoto il cui scopo viene servito dopo l'installazione dell'estensione. Tuttavia, se le circostanze determinano, l'app Contenitore e l'estensione possono condividere risorse da un'area comune. Inoltre, un'estensione today può richiedere all'app Contenitore di aprire un URL. Questo comportamento viene visualizzato nel widget Conto alla rovescia eventi.
Creazione di un'estensione
Le estensioni (e le relative app contenitore) devono essere file binari a 64 bit e compilate usando le API unificate di Xamarin.iOS. Quando si sviluppa un'estensione, le soluzioni conterranno almeno due progetti: l'app contenitore e un progetto per ogni estensione fornita dal contenitore.
Requisiti del progetto dell'app contenitore
L'app Contenitore usata per installare l'estensione presenta i requisiti seguenti:
- Deve mantenere un riferimento al progetto Di estensione.
- Deve essere un'app completa (deve essere in grado di avviare ed eseguire correttamente) anche se non offre altro che un modo per installare un'estensione.
- Deve avere un identificatore bundle che costituisce la base per l'identificatore bundle del progetto di estensione (vedere la sezione seguente per altri dettagli).
Requisiti del progetto di estensione
Inoltre, il progetto dell'estensione ha i requisiti seguenti:
Deve avere un identificatore bundle che inizia con l'identificatore bundle dell'app contenitore. Ad esempio, se l'app contenitore ha un identificatore bundle di
com.myCompany.ContainerApp
, l'identificatore dell'estensione potrebbe esserecom.myCompany.ContainerApp.MyExtension
:Deve definire la chiave
NSExtensionPointIdentifier
, con un valore appropriato (ad esempiocom.apple.widget-extension
per un widget Centro notifiche oggi ), nel relativoInfo.plist
file.Deve anche definire la
NSExtensionMainStoryboard
chiave o laNSExtensionPrincipalClass
chiave nel fileInfo.plist
con un valore appropriato:- Usare la
NSExtensionMainStoryboard
chiave per specificare il nome dello storyboard che presenta l'interfaccia utente principale per l'estensione (meno.storyboard
). Ad esempio,Main
per ilMain.storyboard
file. - Usare la
NSExtensionPrincipalClass
chiave per specificare la classe che verrà inizializzata all'avvio dell'estensione. Il valore deve corrispondere al valore Register dell'oggetto :UIViewController
- Usare la
Tipi specifici di estensioni possono avere requisiti aggiuntivi. Ad esempio, una classe principale dell'estensione Today o Notification Center deve implementare INCWidgetProviding.
Importante
Se si avvia il progetto usando uno dei modelli di estensioni forniti da Visual Studio per Mac, la maggior parte di questi requisiti verrà fornita e soddisfatta automaticamente dal modello.
scenario
Nella procedura dettagliata seguente verrà creato un widget Today di esempio che calcola il giorno e il numero di giorni rimanenti nell'anno:
Creazione della soluzione
Per creare la soluzione necessaria, eseguire le operazioni seguenti:
Creare prima di tutto un nuovo progetto di app iOS, Visualizzazione singola e fare clic sul pulsante Avanti:
Chiamare il progetto
TodayContainer
e fare clic sul pulsante Avanti :Verificare il nome del progetto e SolutionName e fare clic sul pulsante Crea per creare la soluzione:
Nella Esplora soluzioni fare quindi clic con il pulsante destro del mouse sulla soluzione e aggiungere un nuovo progetto di estensione iOS dal modello Di estensione oggi:
Chiamare il progetto
DaysRemaining
e fare clic sul pulsante Avanti :Esaminare il progetto e fare clic sul pulsante Crea per crearlo:
La soluzione risultante dovrebbe ora avere due progetti, come illustrato di seguito:
Creazione dell'interfaccia utente dell'estensione
Sarà quindi necessario progettare l'interfaccia per il widget Today . Questa operazione può essere eseguita usando uno Storyboard o creando l'interfaccia utente nel codice. Entrambi i metodi verranno trattati in dettaglio.
Uso di storyboard
Per compilare l'interfaccia utente con uno Storyboard, eseguire le operazioni seguenti:
Nella Esplora soluzioni fare doppio clic sul file del
Main.storyboard
progetto estensione per aprirlo per la modifica:Selezionare l'etichetta aggiunta automaticamente all'interfaccia utente per modello e assegnargli il nome
TodayMessage
nella scheda Widget di Esplora proprietà:Salvare le modifiche apportate allo Storyboard.
Uso del codice
Per compilare l'interfaccia utente nel codice, eseguire le operazioni seguenti:
Nella Esplora soluzioni selezionare il progetto DaysRemaining, aggiungere una nuova classe e chiamarla
CodeBasedViewController
:Anche in questo caso, nel Esplora soluzioni fare doppio clic sul file dell'estensione
Info.plist
per aprirlo per la modifica:Selezionare la visualizzazione origine (nella parte inferiore della schermata) e aprire il
NSExtension
nodo:Rimuovere la
NSExtensionMainStoryboard
chiave e aggiungere un oggettoNSExtensionPrincipalClass
con il valoreCodeBasedViewController
:Salva le modifiche.
Modificare quindi il CodeBasedViewController.cs
file e renderlo simile al seguente:
using System;
using Foundation;
using UIKit;
using NotificationCenter;
using CoreGraphics;
namespace DaysRemaining
{
[Register("CodeBasedViewController")]
public class CodeBasedViewController : UIViewController, INCWidgetProviding
{
public CodeBasedViewController ()
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Add label to view
var TodayMessage = new UILabel (new CGRect (0, 0, View.Frame.Width, View.Frame.Height)) {
TextAlignment = UITextAlignment.Center
};
View.AddSubview (TodayMessage);
// Insert code to power extension here...
}
}
}
Si noti che corrisponde [Register("CodeBasedViewController")]
al valore specificato per quanto NSExtensionPrincipalClass
sopra.
Codifica dell'estensione
Dopo aver creato l'interfaccia utente, aprire o il TodayViewController.cs
CodeBasedViewController.cs
file (in base al metodo usato per creare l'interfaccia utente precedente), modificare il metodo ViewDidLoad e renderlo simile al seguente:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Calculate the values
var dayOfYear = DateTime.Now.DayOfYear;
var leapYearExtra = DateTime.IsLeapYear (DateTime.Now.Year) ? 1 : 0;
var daysRemaining = 365 + leapYearExtra - dayOfYear;
// Display the message
if (daysRemaining == 1) {
TodayMessage.Text = String.Format ("Today is day {0}. There is one day remaining in the year.", dayOfYear);
} else {
TodayMessage.Text = String.Format ("Today is day {0}. There are {1} days remaining in the year.", dayOfYear, daysRemaining);
}
}
Se si usa il metodo user interface basato sul codice, sostituire il // Insert code to power extension here...
commento con il nuovo codice riportato sopra. Dopo aver chiamato l'implementazione di base (e aver inserito un'etichetta per la versione basata sul codice), questo codice esegue un semplice calcolo per ottenere il giorno dell'anno e il numero di giorni rimanenti. Visualizza quindi il messaggio nell'etichetta (TodayMessage
) creata nella progettazione dell'interfaccia utente.
Si noti che questo processo è simile al normale processo di scrittura di un'app. Un'estensione ha lo stesso ciclo di vita di UIViewController
un controller di visualizzazione in un'app, ad eccezione delle estensioni che non hanno modalità in background e non vengono sospese al termine dell'uso da parte dell'utente. Le estensioni vengono invece inizializzate e deallocate ripetutamente in base alle esigenze.
Creazione dell'interfaccia utente dell'app contenitore
Per questa procedura dettagliata, l'app contenitore viene semplicemente usata come metodo per distribuire e installare l'estensione e non offre funzionalità proprie. Modificare il file di Main.storyboard
TodayContainer e aggiungere un testo che definisce la funzione dell'estensione e come installarlo:
Salvare le modifiche apportate allo Storyboard.
Test dell'estensione
Per testare l'estensione nel simulatore iOS, eseguire l'app TodayContainer . Verrà visualizzata la visualizzazione principale del contenitore:
Fare quindi clic sul pulsante Home nel simulatore, scorrere verso il basso nella parte superiore della schermata per aprire il Centro notifiche, selezionare la scheda Oggi e fare clic sul pulsante Modifica :
Aggiungere l'estensione DaysRemaining alla visualizzazione Oggi e fare clic sul pulsante Fine :
Il nuovo widget verrà aggiunto alla visualizzazione Oggi e i risultati verranno visualizzati:
Comunicazione con l'app host
L'esempio Di estensione oggi creata in precedenza non comunica con l'app host (la schermata Oggi ). In caso affermativo, verrà utilizzata la proprietà ExtensionContext delle TodayViewController
classi o CodeBasedViewController
.
Per Le estensioni che riceveranno i dati dalle app host, i dati sono sotto forma di una matrice di oggetti NSExtensionItem archiviati nella proprietà InputItems di ExtensionContext dell'estensione.UIViewController
Altre estensioni, ad esempio le estensioni di modifica foto, possono distinguere tra il completamento o l'annullamento dell'utilizzo da parte dell'utente. Verrà segnalato all'app host tramite i metodi CompleteRequest e CancelRequest della proprietà ExtensionContext .
Per altre informazioni, vedere la Guida alla programmazione delle estensioni per le app di Apple.
Comunicazione con l'app padre
Un Gruppo di app consente a diverse applicazioni o a un'applicazione e alle relative estensioni di accedere a un percorso di archiviazione file condiviso. È possibile usare i Gruppi di app per dati quali:
- Impostazioni di Apple Watch.
- NSUserDefaults condivisi.
- File condivisi.
Per altre informazioni, vedere la sezione Gruppi di app della documentazione Sull'uso delle funzionalità.
MobileCoreServices
Quando si usano le estensioni, usare un UTI (Uniform Type Identifier) per creare e modificare i dati scambiati tra l'app, altre app e/o servizi.
La MobileCoreServices.UTType
classe statica definisce le proprietà helper seguenti correlate alle definizioni di kUTType...
Apple:
kUTTypeAlembic
-Alembic
kUTTypeAliasFile
-AliasFile
kUTTypeAliasRecord
-AliasRecord
kUTTypeAppleICNS
-AppleICNS
kUTTypeAppleProtectedMPEG4Audio
-AppleProtectedMPEG4Audio
kUTTypeAppleProtectedMPEG4Video
-AppleProtectedMPEG4Video
kUTTypeAppleScript
-AppleScript
kUTTypeApplication
-Application
kUTTypeApplicationBundle
-ApplicationBundle
kUTTypeApplicationFile
-ApplicationFile
kUTTypeArchive
-Archive
kUTTypeAssemblyLanguageSource
-AssemblyLanguageSource
kUTTypeAudio
-Audio
kUTTypeAudioInterchangeFileFormat
-AudioInterchangeFileFormat
kUTTypeAudiovisualContent
-AudiovisualContent
kUTTypeAVIMovie
-AVIMovie
kUTTypeBinaryPropertyList
-BinaryPropertyList
kUTTypeBMP
-BMP
kUTTypeBookmark
-Bookmark
kUTTypeBundle
-Bundle
kUTTypeBzip2Archive
-Bzip2Archive
kUTTypeCalendarEvent
-CalendarEvent
kUTTypeCHeader
-CHeader
kUTTypeCommaSeparatedText
-CommaSeparatedText
kUTTypeCompositeContent
-CompositeContent
kUTTypeConformsToKey
-ConformsToKey
kUTTypeContact
-Contact
kUTTypeContent
-Content
kUTTypeCPlusPlusHeader
-CPlusPlusHeader
kUTTypeCPlusPlusSource
-CPlusPlusSource
kUTTypeCSource
-CSource
kUTTypeData
-Database
kUTTypeDelimitedText
-DelimitedText
kUTTypeDescriptionKey
-DescriptionKey
kUTTypeDirectory
-Directory
kUTTypeDiskImage
-DiskImage
kUTTypeElectronicPublication
-ElectronicPublication
kUTTypeEmailMessage
-EmailMessage
kUTTypeExecutable
-Executable
kUTExportedTypeDeclarationsKey
-ExportedTypeDeclarationsKey
kUTTypeFileURL
-FileURL
kUTTypeFlatRTFD
-FlatRTFD
kUTTypeFolder
-Folder
kUTTypeFont
-Font
kUTTypeFramework
-Framework
kUTTypeGIF
-GIF
kUTTypeGNUZipArchive
-GNUZipArchive
kUTTypeHTML
-HTML
kUTTypeICO
-ICO
kUTTypeIconFileKey
-IconFileKey
kUTTypeIdentifierKey
-IdentifierKey
kUTTypeImage
-Image
kUTImportedTypeDeclarationsKey
-ImportedTypeDeclarationsKey
kUTTypeInkText
-InkText
kUTTypeInternetLocation
-InternetLocation
kUTTypeItem
-Item
kUTTypeJavaArchive
-JavaArchive
kUTTypeJavaClass
-JavaClass
kUTTypeJavaScript
-JavaScript
kUTTypeJavaSource
-JavaSource
kUTTypeJPEG
-JPEG
kUTTypeJPEG2000
-JPEG2000
kUTTypeJSON
-JSON
kUTType3dObject
-k3dObject
kUTTypeLivePhoto
-LivePhoto
kUTTypeLog
-Log
kUTTypeM3UPlaylist
-M3UPlaylist
kUTTypeMessage
-Message
kUTTypeMIDIAudio
-MIDIAudio
kUTTypeMountPoint
-MountPoint
kUTTypeMovie
-Movie
kUTTypeMP3
-MP3
kUTTypeMPEG
-MPEG
kUTTypeMPEG2TransportStream
-MPEG2TransportStream
kUTTypeMPEG2Video
-MPEG2Video
kUTTypeMPEG4
-MPEG4
kUTTypeMPEG4Audio
-MPEG4Audio
kUTTypeObjectiveCPlusPlusSource
-ObjectiveCPlusPlusSource
kUTTypeObjectiveCSource
-ObjectiveCSource
kUTTypeOSAScript
-OSAScript
kUTTypeOSAScriptBundle
-OSAScriptBundle
kUTTypePackage
-Package
kUTTypePDF
-PDF
kUTTypePerlScript
-PerlScript
kUTTypePHPScript
-PHPScript
kUTTypePICT
-PICT
kUTTypePKCS12
-PKCS12
kUTTypePlainText
-PlainText
kUTTypePlaylist
-Playlist
kUTTypePluginBundle
-PluginBundle
kUTTypePNG
-PNG
kUTTypePolygon
-Polygon
kUTTypePresentation
-Presentation
kUTTypePropertyList
-PropertyList
kUTTypePythonScript
-PythonScript
kUTTypeQuickLookGenerator
-QuickLookGenerator
kUTTypeQuickTimeImage
-QuickTimeImage
kUTTypeQuickTimeMovie
-QuickTimeMovie
kUTTypeRawImage
-RawImage
kUTTypeReferenceURLKey
-ReferenceURLKey
kUTTypeResolvable
-Resolvable
kUTTypeRTF
-RTF
kUTTypeRTFD
-RTFD
kUTTypeRubyScript
-RubyScript
kUTTypeScalableVectorGraphics
-ScalableVectorGraphics
kUTTypeScript
-Script
kUTTypeShellScript
-ShellScript
kUTTypeSourceCode
-SourceCode
kUTTypeSpotlightImporter
-SpotlightImporter
kUTTypeSpreadsheet
-Spreadsheet
kUTTypeStereolithography
-Stereolithography
kUTTypeSwiftSource
-SwiftSource
kUTTypeSymLink
-SymLink
kUTTypeSystemPreferencesPane
-SystemPreferencesPane
kUTTypeTabSeparatedText
-TabSeparatedText
kUTTagClassFilenameExtension
-TagClassFilenameExtension
kUTTagClassMIMEType
-TagClassMIMEType
kUTTypeTagSpecificationKey
-TagSpecificationKey
kUTTypeText
-Text
kUTType3DContent
-ThreeDContent
kUTTypeTIFF
-TIFF
kUTTypeToDoItem
-ToDoItem
kUTTypeTXNTextAndMultimediaData
-TXNTextAndMultimediaData
kUTTypeUniversalSceneDescription
-UniversalSceneDescription
kUTTypeUnixExecutable
-UnixExecutable
kUTTypeURL
-URL
kUTTypeURLBookmarkData
-URLBookmarkData
kUTTypeUTF16ExternalPlainText
-UTF16ExternalPlainText
kUTTypeUTF16PlainText
-UTF16PlainText
kUTTypeUTF8PlainText
-UTF8PlainText
kUTTypeUTF8TabSeparatedText
-UTF8TabSeparatedText
kUTTypeVCard
-VCard
kUTTypeVersionKey
-VersionKey
kUTTypeVideo
-Video
kUTTypeVolume
-Volume
kUTTypeWaveformAudio
-WaveformAudio
kUTTypeWebArchive
-WebArchive
kUTTypeWindowsExecutable
-WindowsExecutable
kUTTypeX509Certificate
-X509Certificate
kUTTypeXML
-XML
kUTTypeXMLPropertyList
-XMLPropertyList
kUTTypeXPCService
-XPCService
kUTTypeZipArchive
-ZipArchive
Vedere l'esempio seguente:
using MobileCoreServices;
...
NSItemProvider itemProvider = new NSItemProvider ();
itemProvider.LoadItem(UTType.PropertyList ,null, (item, err) => {
if (err == null) {
NSDictionary results = (NSDictionary )item;
NSString baseURI =
results.ObjectForKey("NSExtensionJavaScriptPreprocessingResultsKey");
}
});
Per altre informazioni, vedere la sezione Gruppi di app della documentazione Sull'uso delle funzionalità.
Precauzioni e considerazioni
Le estensioni hanno una quantità significativamente inferiore di memoria rispetto alle app. Si prevede che le prestazioni vengano eseguite rapidamente e con intrusioni minime per l'utente e l'app in cui sono ospitate. Tuttavia, un'estensione deve anche fornire una funzione distintiva e utile per l'app che usa con un'interfaccia utente personalizzata che consente all'utente di identificare lo sviluppatore o l'app contenitore dell'estensione a cui appartiene.
In base a questi requisiti rigorosi, è consigliabile distribuire solo le estensioni che sono state testate accuratamente e ottimizzate per l'utilizzo di prestazioni e memoria.
Riepilogo
Questo documento illustra le estensioni, il tipo di punti di estensione e le limitazioni note imposte a un'estensione da iOS. Ha illustrato la creazione, la distribuzione, l'installazione e l'esecuzione di estensioni e il ciclo di vita dell'estensione. È stata fornita una procedura dettagliata per la creazione di un semplice widget Today che mostra due modi per creare l'interfaccia utente del widget usando storyboard o codice. Ha illustrato come testare un'estensione nel simulatore iOS. Infine, ha brevemente discusso la comunicazione con l'app host e alcune precauzioni e considerazioni da prendere durante lo sviluppo di un'estensione.