다음을 통해 공유


Xamarin.iOS의 고급 사용자 알림

iOS 10의 새로운 기능인 사용자 알림 프레임워크를 사용하면 로컬 및 원격 알림을 배달하고 처리할 수 있습니다. 이 프레임워크를 사용하여 앱 또는 앱 확장 프로그램은 위치 또는 시간 등의 조건 집합을 지정하여 로컬 알림 배달을 예약할 수 있습니다.

사용자 알림 정보

새 사용자 알림 프레임워크를 사용하면 로컬 및 원격 알림의 배달 및 처리를 허용합니다. 이 프레임워크를 사용하여 앱 또는 앱 확장은 위치 또는 시간 등의 조건 집합을 지정하여 로컬 알림 배달을 예약할 수 있습니다.

또한 앱 또는 확장은 사용자의 iOS 디바이스에 배달될 때 로컬 및 원격 알림을 모두 수신하고 수정할 수 있습니다.

새 사용자 알림 UI 프레임워크를 사용하면 앱 또는 앱 확장이 사용자에게 표시될 때 로컬 및 원격 알림의 모양을 사용자 지정할 수 있습니다.

이 프레임워크는 앱이 사용자에게 알림을 제공할 수 있는 다음과 같은 방법을 제공합니다.

  • 시각적 경고 - 알림이 화면 위쪽에서 배너로 롤다운되는 위치입니다.
  • 소리 및 진동 - 알림과 연결할 수 있습니다.
  • 앱 아이콘 바딩 - 앱 아이콘에 새 콘텐츠를 사용할 수 있음을 보여 주는 배지가 표시됩니다. 읽지 않은 전자 메일 메시지 수와 같습니다.

또한 사용자의 현재 컨텍스트에 따라 알림이 표시되는 다양한 방법이 있습니다.

  • 디바이스의 잠금이 해제된 경우 알림은 화면 위쪽에서 배너로 롤다운됩니다.
  • 디바이스가 잠겨 있으면 알림이 사용자의 잠금 화면에 표시됩니다.
  • 사용자가 알림을 놓친 경우 알림 센터를 열고 사용 가능한 대기 알림을 볼 수 있습니다.

Xamarin.iOS 앱에는 보낼 수 있는 두 가지 유형의 사용자 알림이 있습니다.

  • 로컬 알림 - 이러한 알림은 사용자 디바이스에 로컬로 설치된 앱에서 전송됩니다.
  • 원격 알림 - 원격 서버에서 전송되고 사용자에게 표시되거나 앱 콘텐츠의 백그라운드 업데이트를 트리거합니다.

자세한 내용은 향상된 사용자 알림 설명서를 참조하세요.

새 사용자 알림 인터페이스

iOS 10의 사용자 알림에는 잠금 화면, 디바이스 위쪽 또는 알림 센터에서 배너로 표시할 수 있는 제목, 부제목 및 선택적 미디어 첨부 파일과 같은 더 많은 콘텐츠를 제공하는 새로운 UI 디자인이 제공됩니다.

iOS 10에서 사용자 알림이 표시되는 위치에 관계없이 동일한 모양과 느낌 및 동일한 기능과 함께 표시됩니다.

iOS 8에서 Apple은 개발자가 알림에 사용자 지정 작업을 연결하고 사용자가 앱을 시작하지 않고도 알림에 대한 작업을 수행할 수 있는 실행 가능한 알림을 도입했습니다. iOS 9에서 Apple은 사용자가 텍스트 항목으로 알림에 응답할 수 있도록 빠른 회신을 사용하여 실행 가능한 알림을 향상시켰습니다.

사용자 알림은 iOS 10에서 사용자 환경의 더 중요한 부분이기 때문에 Apple은 사용자가 알림을 누르고 사용자 지정 사용자 인터페이스가 표시되어 알림과 풍부한 상호 작용을 제공하는 3D Touch를 지원하기 위해 실행 가능한 알림을 추가로 확장했습니다.

사용자 지정 사용자 알림 UI가 표시되면 사용자가 알림에 연결된 작업과 상호 작용하는 경우 사용자 지정 UI를 즉시 업데이트하여 변경된 내용에 대한 피드백을 제공할 수 있습니다.

iOS 10을 새로 추가한 사용자 알림 UI API를 사용하면 Xamarin.iOS 앱이 이러한 새로운 사용자 알림 UI 기능을 쉽게 활용할 수 있습니다.

미디어 첨부 파일 추가

사용자 간에 공유되는 더 일반적인 항목 중 하나는 사진이므로 iOS 10은 알림에 미디어 항목(예: 사진)을 직접 첨부할 수 있는 기능을 추가했습니다. 그러면 알림의 나머지 콘텐츠와 함께 사용자에게 표시되고 쉽게 사용할 수 있습니다.

