Notificações avançadas do usuário no Xamarin.iOS

Novidade no iOS 10, a estrutura de Notificação do Usuário permite a entrega e o manuseio de notificações locais e remotas. Usando essa estrutura, um aplicativo ou extensão de aplicativo pode agendar a entrega de notificações locais especificando um conjunto de condições, como local ou hora do dia.

Sobre notificações do usuário

A nova estrutura de Notificação do Usuário permite a entrega e o tratamento de notificações locais e remotas. Usando essa estrutura, um aplicativo ou Extensão de Aplicativo pode agendar a entrega de notificações locais especificando um conjunto de condições, como local ou hora do dia.

Além disso, o aplicativo ou extensão pode receber (e potencialmente modificar) notificações locais e remotas à medida que são entregues ao dispositivo iOS do usuário.

A nova estrutura da interface do usuário de Notificação do Usuário permite que um aplicativo ou Extensão de Aplicativo personalize a aparência das notificações locais e remotas quando elas são apresentadas ao usuário.

Essa estrutura fornece as seguintes maneiras pelas quais um aplicativo pode entregar notificações a um usuário:

  • Alertas visuais - Onde a notificação rola da parte superior da tela como um banner.
  • Som e Vibrações - Pode ser associado a uma notificação.
  • Badging do ícone do aplicativo - Onde o ícone do aplicativo exibe um selo mostrando que o novo conteúdo está disponível. Como o número de mensagens de email não lidas.

Além disso, dependendo do contexto atual do usuário, há diferentes maneiras de apresentar uma notificação:

  • Se o dispositivo estiver desbloqueado, a notificação rolará para baixo da parte superior da tela como um banner.
  • Se o dispositivo estiver bloqueado, a notificação será exibida na tela de bloqueio do usuário.
  • Se o usuário perdeu uma notificação, ele pode abrir a Central de Notificações e exibir todas as notificações disponíveis em espera.

Um aplicativo Xamarin.iOS tem dois tipos de Notificações do Usuário que ele pode enviar:

  • Notificações locais - São enviadas por aplicativos instalados localmente no dispositivo dos usuários.
  • Notificações remotas - são enviadas de um servidor remoto e apresentadas ao usuário ou acionam uma atualização em segundo plano do conteúdo do aplicativo.

Para obter mais informações, consulte nossa documentação de Notificações de Usuário Avançadas .

A nova interface de notificação do usuário

As Notificações do Usuário no iOS 10 são apresentadas com um novo design de interface do usuário que fornece mais conteúdo, como um Título, Legenda e Anexos de Mídia opcionais que podem ser apresentados na Tela de Bloqueio, como um Banner na parte superior do dispositivo ou na Central de Notificações.

Não importa onde uma Notificação do Usuário é exibida no iOS 10, ela é apresentada com a mesma aparência e com os mesmos recursos e funcionalidades.

No iOS 8, a Apple introduziu Notificações Acionáveis onde o desenvolvedor poderia anexar Ações Personalizadas a uma Notificação e permitir que o usuário realizasse uma ação em uma Notificação sem precisar iniciar o aplicativo. No iOS 9, a Apple aprimorou as Notificações Acionáveis com Resposta Rápida, que permite que o usuário responda a uma Notificação com entrada de texto.

Como as Notificações do Usuário são uma parte mais integral da experiência do usuário no iOS 10, a Apple expandiu ainda mais as Notificações Acionáveis para oferecer suporte ao 3D Touch, em que o usuário pressiona uma notificação e uma interface de usuário personalizada é exibida para fornecer uma interação rica com a notificação.

Quando a interface do usuário personalizada da Notificação do Usuário é exibida, se o usuário interagir com quaisquer Ações anexadas à Notificação, a interface do usuário personalizada poderá ser atualizada instantaneamente para fornecer comentários sobre o que foi alterado.

