Compartilhar via


Extensões do iOS no Xamarin.iOS

Criando extensões no vídeo do iOS

As extensões, como introduzidas no iOS 8, são especializadas UIViewControllers que são apresentadas pelo iOS dentro de contextos padrão, como dentro da Central de Notificações, como tipos de teclado personalizados solicitados pelo usuário para executar entrada especializada ou outros contextos, como editar uma foto onde a Extensão pode fornecer filtros de efeitos especiais.

Todas as extensões são instaladas em conjunto com um aplicativo de contêiner (com ambos os elementos escritos usando as APIs unificadas de 64 bits) e são ativadas a partir de um ponto de extensão específico em um aplicativo host. E como eles serão usados como suplementos às funções existentes do sistema, eles devem ser de alto desempenho, enxutos e robustos.

Pontos de extensão

Tipo Descrição Ponto de Extensão Aplicativo host
Ação Editor ou visualizador especializado para um tipo de mídia específico com.apple.ui-services Qualquer
Provedor de Documentos Permite que o aplicativo use um repositório de documentos remoto com.apple.fileprovider-ui Aplicativos usando um UIDocumentPickerViewController
Teclado Teclados alternativos com.apple.keyboard-service Qualquer
Edição de Fotos Manipulação e edição de fotos com.apple.photo-editing Photos.app editor
Compartilhar Compartilha dados com redes sociais, serviços de mensagens, etc. com.apple.share-services Qualquer
Hoje "Widgets" que aparecem na tela Hoje ou na Central de Notificações com.apple.widget-extensions Hoje e a Central de Notificações

Pontos de extensão adicionais foram adicionados no iOS 10 e iOS 12. Você pode encontrar a tabela completa de todos os tipos suportados no Guia de Programação de Extensão de Aplicativo iOS.

Limitações

As extensões têm uma série de limitações, algumas das quais são universais para todos os tipos (por exemplo, nenhum tipo de extensão pode acessar as câmeras ou microfones), enquanto outros tipos de extensão podem ter limitações específicas em seu uso (por exemplo, teclados personalizados não podem ser usados para campos de entrada de dados seguros, como para senhas).

As limitações universais são:

Para limitações individuais, consulte o Guia de Programação de Extensão de Aplicativo da Apple.

Distribuindo, instalando e executando extensões

As extensões são distribuídas de dentro de um aplicativo contêiner, que, por sua vez, é enviado e distribuído pela App Store. A(s) extensão(ões) distribuída(s) com o aplicativo são instaladas nesse ponto, mas o usuário deve habilitar cada extensão explicitamente. Os diferentes tipos de extensões são habilitados de maneiras diferentes; vários exigem que o usuário navegue até o aplicativo Configurações e habilite-os a partir daí. Enquanto outros são habilitados no ponto de uso, como ativar uma extensão de compartilhamento ao enviar uma foto.

O aplicativo no qual a Extensão é usada (onde o usuário encontra o Ponto de Extensão) é chamado de aplicativo Host, pois é o aplicativo que hospeda a Extensão quando ela é executada. O aplicativo que instala a Extensão é o aplicativo Contêiner, pois é o aplicativo que continha a Extensão quando foi instalado.

Normalmente, o aplicativo de contêiner descreve a extensão e orienta o usuário pelo processo de habilitá-la.

Depurar e lançar versões de extensões

Os limites de memória para executar extensões de aplicativo são significativamente menores do que os limites de memória aplicados a um aplicativo em primeiro plano. Os simuladores que executam o iOS têm menos restrições aplicadas às extensões, e você pode executar sua extensão sem problemas. No entanto, executar a mesma extensão em um dispositivo pode levar a resultados inesperados, incluindo a falha da extensão ou ser agressivamente encerrada pelo sistema. Portanto, certifique-se de compilar e testar a extensão em um dispositivo antes de enviá-la.

Você deve garantir que as seguintes configurações sejam aplicadas ao projeto de contêiner e a todas as extensões referenciadas:

  1. Crie um pacote de aplicativos na configuração da versão .
  2. Nas configurações do projeto de compilação do iOS, defina a opção Comportamento do vinculador como Somente SDKs do Framework vinculado ou Vincular tudo.
  3. Nas configurações do projeto de depuração do iOS, desmarque a opção Habilitar depuração e Habilitar criação de perfil.

Ciclo de vida da extensão