그러나 작은 이미지도 보내는 데 관련된 크기 때문에 원격 알림 페이로드에 연결하는 것은 실용적이지 않습니다. 이 상황을 처리하기 위해 개발자는 iOS 10의 새 서비스 확장을 사용하여 다른 원본(예: CloudKit 데이터 저장소)에서 이미지를 다운로드하고 사용자에게 표시되기 전에 알림의 콘텐츠에 연결할 수 있습니다.

서비스 확장 프로그램에서 원격 알림을 수정하려면 해당 페이로드를 변경 가능한 것으로 표시해야 합니다. 예시:

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

프로세스의 다음 개요를 살펴보세요.

미디어 첨부 파일 프로세스 추가

APN을 통해 디바이스에 원격 알림이 전달되면 서비스 확장은 원하는 모든 수단(예: NSURLSession)을 통해 필요한 이미지를 다운로드할 수 있으며, 이미지를 수신한 후 알림 내용을 수정하고 사용자에게 표시할 수 있습니다.

다음은 코드에서 이 프로세스를 처리하는 방법의 예입니다.

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

APN에서 알림을 받으면 이미지의 사용자 지정 주소가 콘텐츠에서 읽혀지고 파일이 서버에서 다운로드됩니다. UNNotificationAttachement 그런 다음, 고유한 ID와 이미지의 로컬 위치(a)NSUrl로 만들어집니다. 알림 콘텐츠의 변경 가능한 복사본이 만들어지고 미디어 첨부 파일이 추가됩니다. 마지막으로 알림을 호출 contentHandler하여 사용자에게 표시됩니다.

첨부 파일이 알림에 추가되면 시스템에서 파일의 이동 및 관리를 인수합니다.

위에 제공된 원격 알림 외에도 미디어 첨부 파일은 콘텐츠와 함께 생성되고 알림에 첨부되는 로컬 알림 UNNotificationAttachement 에서도 지원됩니다.

iOS 10의 알림은 이미지의 미디어 첨부 파일(정적 및 GIF), 오디오 또는 비디오 및 시스템에서 알림이 사용자에게 표시될 때 이러한 각 유형의 첨부 파일에 대해 올바른 사용자 지정 UI를 자동으로 표시하도록 지원합니다.

참고 항목

시스템이 앱의 서비스 확장을 실행할 때 둘 다에 엄격한 제한을 적용하기 때문에 미디어 크기와 원격 서버에서 미디어를 다운로드하는 데 걸리는 시간(또는 로컬 알림용 미디어를 어셈블)을 모두 최적화하는 데 주의해야 합니다. 예를 들어 이미지의 축소된 버전 또는 알림에 표시할 비디오의 작은 클립을 보내는 것이 좋습니다.

사용자 지정 사용자 인터페이스 만들기

사용자 알림에 대한 사용자 지정 사용자 인터페이스를 만들려면 개발자가 앱 솔루션에 알림 콘텐츠 확장(iOS 10을 새로 추가)을 추가해야 합니다.

알림 콘텐츠 확장을 사용하면 개발자가 알림 UI에 자신의 보기를 추가하고 원하는 콘텐츠를 그릴 수 있습니다. iOS 12부터 알림 콘텐츠 확장은 단추 및 슬라이더와 같은 대화형 UI 컨트롤을 지원합니다. 자세한 내용은 iOS 12 설명서의 대화형 알림을 참조하세요.

사용자 알림과의 사용자 상호 작용을 지원하려면 사용자 지정 작업을 만들고, 시스템에 등록하고, 시스템에 예약하기 전에 알림에 연결해야 합니다. 알림 콘텐츠 확장 프로그램은 이러한 작업의 처리를 처리하기 위해 호출됩니다. 사용자 지정 작업에 대한 자세한 내용은 향상된 사용자 알림 문서의 알림 작업 섹션을 참조하세요.

사용자 지정 UI가 있는 사용자 알림이 사용자에게 표시되면 다음과 같은 요소가 있습니다.

사용자 지정 UI 요소가 있는 사용자 알림

사용자가 사용자 지정 작업(알림 아래에 표시됨)과 상호 작용하는 경우 사용자 인터페이스를 업데이트하여 지정된 작업을 호출할 때 발생한 작업으로 사용자 피드백을 제공할 수 있습니다.

알림 콘텐츠 확장 추가