Novidade no iOS 10, a API da Interface do Usuário de Notificação permite que um aplicativo Xamarin.iOS aproveite facilmente esses novos recursos da Interface do Usuário de Notificação.

Adicionando anexos de mídia

Um dos itens mais comuns que são compartilhados entre os usuários são as fotos, então o iOS 10 adicionou a capacidade de anexar um Item de Mídia (como uma foto) diretamente a uma Notificação, onde ele será apresentado e prontamente disponível para o usuário junto com o restante do conteúdo da Notificação.

No entanto, devido aos tamanhos envolvidos no envio até mesmo de uma imagem pequena, anexá-la a uma carga de notificação remota torna-se impraticável. Para lidar com essa situação, o desenvolvedor pode usar a nova extensão de serviço no iOS 10 para baixar a imagem de outra fonte (como um armazenamento de dados do CloudKit) e anexá-la ao conteúdo da notificação antes de ser exibida ao usuário.

Para que uma Notificação Remota seja modificada por uma Extensão de Serviço, sua carga útil deve ser marcada como mutável. Por exemplo:

{
    aps : {
        alert : "New Photo Available",
        mutable-content: 1
    },
    my-attachment : "https://example.com/photo.jpg"
}

Dê uma olhada na seguinte visão geral do processo:

Processo de adição de anexos de mídia

Uma vez que a Notificação Remota é entregue ao dispositivo (via APNs), a Extensão de Serviço pode baixar a imagem necessária através de qualquer meio desejado (como um NSURLSession) e, depois de receber a imagem, pode modificar o conteúdo da Notificação e exibi-la ao usuário.

Veja a seguir um exemplo de como esse processo pode ser tratado no código:

using System;
using Foundation;
using UIKit;
using UserNotifications;

namespace MonkeyNotification
{
    public class NotificationService : UNNotificationServiceExtension
    {
        #region Constructors
        public NotificationService (IntPtr handle) : base(handle)
        {
        }
        #endregion

        #region Override Methods
        public override void DidReceiveNotificationRequest (UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
        {
            // Get file URL
            var attachementPath = request.Content.UserInfo.ObjectForKey (new NSString ("my-attachment"));
            var url = new NSUrl (attachementPath.ToString ());

            // Download the file
            var localURL = new NSUrl ("PathToLocalCopy");

            // Create attachment
            var attachmentID = "image";
            var options = new UNNotificationAttachmentOptions ();
            NSError err;
            var attachment = UNNotificationAttachment.FromIdentifier (attachmentID, localURL, options , out err);

            // Modify contents
            var content = request.Content.MutableCopy() as UNMutableNotificationContent;
            content.Attachments = new UNNotificationAttachment [] { attachment };

            // Display notification
            contentHandler (content);
        }

        public override void TimeWillExpire ()
        {
            // Handle service timing out
        }
        #endregion
    }
}

Quando a notificação é recebida de APNs, o endereço personalizado da imagem é lido do conteúdo e o arquivo é baixado do servidor. Em seguida, um UNNotificationAttachement é criado com um ID exclusivo e o local da imagem (como um NSUrlarquivo ). Uma cópia mutável do Conteúdo de Notificação é criada e Anexos de Mídia são adicionados. Finalmente, a notificação é exibida ao usuário chamando o contentHandler.

Uma vez que um anexo foi adicionado a uma notificação, o sistema assume a movimentação e o gerenciamento do arquivo.

Além das Notificações Remotas apresentadas acima, os Anexos de Mídia também são suportados a partir de Notificações Locais, onde o é criado e anexado UNNotificationAttachement à Notificação junto com seu Conteúdo.

A notificação no iOS 10 suporta anexos de mídia de imagens (estáticas e GIFs), áudio ou vídeo e o sistema exibirá automaticamente a interface do usuário personalizada correta para cada um desses tipos de anexos quando a notificação for apresentada ao usuário.

Observação

Deve-se tomar cuidado para otimizar o tamanho da mídia e o tempo necessário para baixar a mídia do servidor remoto (ou para montar a mídia para Notificações Locais), pois o sistema impõe limites estritos a ambos ao executar a Extensão de Serviço do aplicativo. Por exemplo, considere enviar uma versão reduzida da imagem ou um pequeno clipe de um vídeo a ser apresentado na Notificação.

Criando interfaces de usuário personalizadas

Para criar uma Interface do Usuário personalizada para suas Notificações do Usuário, o desenvolvedor precisa adicionar uma Extensão de Conteúdo de Notificação (nova no iOS 10) à solução do aplicativo.

A Extensão de Conteúdo de Notificação permite que o desenvolvedor adicione suas próprias exibições à interface do usuário de Notificação e desenhe qualquer conteúdo desejado. A partir do iOS 12, as Extensões de Conteúdo de Notificação oferecem suporte a controles interativos da interface do usuário, como botões e controles deslizantes. Para obter mais informações, consulte as notificações interativas na documentação do iOS 12 .

Para suportar a interação do usuário com uma Notificação do Usuário, as Ações Personalizadas devem ser criadas, registradas no sistema e anexadas à Notificação antes que ela seja agendada com o sistema. A Extensão de Conteúdo de Notificação será chamada para lidar com o processamento dessas ações. Consulte a seção Trabalhando com Ações de Notificação do documento Notificações Avançadas do Usuário para obter mais detalhes sobre Ações Personalizadas.

Quando uma notificação de usuário com uma interface do usuário personalizada é apresentada ao usuário, ela terá os seguintes elementos:

Uma notificação do usuário com elementos de interface do usuário personalizados

Se o usuário interagir com as Ações Personalizadas (apresentadas abaixo da Notificação), a Interface do Usuário poderá ser atualizada para fornecer comentários ao usuário sobre o que aconteceu quando ele invocou uma determinada ação.

Adicionando uma extensão de conteúdo de notificação

Para implementar uma interface do usuário de notificação de usuário personalizada em um aplicativo Xamarin.iOS, faça o seguinte:

  1. Abra a solução do aplicativo no Visual Studio para Mac.

  2. Clique com o botão direito do mouse no Nome da Solução no Painel de Soluções e selecione Adicionar>Novo Projeto.

  3. Selecione Extensões>do iOS>Extensões de Conteúdo de Notificação e clique no botão Avançar:

    Selecionar extensões de conteúdo de notificação

  4. Digite um Nome para a extensão e clique no botão Avançar :

    Insira um Nome para a extensão

  5. Ajuste o Nome do Projeto e/ou Nome da Solução, se necessário, e clique no botão Criar:

    Ajustar o nome do projeto e/ou o nome da solução

Quando a extensão de conteúdo de notificação é adicionada à solução, três arquivos serão criados no projeto da extensão:

  1. NotificationViewController.cs - Este é o controlador de exibição principal para a extensão de conteúdo de notificação.
  2. MainInterface.storyboard - Onde o desenvolvedor estabelece a interface do usuário visível para a Extensão de Conteúdo de Notificação no iOS Designer.
  3. Info.plist - Controla a configuração da Extensão de Conteúdo de Notificação.

O arquivo padrão NotificationViewController.cs tem a seguinte aparência:

using System;
using Foundation;
using UIKit;
using UserNotifications;
using UserNotificationsUI;

namespace MonkeyChatNotifyExtension
{
    public partial class NotificationViewController : UIViewController, IUNNotificationContentExtension
    {
        #region Constructors
        protected NotificationViewController (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do any required interface initialization here.
        }
        #endregion

