Condividi tramite


Pulsanti di azione di notifica dinamica in Xamarin.iOS

In iOS 12 le notifiche possono aggiungere, rimuovere e aggiornare dinamicamente i pulsanti di azione associati. Tale personalizzazione consente di fornire agli utenti azioni direttamente rilevanti per il contenuto della notifica e l'interazione dell'utente con esso.

App di esempio: RedGreenNotifications

I frammenti di codice in questa guida provengono da un'app di esempio, che illustra come usare Xamarin.iOS per usare i pulsanti di azione di notifica in iOS 12.

Questa app di esempio invia due tipi di notifiche locali: rosso e verde. Dopo aver inviato una notifica all'app, usare 3D Touch per visualizzare l'interfaccia utente personalizzata. Usare quindi i pulsanti di azione della notifica per ruotare l'immagine visualizzata. Quando l'immagine ruota, viene visualizzato un pulsante Reimposta rotazione e scompare in base alle esigenze.

I frammenti di codice in questa guida provengono da questa app di esempio.

Pulsanti azione predefiniti

La categoria di una notifica determina i pulsanti di azione predefiniti.

Creare e registrare categorie di notifica durante l'avvio di un'applicazione. Nell'app di esempio, ad esempio, il FinishedLaunching metodo di AppDelegate esegue le operazioni seguenti:

  • Definisce una categoria per le notifiche rosse e un'altra per le notifiche verdi
  • Registra queste categorie chiamando SetNotificationCategories metodo di UNUserNotificationCenter
  • Collega un singolo UNNotificationAction a ogni categoria

Il codice di esempio seguente illustra come funziona:

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
    // Request authorization to send notifications
    UNUserNotificationCenter center = UNUserNotificationCenter.Current;
    var options = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Provisional | UNAuthorizationOptions.ProvidesAppNotificationSettings;
    center.RequestAuthorization(options, (bool success, NSError error) =>
    {
        // ...
        var rotateTwentyDegreesAction = UNNotificationAction.FromIdentifier("rotate-twenty-degrees-action", "Rotate 20°", UNNotificationActionOptions.None);

        var redCategory = UNNotificationCategory.FromIdentifier(
            "red-category",
            new UNNotificationAction[] { rotateTwentyDegreesAction },
            new string[] { },
            UNNotificationCategoryOptions.CustomDismissAction
        );

        var greenCategory = UNNotificationCategory.FromIdentifier(
            "green-category",
            new UNNotificationAction[] { rotateTwentyDegreesAction },
            new string[] { },
            UNNotificationCategoryOptions.CustomDismissAction
        );

        var set = new NSSet<UNNotificationCategory>(redCategory, greenCategory);
        center.SetNotificationCategories(set);
    });
    // ...
}

In base a questo codice, qualsiasi notifica la cui Content.CategoryIdentifier è "red-category" o "green-category", per impostazione predefinita, mostra un pulsante di azione Ruota 20° .

Gestione in-app dei pulsanti di azione di notifica

UNUserNotificationCenter ha una Delegate proprietà di tipo IUNUserNotificationCenterDelegate.