Xamarin.iOS 앱에서 사용자 지정 사용자 알림 UI를 구현하려면 다음을 수행합니다.

  1. Mac용 Visual Studio 앱의 솔루션을 엽니다.

  2. 솔루션 패드에서 솔루션 이름을 마우스 오른쪽 단추로 클릭하고 새 프로젝트 추가>를 선택합니다.

  3. iOS>확장 알림>콘텐츠 확장을 선택하고 다음 단추를 클릭합니다.

    알림 콘텐츠 확장 선택

  4. 확장의 이름을 입력하고 다음 단추를 클릭합니다.

    확장의 이름을 입력합니다.

  5. 필요한 경우 프로젝트 이름 및/또는 솔루션 이름을 조정하고 만들기 단추를 클릭합니다.

    프로젝트 이름 및/또는 솔루션 이름 조정

알림 콘텐츠 확장이 솔루션에 추가되면 확장 프로젝트에 세 개의 파일이 만들어집니다.

  1. NotificationViewController.cs- 알림 콘텐츠 확장에 대한 기본 보기 컨트롤러입니다.
  2. MainInterface.storyboard - 개발자가 iOS 디자이너에서 알림 콘텐츠 확장에 대해 표시되는 UI를 배치하는 위치입니다.
  3. Info.plist - 알림 콘텐츠 확장의 구성을 제어합니다.

기본 NotificationViewController.cs 파일은 다음과 같습니다.

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

알림 DidReceiveNotification 콘텐츠 확장에서 사용자 지정 UI를 콘텐츠로 채울 수 있도록 사용자가 알림을 확장할 때 메서드가 호출됩니다 UNNotification. 위의 예제에서는 레이블이 뷰에 추가되어 이름이 label 있는 코드에 노출되며 알림 본문을 표시하는 데 사용됩니다.

알림 콘텐츠 확장의 범주 설정