Uma extensão pode ser tão simples quanto um único UIViewController ou extensões mais complexas que apresentam várias telas de interface do usuário. Quando o usuário encontrar um Ponto de Extensão (como ao compartilhar uma imagem), ele terá a oportunidade de escolher entre as Extensões registradas para esse Ponto de Extensão.

Se eles escolherem uma das extensões do seu aplicativo, ela UIViewController será instanciada e iniciará o ciclo de vida normal do View Controller. No entanto, ao contrário de um aplicativo normal, que são suspensos, mas geralmente não terminados quando o usuário termina de interagir com eles, as extensões são carregadas, executadas e, em seguida, encerradas repetidamente.

As extensões podem se comunicar com seus aplicativos Host por meio de um objeto NSExtensionContext . Algumas extensões têm operações que recebem retornos de chamada assíncronos com os resultados. Esses retornos de chamada serão executados em threads em segundo plano e a extensão deve levar isso em consideração; por exemplo, usando NSObject.InvokeOnMainThread se eles quiserem atualizar a interface do usuário. Consulte a seção Comunicando-se com o Aplicativo Host abaixo para obter mais detalhes.

Por padrão, as extensões e seus aplicativos de contêiner não podem se comunicar, apesar de serem instalados juntos. Em alguns casos, o aplicativo Container é essencialmente um contêiner vazio de "envio" cuja finalidade é atendida depois que a extensão é instalada. No entanto, se as circunstâncias o determinarem, o aplicativo Contêiner e a Extensão poderão compartilhar recursos de uma área comum. Além disso, uma extensão Hoje pode solicitar que seu aplicativo Container abra uma URL. Esse comportamento é mostrado no widget de contagem regressiva de eventos.

Criando uma extensão

As extensões (e seus aplicativos de contêiner) devem ser binários de 64 bits e criados usando as APIs unificadas do Xamarin.iOS. Ao desenvolver uma extensão, suas soluções conterão pelo menos dois projetos: o aplicativo de contêiner e um projeto para cada extensão fornecida pelo contêiner.

Requisitos do projeto de aplicativo de contêiner

O aplicativo Container usado para instalar a Extensão tem os seguintes requisitos:

  • Deve manter uma referência ao projeto de Extensão.
  • Ele deve ser um aplicativo completo (deve ser capaz de iniciar e executar com êxito), mesmo que ele não faça nada mais do que fornecer uma maneira de instalar uma extensão.
  • Ele deve ter um Identificador de Pacote que seja a base para o Identificador de Pacote do projeto de Extensão (consulte a seção abaixo para obter mais detalhes).

Requisitos do projeto de extensão

Além disso, o projeto da Extensão possui os seguintes requisitos:

  • Ele deve ter um Identificador de Pacote que comece com o Identificador de Pacote do aplicativo Contêiner. Por exemplo, se o aplicativo de contêiner tiver um identificador de pacote de , o identificador da com.myCompany.ContainerAppextensão pode ser com.myCompany.ContainerApp.MyExtension:

    Identificadores de pacote

  • Ele deve definir a chave NSExtensionPointIdentifier, com um valor apropriado (como com.apple.widget-extension para um widget da Central de Notificações Hoje ), em seu Info.plist arquivo.

  • Ele também deve definir a NSExtensionMainStoryboard chave ou a NSExtensionPrincipalClass chave em seu Info.plist arquivo com um valor apropriado:

    • Use a NSExtensionMainStoryboard chave para especificar o nome do Storyboard que apresenta a interface do usuário principal para a Extensão (menos .storyboard). Por exemplo, Main para o Main.storyboard arquivo.
    • Use a NSExtensionPrincipalClass chave para especificar a classe que será inicializada quando a extensão for iniciada. O valor deve corresponder ao valor Register do seu UIViewController:

    Registro de classe principal

Tipos específicos de extensões podem ter requisitos adicionais. Por exemplo, a classe principal de uma extensão de hoje ou da Central de Notificações deve implementar INCWidgetProviding.

Importante

Se você iniciar seu projeto usando um dos modelos de extensões fornecidos pelo Visual Studio para Mac, a maioria (se não todos) esses requisitos serão fornecidos e atendidos automaticamente pelo modelo.

Passo a passo

No passo a passo a seguir, você criará um exemplo de widget Hoje que calcula o dia e o número de dias restantes no ano:

Um exemplo de widget Hoje que calcula o dia e o número de dias restantes no ano

Criando a solução