Nell'app di esempio, AppDelegate imposta se stesso come delegato del Centro notifiche utente in FinishedLaunching:

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
    // Request authorization to send notifications
    UNUserNotificationCenter center = UNUserNotificationCenter.Current;
    var options = // ...
    center.RequestAuthorization(options, (bool success, NSError error) =>
    {
        center.Delegate = this;
        // ...

AppDelegate Implementa quindiDidReceiveNotificationResponse per gestire i tap del pulsante azione:

[Export("userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:")]
public void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, System.Action completionHandler)
{
    if (response.IsDefaultAction)
    {
        Console.WriteLine("ACTION: Default");
    }
    if (response.IsDismissAction)
    {
        Console.WriteLine("ACTION: Dismiss");
    }
    else
    {
        Console.WriteLine($"ACTION: {response.ActionIdentifier}");
    }

    completionHandler();
        }

Questa implementazione di DidReceiveNotificationResponse non gestisce il pulsante di azione Ruota 20° della notifica. Al contrario, l'estensione del contenuto della notifica gestisce i tap su questo pulsante. La sezione successiva illustra ulteriormente la gestione dei pulsanti di azione di notifica.

Pulsanti azione nell'estensione del contenuto di notifica

Un'estensione del contenuto di notifica contiene un controller di visualizzazione che definisce l'interfaccia personalizzata per una notifica.

Questo controller di visualizzazione può usare i metodi e SetNotificationActions nel GetNotificationActions relativoExtensionContext per accedere e modificare i pulsanti di azione della notifica.

Nell'app di esempio, il controller di visualizzazione dell'estensione del contenuto di notifica modifica i pulsanti di azione solo quando risponde a un tocco su un pulsante di azione già esistente.

Nota

Un'estensione del contenuto di notifica può rispondere al tocco di un pulsante di azione nel metodo del controller di DidReceiveNotificationResponse visualizzazione, dichiarato come parte di IUNNotificationContentExtension.

Anche se condivide un nome con il DidReceiveNotificationResponse metodo descritto in precedenza, si tratta di un metodo diverso.

Al termine dell'elaborazione di un tocco di un pulsante, un'estensione del contenuto di notifica può scegliere se indicare all'applicazione principale di gestire lo stesso tocco del pulsante. A tale scopo, deve passare un valore appropriato di UNNotificationContentExtensionResponseOption al gestore di completamento:

  • Dismiss indica che l'interfaccia di notifica deve essere chiusa e che l'app principale non deve gestire il tocco del pulsante.
  • DismissAndForwardAction indica che l'interfaccia di notifica deve essere chiusa e che l'app principale deve anche gestire il tocco del pulsante.
  • DoNotDismiss indica che l'interfaccia di notifica non deve essere ignorata e che l'app principale non deve gestire il tocco del pulsante.

Il metodo dell'estensione del DidReceiveNotificationResponse contenuto determina quale pulsante di azione è stato toccato, ruota l'immagine nell'interfaccia della notifica e mostra o nasconde un pulsante di azione Reimposta :

[Export("didReceiveNotificationResponse:completionHandler:")]
public void DidReceiveNotificationResponse(UNNotificationResponse response, Action<UNNotificationContentExtensionResponseOption> completionHandler)
{
    var rotationAction = ExtensionContext.GetNotificationActions()[0];

    if (response.ActionIdentifier == "rotate-twenty-degrees-action")
    {
        rotationButtonTaps += 1;

        double radians = (20 * rotationButtonTaps) * (2 * Math.PI / 360.0);
        Xamagon.Transform = CGAffineTransform.MakeRotation((float)radians);

        // 9 rotations * 20 degrees = 180 degrees. No reason to
        // show the reset rotation button when the image is half
        // or fully rotated.
        if (rotationButtonTaps % 9 == 0)
        {
            ExtensionContext.SetNotificationActions(new UNNotificationAction[] { rotationAction });
        }
        else if (rotationButtonTaps % 9 == 1)
        {
            var resetRotationAction = UNNotificationAction.FromIdentifier("reset-rotation-action", "Reset rotation", UNNotificationActionOptions.None);
            ExtensionContext.SetNotificationActions(new UNNotificationAction[] { rotationAction, resetRotationAction });
        }
    }

    if (response.ActionIdentifier == "reset-rotation-action")
    {
        rotationButtonTaps = 0;

        double radians = (20 * rotationButtonTaps) * (2 * Math.PI / 360.0);
        Xamagon.Transform = CGAffineTransform.MakeRotation((float)radians);

        ExtensionContext.SetNotificationActions(new UNNotificationAction[] { rotationAction });
    }

    completionHandler(UNNotificationContentExtensionResponseOption.DoNotDismiss);
}

In questo caso, il metodo passa UNNotificationContentExtensionResponseOption.DoNotDismiss al gestore di completamento. Ciò significa che l'interfaccia della notifica rimarrà aperta.