응답하는 특정 범주에 따라 앱의 알림 콘텐츠 확장을 찾는 방법을 시스템에 알려야 합니다. 다음을 수행하십시오:

  1. Solution Pad에서 확장 프로그램 Info.plist 파일을 두 번 클릭하여 편집용으로 엽니다.

  2. 원본 보기로 전환합니다.

  3. 키를 확장합니다 NSExtension .

  4. 확장이 UNNotificationExtensionCategory 속한 범주의 값을 사용하여 문자열 형식으로 키를 추가합니다(이 예제에서는 'event-invite).

    UNNotificationExtensionCategory 키 추가

  5. 변경 내용을 저장합니다.

알림 콘텐츠 확장 범주(UNNotificationExtensionCategory)는 알림 작업을 등록하는 데 사용되는 것과 동일한 범주 값을 사용합니다. 앱이 여러 범주에 동일한 UI를 사용하는 경우 배열 형식으로 전환 UNNotificationExtensionCategory 하고 필요한 모든 범주를 제공합니다. 예시:

기본 알림 콘텐츠 숨기기

사용자 지정 알림 UI가 기본 알림과 동일한 콘텐츠를 표시하는 경우(제목, 부제목 및 본문이 알림 UI 아래쪽에 자동으로 표시됨) 확장 Info.plist 파일의 값 YES 이 있는 부울 형식으로 키에 키를 NSExtensionAttributes 추가하여 UNNotificationExtensionDefaultContentHidden 이 기본 정보를 숨길 수 있습니다.

사용자 지정 UI 디자인

알림 콘텐츠 확장의 사용자 지정 사용자 인터페이스를 디자인하려면 파일을 두 번 클릭하여 MainInterface.storyboard iOS 디자이너에서 편집할 수 있도록 열고 원하는 인터페이스(예: UILabelsUIImageViews)를 빌드해야 하는 요소를 끌어옵니다.

참고 항목

iOS 12를 기준으로 알림 콘텐츠 확장에는 단추 및 텍스트 필드와 같은 대화형 컨트롤이 포함될 수 있습니다. 자세한 내용은 iOS 12 설명서의 대화형 알림을 참조하세요.

UI가 배치되고 필요한 컨트롤이 C# 코드에 노출되면 편집용 컨트롤을 열고 NotificationViewController.cs 사용자가 알림을 확장할 때 UI를 채우도록 메서드를 수정 DidReceiveNotification 합니다. 예시:

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

콘텐츠 영역 크기 설정

사용자에게 표시되는 콘텐츠 영역의 크기를 조정하기 위해 아래 코드는 메서드의 PreferredContentSize ViewDidLoad 속성을 원하는 크기로 설정하는 것입니다. 이 크기는 iOS 디자이너의 보기에 제약 조건을 적용하여 조정할 수도 있습니다. 개발자가 가장 적합한 방법을 선택해야 합니다.

알림 콘텐츠 확장이 호출되기 전에 알림 시스템이 이미 실행 중이므로 콘텐츠 영역이 전체 크기로 시작되고 사용자에게 표시될 때 요청된 크기로 애니메이션이 적용됩니다.

이 효과를 제거하려면 확장에 Info.plist 대한 파일을 편집하고 원하는 비율을 나타내는 값을 사용하여 키의 NSExtensionAttributes 키를 Number 형식으로 설정합니다UNNotificationExtensionInitialContentSizeRatio. 예시:

사용자 지정 UI에서 미디어 첨부 파일 사용

위의 미디어 첨부 파일 추가 섹션에서 볼 수 있듯이 미디어 첨부 파일 은 알림 페이로드의 일부이므로 기본 알림 UI와 마찬가지로 알림 콘텐츠 확장에 액세스하여 표시할 수 있습니다.

예를 들어 위의 사용자 지정 UI에 C# 코드에 노출된 UI가 포함된 UIImageView 경우 다음 코드를 사용하여 미디어 첨부 파일로 채울 수 있습니다.

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

미디어 첨부 파일은 시스템에서 관리되므로 앱의 샌드박스 외부에 있습니다. 확장 프로그램은 메서드를 호출 StartAccessingSecurityScopedResource 하여 파일에 대한 액세스를 원한다는 것을 시스템에 알려야 합니다. 파일로 확장이 완료되면 연결을 해제하기 위해 호출 StopAccessingSecurityScopedResource 해야 합니다.

사용자 지정 UI에 사용자 지정 작업 추가

사용자 지정 작업 단추를 사용하여 사용자 지정 알림 UI에 대화형 작업을 추가할 수 있습니다. 사용자 지정 작업에 대한 자세한 내용은 향상된 사용자 알림 문서의 알림 작업 섹션을 참조하세요.

알림 콘텐츠 확장은 사용자 지정 작업 외에도 다음과 같은 기본 제공 작업에 응답할 수 있습니다.

  • 기본 작업 - 사용자가 알림을 탭하여 앱을 열고 지정된 알림의 세부 정보를 표시하는 경우입니다.
  • 작업 해제 - 사용자가 지정된 알림을 해제하면 이 작업이 앱으로 전송됩니다.

알림 콘텐츠 확장은 사용자가 사용자 지정 작업 수락 단추를 탭할 때 수락된 날짜를 표시하는 등 사용자 지정 작업 중 하나를 호출할 때 해당 UI를 업데이트하는 기능도 있습니다. 또한 알림 콘텐츠 확장은 알림이 닫히기 전에 사용자가 해당 작업의 효과를 볼 수 있도록 알림 UI의 해제를 지연하도록 시스템에 알릴 수 있습니다.

이 작업은 완료 처리기를 포함하는 메서드의 DidReceiveNotification 두 번째 버전을 구현하여 수행됩니다. 예시:

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

알림 콘텐츠 확장의 메서드에 DidReceiveNotification 처리기를 추가 Server.PostEventResponse 하면 확장에서 모든 사용자 지정 작업을 처리해야 합니다. 또한 확장을 변경 UNNotificationContentExtensionResponseOption하여 포함 앱에 사용자 지정 작업을 전달할 수 있습니다. 예시:

// Close Notification
completionHandler (UNNotificationContentExtensionResponseOption.DismissAndForwardAction);

사용자 지정 UI에서 텍스트 입력 작업 작업

앱의 디자인과 알림에 따라 사용자가 알림에 텍스트를 입력해야 하는 경우가 있을 수 있습니다(예: 메시지에 회신). 알림 콘텐츠 확장은 표준 알림과 마찬가지로 기본 제공 텍스트 입력 작업에 액세스할 수 있습니다.

예시:

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

이 코드는 새 텍스트 입력 작업을 만들고 확장의 범주()의 메서드에 MakeExtensionCategory추가합니다. 재정의 DidReceive 메서드에서는 다음 코드를 사용하여 텍스트를 입력하는 사용자를 처리합니다.

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

디자인에서 텍스트 입력 필드에 사용자 지정 단추를 추가해야 하는 경우 다음 코드를 추가하여 포함합니다.

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

사용자가 주석 작업을 트리거하는 경우 뷰 컨트롤러와 사용자 지정 텍스트 입력 필드를 모두 활성화해야 합니다.

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

};

요약

이 문서에서는 Xamarin.iOS 앱에서 새 사용자 알림 프레임워크를 사용하는 방법에 대해 자세히 살펴보았습니다. 로컬 및 원격 알림 모두에 미디어 첨부 파일을 추가하는 방법을 설명했으며 새 사용자 알림 UI를 사용하여 사용자 지정 알림 UI를 만드는 방법을 설명했습니다.