Condividi tramite


Riutilizzare le pagine Xamarin.Forms in un'estensione iOS

Le estensioni iOS consentono di personalizzare il comportamento del sistema esistente aggiungendo funzionalità aggiuntive a predefinite dai punti di estensione iOS e macOS, ad esempio azioni di contesto personalizzate, riempimento automatico delle password, filtri delle chiamate in ingresso, modificatori di contenuto di notifica e altro ancora. Xamarin.iOS supporta le estensioni e questa guida illustra come creare un'estensione iOS con gli strumenti Xamarin.

Le estensioni vengono distribuite come parte di un'app contenitore e attivate da un punto di estensione specifico in un'app host. L'app Contenitore è in genere una semplice applicazione iOS, che fornisce a un utente informazioni sull'estensione, su come attivarla e usarla. Esistono tre approcci principali per la condivisione del codice tra un'estensione e un'app contenitore:

  1. Progetto iOS comune.

    È possibile inserire tutto il codice condiviso tra il contenitore e l'estensione in una libreria iOS condivisa e fare riferimento alla libreria da entrambi i progetti. In genere, la libreria condivisa contiene uiViewController nativi e deve essere una libreria Xamarin.iOS.

  2. Collegamenti ai file.

    In alcuni casi, l'app Contenitore offre la maggior parte delle funzionalità, mentre l'estensione deve eseguire il rendering di un singolo UIViewControlleroggetto . Con pochi file da condividere, è comune aggiungere un collegamento di file all'app Estensione dal file che si trova nell'app Contenitore.

  3. Progetto Xamarin.Forms comune.

    Se le pagine dell'app sono già condivise con un'altra piattaforma, ad esempio Android, usando il framework Xamarin.Forms, l'approccio comune consiste nel ricampionare le pagine necessarie in modo nativo nel progetto estensione, perché l'estensione iOS funziona con le pagine UIViewController native e non Xamarin.Forms. È necessario eseguire passaggi aggiuntivi per usare Xamarin.Forms nell'estensione iOS, come illustrato di seguito.

Xamarin.Forms in un progetto di estensione iOS

La possibilità di usare Xamarin.Forms in un progetto nativo viene fornita tramite moduli nativi. Consente l'aggiunta ContentPagedi pagine derivate direttamente ai progetti Xamarin.iOS nativi. Il CreateViewController metodo di estensione converte un'istanza di una pagina Xamarin.Forms in un oggetto nativo UIViewController, che può essere usato o modificato come controller normale. Poiché un'estensione iOS è un tipo speciale di progetto iOS nativo, è anche possibile usare i moduli nativi.

Importante

Esistono molte limitazioni note per le estensioni iOS. Sebbene sia possibile usare Xamarin.Forms in un'estensione iOS, è consigliabile eseguire questa operazione con molta attenzione, monitorando l'utilizzo della memoria e il tempo di avvio. In caso contrario, l'estensione potrebbe essere terminata da iOS senza alcun modo per gestire questa operazione normalmente.

scenario

In questa procedura dettagliata si creerà un'applicazione Xamarin.Forms, un'estensione Xamarin.iOS e si riutilizza il codice condiviso nel progetto di estensione:

  1. Aprire Visual Studio per Mac, creare un nuovo progetto Xamarin.Forms usando il modello App Forms vuota e denominarlo FormsShareExtension:

    Create Project

  2. In FormsShareExtension/MainPage.xaml sostituire il contenuto con il layout seguente:

    <?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>
    
  3. Aggiungere una nuova classe denominata MainPageViewMode al progetto FormsShareExtension e sostituire il contenuto della classe con il codice seguente:

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

    Il codice viene condiviso in tutte le piattaforme e verrà usato anche da un'estensione iOS.

  4. Nel riquadro della soluzione fare clic con il pulsante destro del mouse sulla soluzione, selezionare Aggiungi nuova estensione per iOS Estensione, denominarla MyAction e premere Crea:In solution pad, right click on the solution, select Add New Project > iOS > Extension > Action Extension, name it MyAction and press Create>:

    Screenshot shows the Choose a template with Action Extension selected.

  5. Per usare Xamarin.Forms nell'estensione iOS e nel codice condiviso, è necessario aggiungere i riferimenti necessari:

    • Fare clic con il pulsante destro del mouse sull'estensione iOS, selezionare Riferimenti > Aggiungi progetti > di riferimento > FormsShareExtension e premere OK.

    • Fare clic con il pulsante destro del mouse sull'estensione iOS, selezionare Pacchetti Gestisci pacchetti > NuGet... > Xamarin.Forms e premere Aggiungi pacchetto.

  6. Espandere il progetto Estensione e modificare un punto di ingresso per inizializzare Xamarin.Forms e creare pagine. Per i requisiti di iOS, un'estensione deve definire il punto di ingresso in Info.plist come NSExtensionMainStoryboard o NSExtensionPrincipalClass. Una volta attivato il punto di ingresso, in questo caso si tratta del ActionViewController.ViewDidLoad metodo , è possibile creare un'istanza di una pagina di Xamarin.Forms e visualizzarla a un utente. Aprire quindi il punto di ingresso e sostituire il ViewDidLoad metodo con l'implementazione seguente:

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

    Viene MainPage creata un'istanza usando un costruttore standard e prima di poterla usare nell'estensione, convertirla in un oggetto nativo UIViewController usando il CreateViewController metodo di estensione.

    Compilare ed eseguire l'applicazione:

    Screenshot shows a Hello from Xamarin dot Forms message on a mobile device.

    Per attivare l'estensione, passare al browser Safari, digitare qualsiasi indirizzo Web, ad esempio microsoft.com, premere spostarsi e quindi premere l'icona Condividi nella parte inferiore della pagina per visualizzare le estensioni dell'azione disponibili. Nell'elenco delle estensioni disponibili selezionare l'estensione MyAction toccandola:

    Screenshot shows a Microsoft Teams Learn more page with the Share icon highlighted on a mobile device.Screenshot shows an Official Home Page with MyAction highlighted on a mobile device.Screenshot shows a Welcome to X F Page created from an i O S extension message on a mobile device.

    L'estensione è attivata e la pagina Xamarin.Forms viene visualizzata all'utente. Tutte le associazioni e i comandi funzionano come nell'app Contenitore.

  7. Il controller di visualizzazione del punto di ingresso originale è visibile perché viene creato e attivato da iOS. Per risolvere questo problema, modificare lo stile della presentazione modale su UIModalPresentationStyle.FullScreen per il nuovo controller aggiungendo il codice seguente subito prima della PresentModalViewController chiamata:

    newController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
    

    Compilare ed eseguire nel simulatore iOS o in un dispositivo:

    Xamarin.Forms in iOS Extension

    Importante

    Per la compilazione del dispositivo assicurarsi di usare le impostazioni di compilazione appropriate e la configurazione della versione, come descritto qui.