Reutilizar páginas de Xamarin.Forms en una extensión de iOS
Las extensiones de iOS permiten personalizar el comportamiento del sistema existente agregando una funcionalidad adicional a puntos de extensión predefinidos de iOS y macOS, como acciones de contexto personalizadas, autorrellenado de contraseñas, filtros de llamadas entrantes, modificadores de contenido de notificación, etc. Xamarin.iOS admite extensiones y esta guía le guiará a través de la creación de una extensión de iOS mediante herramientas de Xamarin.
Las extensiones se distribuyen como parte de una aplicación contenedora y se activan desde un punto de extensión específico en una aplicación host. La aplicación Contenedor suele ser una aplicación de iOS sencilla, que proporciona a un usuario información sobre la extensión, cómo activarla y usarla. Hay tres enfoques principales para compartir código entre una extensión y una aplicación contenedora:
Proyecto de iOS común.
Puede colocar todo el código compartido entre el contenedor y la extensión en una biblioteca compartida de iOS y hacer referencia a la biblioteca de ambos proyectos. Normalmente, la biblioteca compartida contiene uiViewControllers nativos y tiene que ser una biblioteca de Xamarin.iOS.
Vínculos de archivo.
En algunos casos, la aplicación Contenedor proporciona la mayor parte de la funcionalidad, mientras que la extensión debe representar un solo
UIViewController
. Con pocos archivos para compartir, es habitual agregar un vínculo de archivo a la aplicación de extensión desde el archivo ubicado en la aplicación contenedora.Proyecto común de Xamarin.Forms.
Si las páginas de la aplicación ya se comparten con otra plataforma, como Android, mediante el marco de Xamarin.Forms, el enfoque común es volver a implementar las páginas necesarias de forma nativa en el proyecto de extensión, ya que la extensión de iOS funciona con uiViewControllers nativos y no con páginas de Xamarin.Forms. Tiene que realizar pasos adicionales para usar Xamarin.Forms en la extensión de iOS, que se explica a continuación.
Xamarin.Forms en un proyecto de extensión de iOS
La capacidad de usar Xamarin.Forms en un proyecto nativo se proporciona a través de Native Forms. Permite agregar páginas derivadas de ContentPage
directamente a proyectos nativos de Xamarin.iOS. El método de extensión CreateViewController
convierte una instancia de una página de Xamarin.Forms en un UIViewController
nativo, que se podría usar o modificar como controlador normal. Dado que una extensión de iOS es un tipo especial de un proyecto nativo de iOS, también puede usar formularios nativos aquí.
Importante
Hay muchas limitaciones conocidas para las extensiones de iOS. Aunque puede usar Xamarin.Forms en una extensión de iOS, debe hacerlo con cuidado, supervisar el uso de memoria y el tiempo de inicio. De lo contrario, iOS podría terminar la extensión sin ninguna manera de controlar esto correctamente.
Tutorial
En este tutorial, va a crear una aplicación de Xamarin.Forms, una extensión de Xamarin.iOS y reutilizar código compartido en el proyecto de extensión:
Abra Visual Studio para Mac, cree un proyecto de Xamarin.Forms con la plantilla Aplicación de formularios en blanco y asígnele el nombre FormsShareExtension:
En FormsShareExtension/MainPage.xaml, reemplace el contenido por el siguiente diseño:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="FormsShareExtension.MainPage" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:local="clr-namespace:FormsShareExtension" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:DataType="local:MainPageViewModel" BackgroundColor="Orange" mc:Ignorable="d"> <ContentPage.BindingContext> <local:MainPageViewModel Message="Hello from Xamarin.Forms!" /> </ContentPage.BindingContext> <StackLayout HorizontalOptions="Center" VerticalOptions="Center"> <Label Margin="20" Text="{Binding Message}" VerticalOptions="CenterAndExpand" /> <Button Command="{Binding DoCommand}" Text="Do the job!" /> </StackLayout> </ContentPage>
Agregue una nueva clase denominada MainPageViewMode al proyecto FormsShareExtension y reemplace el contenido de la clase por el código siguiente:
using System; using System.ComponentModel; using System.Windows.Input; using Xamarin.Forms; namespace FormsShareExtension { public class MainPageViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _message; public string Message { get { return _message; } set { if (_message != value) { _message = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Message))); } } } private ICommand _doCommand; public ICommand DoCommand { get { return _doCommand; } set { if(_doCommand != value) { _doCommand = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DoCommand))); } } } public MainPageViewModel() { DoCommand = new Command(OnDoCommandExecuted); } private void OnDoCommandExecuted(object state) { Message = $"Job {Environment.TickCount} has been completed!"; } } }
El código se comparte en todas las plataformas y también lo usará una extensión de iOS.
En el panel de solución, haga clic con el botón derecho en la solución, seleccione, seleccione Agregar > Nuevo proyecto > iOS > Extensión > Extensión de acción, asígnele el nombre MyAction y presione Crear:
Para usar Xamarin.Forms en la extensión de iOS y el código compartido, debe agregar referencias necesarias:
Haga clic con el botón derecho en la extensión de iOS, seleccione Referencias > Agregar referencias > Proyectos > FormsShareExtension y presione Aceptar.
Haga clic con el botón derecho en la extensión de iOS, seleccione Paquetes > Administrar paquetes NuGet... > Xamarin.Forms y presione Agregar paquete.
Expanda el proyecto de extensión y modifique un punto de entrada para inicializar Xamarin.Forms y crear páginas. Según los requisitos de iOS, una extensión debe definir el punto de entrada de Info.plist como
NSExtensionMainStoryboard
oNSExtensionPrincipalClass
. Una vez activado el punto de entrada, en este caso es el métodoActionViewController.ViewDidLoad
, puede crear una instancia de una página de Xamarin.Forms y mostrarla a un usuario. Por lo tanto, abra el punto de entrada y reemplace el métodoViewDidLoad
por la siguiente implementación:public override void ViewDidLoad() { base.ViewDidLoad(); // Initialize Xamarin.Forms framework global::Xamarin.Forms.Forms.Init(); // Create an instance of XF page with associated View Model var xfPage = new MainPage(); var viewModel = (MainPageViewModel)xfPage.BindingContext; viewModel.Message = "Welcome to XF Page created from an iOS Extension"; // Override the behavior to complete the execution of the Extension when a user press the button viewModel.DoCommand = new Command(() => DoneClicked(this)); // Convert XF page to a native UIViewController which can be consumed by the iOS Extension var newController = xfPage.CreateViewController(); // Present new view controller as a regular view controller this.PresentModalViewController(newController, false); }
Se crea una instancia de
MainPage
mediante un constructor estándar y antes de poder usarlo en la extensión, conviértalo en unUIViewController
nativo mediante el método de extensiónCreateViewController
.Compile y ejecute la aplicación:
Para activar la extensión, vaya al explorador Safari, escriba cualquier dirección web, por ejemplo, microsoft.com, presione navegar y, a continuación, presione el icono Compartir en la parte inferior de la página para ver las extensiones de acción disponibles. En la lista de extensiones disponibles, seleccione la extensión MyAction pulsando en ella:
La extensión se activa y la página de Xamarin.Forms se muestra al usuario. Todos los enlaces y comandos funcionan como en la aplicación Contenedor.
El controlador de vista del punto de entrada original es visible porque iOS lo crea y activa. Para corregirlo, cambie el estilo de presentación modal a
UIModalPresentationStyle.FullScreen
para el nuevo controlador agregando el código siguiente justo antes de la llamadaPresentModalViewController
:newController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
Compile y ejecute en el simulador de iOS o en un dispositivo:
Importante
Para la compilación del dispositivo, asegúrese de usar la configuración de compilación adecuada y la configuración Versión, como se describe aquí.