Extensões do iOS no Xamarin.iOS

Criando extensões no vídeo do iOS

As extensões, conforme introduzidas no iOS 8, são especializadas UIViewControllers e apresentadas pelo iOS dentro de contextos padrão, como na Central de Notificações, como tipos de teclado personalizados solicitados pelo usuário para executar entrada especializada ou outros contextos, como editar uma foto em que 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 gravados usando as APIs unificadas de 64 bits) e são ativadas 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 determinado tipo de mídia com.apple.ui-services Qualquer
Provedor de documentos Permite que o aplicativo use um armazenamento de documentos remoto com.apple.fileprovider-ui Aplicativos que usam 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 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 com suporte no Guia de Programação de Extensão de Aplicativo iOS.

Limitações

As extensões têm várias 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 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 de contêiner, que, por sua vez, é enviado e distribuído por meio da App Store. As extensões distribuídas 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 ativados 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 ativados no ponto de uso, como ativar uma extensão de compartilhamento ao enviar uma foto.

O aplicativo no qual a Extensão é usada (em que 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 ela foi instalada.

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 falha da extensão ou encerramento agressivo pelo sistema. Portanto, certifique-se de criar 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 de versão .
  2. Nas configurações do projeto de build do iOS, defina a opção Comportamento do vinculador como Vincular somente SDKs do Framework 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 encontra 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 Controlador de Exibição. No entanto, ao contrário de um aplicativo normal, que é suspenso, mas geralmente não encerrado quando o usuário termina de interagir com eles, as extensões são carregadas, executadas e 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 quiserem atualizar a interface do usuário. Consulte a seção Comunicação 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 de contêiner é essencialmente um contêiner de "remessa" vazio cuja finalidade é atendida depois que a extensão é instalada. No entanto, se as circunstâncias exigirem, o aplicativo de contêiner e a extensão poderão compartilhar recursos de uma área comum. Além disso, uma Extensão Today pode solicitar que seu aplicativo de contêiner abra uma URL. Esse comportamento é mostrado no widget Event Countdown.

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 do aplicativo de contêiner

O aplicativo de contêiner usado para instalar a extensão tem os seguintes requisitos:

  • Ele deve manter uma referência ao projeto de extensão.
  • Deve ser um aplicativo completo (deve ser capaz de iniciar e executar com êxito), mesmo que não faça nada além de fornecer uma maneira de instalar uma extensão.
  • Ele deve ter um Identificador de Pacote que é 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 tem os seguintes requisitos:

  • Ele deve ter um Identificador de Pacote que comece com o Identificador de Pacote do aplicativo de contêiner. Por exemplo, se o aplicativo de contêiner tiver um identificador de pacote de , o identificador da com.myCompany.ContainerAppextensão poderá 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 do Centro de Notificações ou Today 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) desses requisitos será fornecida e atendida automaticamente pelo modelo.

Passo a passo

No passo a passo a seguir, você criará um widget Hoje de exemplo 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 Avançar

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

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

  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 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 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 Avançar

  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, conforme mostrado aqui

Criando a interface do usuário da extensão

Em seguida, você precisará projetar a interface para o 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 abaixo 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 dos 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 dê a ele o nome TodayMessage 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 TodayMessage 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 DaysRemaining , adicione uma nova classe e chame-a CodeBasedViewControllerde :

    Eleja o projeto DaysRemaining, 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 Info.plist de extensões para abri-lo para edição

  3. Selecione a Visualização de origem (na parte inferior da tela) e abra o NSExtension nó:

    Selecione o Modo de Exibiçã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 faça com que ele fique 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 especificado 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 se pareça com o seguinte:

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 inicializadas e desalocadas repetidamente 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 exibição principal do contêiner será exibida:

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

Em seguida, aperte o botão Início no Simulador, deslize de cima para baixo na tela para abrir a Central de Notificações, selecione a guia Hoje e clique no botão Editar:

Aperte o botão Home no Simulador, deslize de cima para baixo na 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 à visualizaçã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

Comunicação 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, ele usaria a propriedade ExtensionContext das TodayViewController classes or 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 arquivo .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.

Comunicação 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 .

Serviços MobileCoreServices

Ao trabalhar com extensões, use um Uniform Type Identifier (UTI) para criar e manipular dados 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 no usuário e no 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 de marca que permita ao usuário identificar o desenvolvedor da Extensão ou o aplicativo de contêiner ao qual ele pertence.

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

Resumo

Este documento abordou 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 Today 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 Simulador do iOS. Por fim, 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.