        #region Public Methods
        [Export ("didReceiveNotification:")]
        public void DidReceiveNotification (UNNotification notification)
        {
            label.Text = notification.Request.Content.Body;

            // Grab content
            var content = notification.Request.Content;

        }
        #endregion
    }
}

O DidReceiveNotification método é chamado quando a notificação é expandida pelo usuário para que a extensão de conteúdo de notificação possa preencher a interface do usuário personalizada com o conteúdo do UNNotification. Para o exemplo acima, um Rótulo foi adicionado ao modo de exibição, exposto ao código com o nome label e é usado para exibir o corpo da Notificação.

Definindo as categorias da Extensão de Conteúdo de Notificação

O sistema precisa ser informado sobre como encontrar a Extensão de Conteúdo de Notificação do aplicativo com base nas categorias específicas às quais ele responde. Faça o seguinte:

  1. Clique duas vezes no arquivo da Info.plist extensão no Solution Pad para abri-lo para edição.

  2. Alterne para o modo de exibição de Código-fonte.

  3. Expanda a NSExtension chave.

  4. Adicione a UNNotificationExtensionCategory chave como tipo String com o valor da categoria à qual a Extensão pertence (neste exemplo 'event-invite):

    Adicionar a chave UNNotificationExtensionCategory

  5. Salve suas alterações.

As Categorias de Extensão de Conteúdo de Notificação (UNNotificationExtensionCategory) usam os mesmos valores de categoria usados para registrar Ações de Notificação. Na situação em que o aplicativo usará a mesma interface do usuário para várias categorias, alterne para UNNotificationExtensionCategory o tipo Matriz e forneça todas as categorias necessárias. Por exemplo:

Ocultando o conteúdo de notificação padrão

Na situação em que a interface do usuário de notificação personalizada exibirá o mesmo conteúdo que a notificação padrão (título, legenda e corpo exibidos automaticamente na parte inferior da interface do usuário de notificação), essas informações padrão podem ser ocultadas adicionando a UNNotificationExtensionDefaultContentHidden chave à NSExtensionAttributes chave como tipo booleano com um valor de no arquivo da YESInfo.plist extensão:

Projetando a interface do usuário personalizada

Para criar a interface de usuário personalizada da Extensão de Conteúdo de Notificação, clique duas vezes no MainInterface.storyboard arquivo para abri-lo para edição no Designer do iOS, arraste os elementos necessários para criar a interface desejada (como UILabels e UIImageViews).

Observação

A partir do iOS 12, uma Extensão de Conteúdo de Notificação pode incluir controles interativos, como botões e campos de texto. Para obter mais informações, consulte as notificações interativas na documentação do iOS 12 .

Depois que a interface do usuário tiver sido definida e os controles necessários expostos ao código C#, abra o NotificationViewController.cs para edição e modifique o DidReceiveNotification método para preencher a interface do usuário quando o usuário expandir a notificação. Por exemplo:

using System;
using Foundation;
using UIKit;
using UserNotifications;
using UserNotificationsUI;

namespace MonkeyChatNotifyExtension
{
    public partial class NotificationViewController : UIViewController, IUNNotificationContentExtension
    {
        #region Constructors
        protected NotificationViewController (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do any required interface initialization here.
        }
        #endregion

        #region Public Methods
        [Export ("didReceiveNotification:")]
        public void DidReceiveNotification (UNNotification notification)
        {
            label.Text = notification.Request.Content.Body;

            // Grab content
            var content = notification.Request.Content;

            // Display content in the UILabels
            EventTitle.Text = content.Title;
            EventDate.Text = content.Subtitle;
            EventMessage.Text = content.Body;

            // Get location and display
            var location = content.UserInfo ["location"].ToString ();
            if (location != null) {
                Event.Location.Text = location;
            }

        }
        #endregion
    }
}

Definindo o tamanho da área de conteúdo

Para ajustar o tamanho da área de conteúdo exibida para o usuário, o código abaixo está definindo a PreferredContentSizeViewDidLoad propriedade no método para o tamanho desejado. Esse tamanho também pode ser ajustado aplicando restrições à exibição no iOS Designer, resta ao desenvolvedor escolher o método que funciona melhor para eles.

Como o sistema de notificação já está em execução antes que a extensão de conteúdo de notificação seja invocada, a área de conteúdo começará em tamanho real e será animada até o tamanho solicitado quando apresentada ao usuário.

Para eliminar esse efeito, edite o Info.plist arquivo para a extensão e defina a UNNotificationExtensionInitialContentSizeRatioNSExtensionAttributes chave da chave para digitar Number com um valor que representa a proporção desejada. Por exemplo:

Usando anexos de mídia na interface do usuário personalizada

Como os Anexos de Mídia (como visto na seção Adicionando Anexos de Mídia acima) fazem parte da Carga de Notificação, eles podem ser acessados e exibidos na Extensão de Conteúdo de Notificação da mesma forma que seriam na Interface do Usuário de Notificação padrão.

Por exemplo, se a interface do usuário personalizada acima incluísse um UIImageView que foi exposto ao código C#, o código a seguir poderia ser usado para preenchê-lo com o anexo de mídia:

using System;
using Foundation;
using UIKit;
using UserNotifications;
using UserNotificationsUI;

namespace MonkeyChatNotifyExtension
{
    public partial class NotificationViewController : UIViewController, IUNNotificationContentExtension
    {
        #region Constructors
        protected NotificationViewController (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do any required interface initialization here.
        }
        #endregion

        #region Public Methods
        [Export ("didReceiveNotification:")]
        public void DidReceiveNotification (UNNotification notification)
        {
            label.Text = notification.Request.Content.Body;

            // Grab content
            var content = notification.Request.Content;

            // Display content in the UILabels
            EventTitle.Text = content.Title;
            EventDate.Text = content.Subtitle;
            EventMessage.Text = content.Body;

            // Get location and display
            var location = content.UserInfo ["location"].ToString ();
            if (location != null) {
                Event.Location.Text = location;
            }

            // Get Media Attachment
            if (content.Attachements.Length > 1) {
                var attachment = content.Attachments [0];
                if (attachment.Url.StartAccessingSecurityScopedResource ()) {
                    EventImage.Image = UIImage.FromFile (attachment.Url.Path);
                    attachment.Url.StopAccessingSecurityScopedResource ();
                }
            }
        }
        #endregion
    }
}

Como o Anexo de Mídia é gerenciado pelo sistema, ele está fora da área restrita do aplicativo. A extensão precisa informar ao sistema que deseja acessar o arquivo chamando o StartAccessingSecurityScopedResource método. Quando a extensão é feita com o arquivo, ele precisa chamar o StopAccessingSecurityScopedResource para liberar sua conexão.

Adicionando ações personalizadas a uma interface do usuário personalizada

Os botões de ação personalizados podem ser usados para adicionar interatividade a uma interface do usuário de notificação personalizada. Consulte a seção Trabalhando com ações de notificação do documento Notificações avançadas do usuário para obter mais detalhes sobre ações personalizadas.

Além das ações personalizadas, a Extensão de Conteúdo de Notificação também pode responder às seguintes ações internas:

  • Ação padrão - É quando o usuário toca em uma notificação para abrir o aplicativo e exibir os detalhes da notificação fornecida.
  • Ação de descartar - Essa ação é enviada ao aplicativo quando o usuário descarta uma determinada notificação.

As Extensões de Conteúdo de Notificação também têm a capacidade de atualizar sua interface do usuário quando o usuário invoca uma das Ações Personalizadas, como mostrar uma data como aceita quando o usuário toca no botão Aceitar Ação Personalizada. Além disso, as extensões de conteúdo de notificação podem dizer ao sistema para atrasar a desmissão da interface do usuário de notificação para que o usuário possa ver o efeito de sua ação antes que a notificação seja fechada.

Isso é feito implementando uma segunda versão do método que inclui um manipulador de DidReceiveNotification conclusão. Por exemplo:

using System;
using Foundation;
using UIKit;
using UserNotifications;
using UserNotificationsUI;
using CoreGraphics;

namespace myApp {
    public class NotificationViewController : UIViewController, UNNotificationContentExtension {

        public override void ViewDidLoad() {
            base.ViewDidLoad();

            // Adjust the size of the content area
            var size = View.Bounds.Size
            PreferredContentSize = new CGSize(size.Width, size.Width/2);
        }

        public void DidReceiveNotification(UNNotification notification) {

            // Grab content
            var content = notification.Request.Content;

            // Display content in the UILabels
            EventTitle.Text = content.Title;
            EventDate.Text = content.Subtitle;
            EventMessage.Text = content.Body;

            // Get location and display
            var location = Content.UserInfo["location"] as string;
            if (location != null) {
                Event.Location.Text = location;
            }

            // Get Media Attachment
            if (content.Attachements.Length > 1) {
                var attachment = content.Attachments[0];
                if (attachment.Url.StartAccessingSecurityScopedResource()) {
                    EventImage.Image = UIImage.FromFile(attachment.Url.Path);
                    attachment.Url.StopAccessingSecurityScopedResource();
                }
            }
        }

        [Export ("didReceiveNotificationResponse:completionHandler:")]
        public void DidReceiveNotification (UNNotificationResponse response, Action<UNNotificationContentExtensionResponseOption> completionHandler)
        {

            // Update UI when the user interacts with the
            // Notification
            Server.PostEventResponse += (response) {
                // Take action based on the response
                switch(response.ActionIdentifier){
                case "accept":
                    EventResponse.Text = "Going!";
                    EventResponse.TextColor = UIColor.Green;
                    break;
                case "decline":
                    EventResponse.Text = "Not Going.";
                    EventResponse.TextColor = UIColor.Red;
                    break;
                }

                // Close Notification
                completionHandler (UNNotificationContentExtensionResponseOption.Dismiss);
            };
        }
    }
}

Ao adicionar o Server.PostEventResponse manipulador ao DidReceiveNotification método da Extensão de Conteúdo de Notificação, a Extensão deve manipular todas as ações personalizadas. A extensão também pode encaminhar as ações personalizadas para o aplicativo que contém alterando o UNNotificationContentExtensionResponseOption. Por exemplo:

// Close Notification
completionHandler (UNNotificationContentExtensionResponseOption.DismissAndForwardAction);

Trabalhando com a ação de entrada de texto na interface do usuário personalizada

Dependendo do design do aplicativo e da Notificação, pode haver momentos que exijam que o usuário insira texto na Notificação (como responder a uma mensagem). Uma Extensão de Conteúdo de Notificação tem acesso à ação de entrada de texto interna, assim como uma notificação padrão.

Por exemplo:

using System;
using Foundation;
using UIKit;
using UserNotifications;
using UserNotificationsUI;

namespace MonkeyChatNotifyExtension
{
    public partial class NotificationViewController : UIViewController, IUNNotificationContentExtension
    {
        #region Computed Properties
        // Allow to take input
        public override bool CanBecomeFirstResponder {
            get { return true; }
        }

        // Return the custom created text input view with the
        // required buttons and return here
        public override UIView InputAccessoryView {
            get { return InputView; }
        }
        #endregion

        #region Constructors
        protected NotificationViewController (IntPtr handle) : base (handle)
        {
            // Note: this .ctor should not contain any initialization logic.
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do any required interface initialization here.
        }
        #endregion

        #region Private Methods
        private UNNotificationCategory MakeExtensionCategory ()
        {

            // Create Accept Action
            ...

            // Create decline Action
            ...

            // Create Text Input Action
            var commentID = "comment";
            var commentTitle = "Comment";
            var textInputButtonTitle = "Send";
            var textInputPlaceholder = "Enter comment here...";
            var commentAction = UNTextInputNotificationAction.FromIdentifier (commentID, commentTitle, UNNotificationActionOptions.None, textInputButtonTitle, textInputPlaceholder);

            // Create category
            var categoryID = "event-invite";
            var actions = new UNNotificationAction [] { acceptAction, declineAction, commentAction };
            var intentIDs = new string [] { };
            var category = UNNotificationCategory.FromIdentifier (categoryID, actions, intentIDs, UNNotificationCategoryOptions.None);

            // Return new category
            return category;

        }
        #endregion

        #region Public Methods
        [Export ("didReceiveNotification:")]
        public void DidReceiveNotification (UNNotification notification)
        {
            label.Text = notification.Request.Content.Body;

            // Grab content
            var content = notification.Request.Content;

            // Display content in the UILabels
            EventTitle.Text = content.Title;
            EventDate.Text = content.Subtitle;
            EventMessage.Text = content.Body;

            // Get location and display
            var location = content.UserInfo ["location"].ToString ();
            if (location != null) {
                Event.Location.Text = location;
            }

            // Get Media Attachment
            if (content.Attachements.Length > 1) {
                var attachment = content.Attachments [0];
                if (attachment.Url.StartAccessingSecurityScopedResource ()) {
                    EventImage.Image = UIImage.FromFile (attachment.Url.Path);
                    attachment.Url.StopAccessingSecurityScopedResource ();
                }
            }
        }

        [Export ("didReceiveNotificationResponse:completionHandler:")]
        public void DidReceiveNotification (UNNotificationResponse response, Action<UNNotificationContentExtensionResponseOption> completionHandler)
        {

            // Is text input?
            if (response is UNTextInputNotificationResponse) {
                var textResponse = response as UNTextInputNotificationResponse;
                Server.Send (textResponse.UserText, () => {
                    // Close Notification
                    completionHandler (UNNotificationContentExtensionResponseOption.Dismiss);
                });
            }

            // Update UI when the user interacts with the
            // Notification
            Server.PostEventResponse += (response) {
                // Take action based on the response
                switch (response.ActionIdentifier) {
                case "accept":
                    EventResponse.Text = "Going!";
                    EventResponse.TextColor = UIColor.Green;
                    break;
                case "decline":
                    EventResponse.Text = "Not Going.";
                    EventResponse.TextColor = UIColor.Red;
                    break;
                }

                // Close Notification
                completionHandler (UNNotificationContentExtensionResponseOption.Dismiss);
            };
        }
        #endregion
    }
}

Esse código cria uma nova ação de entrada de texto e a adiciona à categoria da extensão (no MakeExtensionCategorymétodo ). DidReceive No método de substituição, ele manipula o usuário inserindo texto com o seguinte código:

// Is text input?
if (response is UNTextInputNotificationResponse) {
    var textResponse = response as UNTextInputNotificationResponse;
    Server.Send (textResponse.UserText, () => {
        // Close Notification
        completionHandler (UNNotificationContentExtensionResponseOption.Dismiss);
    });
}

Se o design exigir a adição de botões personalizados ao campo de entrada de texto, adicione o seguinte código para incluí-los:

// Allow to take input
public override bool CanBecomeFirstResponder {
    get {return true;}
}

// Return the custom created text input view with the
// required buttons and return here
public override UIView InputAccessoryView {
    get {return InputView;}
}

Quando a ação de comentário é acionada pelo usuário, o controlador de exibição e o campo de entrada de texto personalizado precisam ser ativados:

// Update UI when the user interacts with the
// Notification
Server.PostEventResponse += (response) {
    // Take action based on the response
    switch(response.ActionIdentifier){
    ...
    case "comment":
        BecomeFirstResponder();
        TextField.BecomeFirstResponder();
        break;
    }

    // Close Notification
    completionHandler (UNNotificationContentExtensionResponseOption.Dismiss);

};

Resumo

Este artigo analisou de forma avançada o uso da nova estrutura de Notificação do Usuário em um aplicativo Xamarin.iOS. Ele abordou a adição de Anexos de Mídia à Notificação Local e Remota e abordou o uso da nova interface do usuário de Notificação do Usuário para criar interfaces de usuário de notificação personalizadas.