Para criar a solução necessária, faça o seguinte:

  1. Primeiro, crie um novo projeto iOS, Single View App e clique no botão Avançar :

    Primeiro, crie um novo projeto iOS, Single View App e clique no botão Next

  2. Chame o projeto TodayContainer e clique no botão Avançar :

    Chame o projeto TodayContainer e clique no botão Next

  3. Verifique o Nome do Projeto e o Nome da Solução e clique no botão Criar para criar a solução:

    Verifique o Nome do Projeto e o Nome da Solução e clique no botão Criar para criar a solução

  4. Em seguida, no Gerenciador de Soluções, clique com o botão direito do mouse na Solução e adicione um novo projeto de Extensão do iOS a partir do modelo Extensão Hoje:

    Em seguida, no Gerenciador de Soluções, clique com o botão direito do mouse na Solução e adicione um novo projeto de Extensão do iOS a partir do modelo Extensão Hoje

  5. Chame o projeto DaysRemaining e clique no botão Avançar :

    Chame o projeto de DaysRemaining e clique no botão Next

  6. Revise o projeto e clique no botão Criar para criá-lo:

    Revise o projeto e clique no botão Criar para criá-lo

A Solução resultante agora deve ter dois projetos, conforme mostrado aqui:

A Solução resultante agora deve ter dois projetos, como mostrado aqui

Criando a interface do usuário da extensão

Em seguida, você precisará projetar a interface para o seu widget Hoje . Isso pode ser feito usando um Storyboard ou criando a interface do usuário no código. Ambos os métodos serão abordados a seguir em detalhes.

Usando storyboards

Para criar a interface do usuário com um Storyboard, faça o seguinte:

  1. No Gerenciador de Soluções, clique duas vezes no arquivo do Main.storyboard projeto de extensão para abri-lo para edição:

    Clique duas vezes no arquivo Main.storyboard de projetos de extensão para abri-lo para edição

  2. Selecione o Rótulo que foi adicionado automaticamente à interface do usuário por modelo e atribua-lhe o NomeTodayMessage na guia Widget do Gerenciador de Propriedades:

    Selecione o Rótulo que foi adicionado automaticamente à interface do usuário por modelo e dê a ele o Nome HojeMensagem na guia Widget do Gerenciador de Propriedades

  3. Salve as alterações no Storyboard.

Usando código

Para criar a interface do usuário no código, faça o seguinte:

  1. No Gerenciador de Soluções, selecione o projeto DaysRemain, adicione uma nova classe e chame-a CodeBasedViewController:

    Eleja o projeto DaysRemain, adicione uma nova classe e chame-a de CodeBasedViewController

  2. Novamente, no Gerenciador de Soluções, clique duas vezes no arquivo da Info.plist Extensão para abri-lo para edição:

    Clique duas vezes no arquivo Extensions Info.plist para abri-lo para edição

  3. Selecione a visualização do código-fonte (na parte inferior da tela) e abra o NSExtension nó:

    Selecione a Visualização de origem na parte inferior da tela e abra o nó NSExtension

  4. Remova a NSExtensionMainStoryboard chave e adicione um NSExtensionPrincipalClass com o valor CodeBasedViewController:

    Remova a chave NSExtensionMainStoryboard e adicione um NSExtensionPrincipalClass com o valor CodeBasedViewController

  5. Salve suas alterações.

Em seguida, edite o CodeBasedViewController.cs arquivo e torne-o parecido com o seguinte:

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...

    }
  }
}

Observe que o [Register("CodeBasedViewController")] corresponde ao valor que você especificou para o NSExtensionPrincipalClass acima.

Codificando a extensão

Com a Interface do Usuário criada, abra o TodayViewController.cs ou o CodeBasedViewController.cs arquivo (com base no método usado para criar a Interface do Usuário acima), altere o método ViewDidLoad e faça com que ele tenha a seguinte aparência:

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 estiver usando o método de interface do usuário baseado em código, substitua o // Insert code to power extension here... comentário pelo novo código acima. Depois de chamar a implementação base (e inserir um Label para a versão baseada em código), esse código faz um cálculo simples para obter o dia do ano e quantos dias restam. Em seguida, ele exibe a mensagem no rótulo (TodayMessage) que você criou no design da interface do usuário.

Observe como esse processo é semelhante ao processo normal de escrever um aplicativo. Uma extensão tem o mesmo ciclo de vida que um controlador de exibição em um aplicativo, exceto que as extensões não têm modos em segundo plano e não são suspensas UIViewController quando o usuário termina de usá-las. Em vez disso, as extensões são repetidamente inicializadas e desalocadas conforme necessário.

Criando a interface do usuário do aplicativo de contêiner

Para este passo a passo, o aplicativo de contêiner é simplesmente usado como um método para enviar e instalar a extensão e não fornece nenhuma funcionalidade própria. Edite o arquivo do Main.storyboard TodayContainer e adicione algum texto definindo a função da extensão e como instalá-la:

Edite o arquivo TodayContainers Main.storyboard e adicione algum texto definindo a função Extensions e como instalá-la

Salve as alterações no Storyboard.

Testando a extensão

Para testar sua extensão no simulador do iOS, execute o aplicativo TodayContainer . A visualização principal do contêiner será exibida:

A exibição principal dos contêineres será exibida

Em seguida, pressione o botão Início no Simulador, deslize para baixo a partir da parte superior da tela para abrir a Central de Notificações, selecione a guia Hoje e clique no botão Editar:

Pressione o botão Início no Simulador, deslize para baixo a partir da parte superior da tela para abrir a Central de Notificações, selecione a guia Hoje e clique no botão Editar

Adicione a extensão DaysRemaining à visualização Hoje e clique no botão Concluído :

Adicione a extensão DaysRemaining ao modo de exibição Hoje e clique no botão Concluído

O novo widget será adicionado à visualização Hoje e os resultados serão exibidos:

O novo widget será adicionado à visualização Hoje e os resultados serão exibidos

Comunicando-se com o aplicativo host

O exemplo de extensão Hoje que você criou acima não se comunica com seu aplicativo host (a tela Hoje ). Se o fizesse, usaria a propriedade ExtensionContext das TodayViewController classes ou CodeBasedViewController .

Para extensões que receberão dados de seus aplicativos host, os dados estão na forma de uma matriz de objetos NSExtensionItem armazenados na propriedade InputItems do ExtensionContext do .UIViewController

Outras extensões, como extensões de edição de fotos, podem distinguir entre o usuário concluir ou cancelar o uso. Isso será sinalizado de volta para o aplicativo host por meio dos métodos CompleteRequest e CancelRequest da propriedade ExtensionContext .

Para obter mais informações, consulte o Guia de Programação de Extensão de Aplicativo da Apple.

Comunicando-se com o aplicativo pai

Um grupo de aplicativos permite que diferentes aplicativos (ou um aplicativo e suas extensões) acessem um local de armazenamento de arquivo compartilhado. Grupos de aplicativo podem ser usados para dados como:

Para obter mais informações, consulte a seção Grupos de aplicativos da nossa documentação Trabalhando com recursos .

MobileCoreServices

Ao trabalhar com extensões, use um Uniform Type Identifier (UTI) para criar e manipular dados que são trocados entre o aplicativo, outros aplicativos e/ou serviços.

A MobileCoreServices.UTType classe estática define as seguintes propriedades auxiliares relacionadas às definições da 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

Consulte o seguinte exemplo:

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");
    }
});

Para obter mais informações, consulte a seção Grupos de aplicativos da nossa documentação Trabalhando com recursos .

Precauções e considerações

As extensões têm significativamente menos memória disponível do que os aplicativos. Espera-se que eles tenham um desempenho rápido e com o mínimo de intrusão para o usuário e o aplicativo em que estão hospedados. No entanto, uma Extensão também deve fornecer uma função distinta e útil para o aplicativo de consumo com uma interface do usuário com marca que permita ao usuário identificar o desenvolvedor da Extensão ou o aplicativo de Contêiner ao qual pertencem.

Dado esses requisitos rígidos, você só deve implantar extensões que tenham sido exaustivamente testadas e otimizadas para desempenho e consumo de memória.

Resumo

Este documento abordou as Extensões, o que são, o tipo de Pontos de Extensão e as limitações conhecidas impostas a uma Extensão pelo iOS. Ele discutiu a criação, distribuição, instalação e execução de extensões e o ciclo de vida da extensão. Ele forneceu um passo a passo da criação de um widget Hoje simples mostrando duas maneiras de criar a interface do usuário do widget usando Storyboards ou código. Ele mostrou como testar uma extensão no iOS Simulator. Finalmente, discutiu brevemente a comunicação com o Host App e algumas precauções e considerações que devem ser tomadas ao desenvolver uma extensão.