Xamarin формы: как обрабатывать уведомления нажмите в IOS - PullRequest
1 голос
/ 09 июля 2019

Я реализовал push-уведомление в своем проекте xamarin forms ios. Теперь я могу получать уведомления на мои айфоны, которые отправляются от почтальона. Но при нажатии на уведомление, как я могу прочитать данные моей модели из уведомления и загрузить PCL App.xaml.cs?

При нажатии на уведомление на устройстве ios мне нужно открыть страницу контента (страницу со списком сообщений) в моем проекте PCL. Я реализовал это в своем проекте PCL App.xaml.cs. Для этого мне нужно загрузить App.xaml.cs из AppDelegate.cs с данными модели, полученными из уведомления.

Следующим способом я загружаю App.xaml.cs с Android MainActivity

LoadApplication(new App(notificationdata));

В ios DidReceiveRemoteNotification вызывается при получении уведомления для фонового и переднего режимов, но не вызывается при нажатии на уведомление.

Мое уведомление: webContentList - это данные моей модели.

{
 "to" : "dmtfiSvBBM0:APA91bFnHkamMSYgxPuiSfdvKnU8hD_mOqrWijnENNgXVSkSgo1ILH3-uKVCU7Ez2PXXOhtDoobIyKBf5UshVfTmvjSqHgXMRTsqguKCSTjIfGnXrVP-_cNFq2sisshZO-BcfkwKTl-I",
 "collapse_key" : "type_a",
 "notification" : {
      "body" : "This is body",
     "title": "Tech Team",
     "priority":"high",
     "content_available":true
 },
 "data" : {
    "webContentList": [
        {
            "webContentDefinitionId": 818084,
            "pageTitle": "CCD Grade 3-4",
            "pageKwd": "CCD Grade 3-4",
            "pageDesc": "CCD Grade 3-4",
            "siteId": 45,
            "pageCreatedTime": 1555145959428,
            "pageUpdatedDate": 1555927274279,
            "modifier": {
                "userId": 12944,
                "applicationId": 32,
                "username": "robert.downey",
                "email": "robert@master-mail.net",
                "firstName": "Robert",
                "lastName": "Downey"
            },
            "creator": {
                "userId": 12944,
                "applicationId": 32,
                "username": "robert.downey",
                "email": "robert@master-mail.net",
                "firstName": "Robert",
                "lastName": "Downey"
            }
        }
        ]
 },
  "ttl": 3600
}

My AppDelegate.cs

    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IUNUserNotificationCenterDelegate, IMessagingDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            Rg.Plugins.Popup.Popup.Init();
            global::Xamarin.Forms.Forms.Init();
            ImageCircleRenderer.Init();
            LoadApplication(new App("", ""));

            #region Push Notification            
            Firebase.Core.App.Configure();
            if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
            {
                // iOS 10 or later
                var authOptions = UNAuthorizationOptions.Alert | UNAuthorizationOptions.Badge | UNAuthorizationOptions.Sound;
                UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) => {
                    Console.WriteLine(granted);
                });

                // For iOS 10 display notification (sent via APNS)
                UNUserNotificationCenter.Current.Delegate = this;

                // For iOS 10 data message (sent via FCM)
                //Messaging.SharedInstance.RemoteMessageDelegate = this;
            }
            else
            {
                // iOS 9 or before
                var allNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
                var settings = UIUserNotificationSettings.GetSettingsForTypes(allNotificationTypes, null);
                UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
            }

            UIApplication.SharedApplication.RegisterForRemoteNotifications();

            Messaging.SharedInstance.Delegate = this;
            Messaging.SharedInstance.ShouldEstablishDirectChannel = true;
            #endregion

            return base.FinishedLaunching(app, options);
        }

        [Export("messaging:didReceiveRegistrationToken:")]
        public void DidReceiveRegistrationToken(Messaging messaging, string fcmToken)
        {
            LogInformation(nameof(DidReceiveRegistrationToken), $"Firebase registration token: {fcmToken}"
            MessagingCenter.Send<object, string>(this, "fcmtoken", fcmToken.ToString());
            Console.WriteLine($"fcmtoken received: {fcmToken}");
        }

        public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
        {
            HandleMessage(userInfo);
            // Print full message.
            LogInformation(nameof(DidReceiveRemoteNotification), userInfo);
            completionHandler(UIBackgroundFetchResult.NewData);
        }

        [Export("messaging:didReceiveMessage:")]
        public void DidReceiveMessage(Messaging messaging, RemoteMessage remoteMessage)
        {
            // Handle Data messages for iOS 10 and above.
            HandleMessage(remoteMessage.AppData);
            LogInformation(nameof(DidReceiveMessage), remoteMessage.AppData);
        }

        void HandleMessage(NSDictionary message)
        {
            //if (MessageReceived == null)
            //    return;

            //MessageType messageType;
            //if (message.ContainsKey(new NSString("aps")))
            //    messageType = MessageType.Notification;
            //else
            //    messageType = MessageType.Data;

            //var e = new UserInfoEventArgs(message, messageType);
            //MessageReceived(this, e);
        }

        public static void ShowMessage(string title, string message, UIViewController fromViewController, Action actionForOk = null)
        {
            var alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
            alert.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, (obj) => actionForOk?.Invoke()));
            fromViewController.PresentViewController(alert, true, null);
        }

        void LogInformation(string methodName, object information) => Console.WriteLine($"\nMethod name: {methodName}\nInformation: {information}");

        async Task RequestPushPermissionAsync()
        {
            // iOS10 and later (https://developer.xamarin.com/guides/ios/platform_features/user-notifications/enhanced-user-notifications/#Preparing_for_Notification_Delivery)
            // Register for ANY type of notification (local or remote):
            var requestResult = await UNUserNotificationCenter.Current.RequestAuthorizationAsync(
                UNAuthorizationOptions.Alert
                | UNAuthorizationOptions.Badge
                | UNAuthorizationOptions.Sound);


            // Item1 = approved boolean
            bool approved = requestResult.Item1;
            NSError error = requestResult.Item2;
            if (error == null)
            {
                // Handle approval
                if (!approved)
                {
                    Console.Write("Permission to receive notifications was not granted.");
                    return;
                }

                var currentSettings = await UNUserNotificationCenter.Current.GetNotificationSettingsAsync();
                if (currentSettings.AuthorizationStatus != UNAuthorizationStatus.Authorized)
                {
                    Console.WriteLine("Permissions were requested in the past but have been revoked (-> Settings app).");
                    return;
                }

                UIApplication.SharedApplication.RegisterForRemoteNotifications();
            }
            else
            {
                Console.Write($"Error requesting permissions: {error}.");
            }
        }
    }
}

Журнал данных при получении уведомления:

Method name: DidReceiveRemoteNotification
Information: {
    aps =     {
        alert =         {
            body = "This is body";
            title = "Tech Team";
        };
        "content-available" = 1;
    };
    "gcm.message_id" = 1562648547588794;
    "gcm.notification.priority" = high;
    "google.c.a.e" = 1;
    webContentList = "[{\"swcmMessage\":null,\"pageTitle\":\"CCD Grade 3-4\",\"modifier\":{\"lastname\":\"downey\",\"zipcode\":null,\"parentemail\":null,\"address2\":null,\"city\":null,\"address1\":null,\"phone2\":null,\"userid\":12944,\"enabled\":true,\"phone1\":null,\"firstname\":\"robert\",\"state\":null,\"usertype\":null,\"applicationid\":32,\"profileimageurl\":null,\"profileimagetype\":null,\"email\":\"robert@master-mail.net\",\"username\":\"robert.downey\"},\"deletable\":true,\"pagecontenttype\":\"tweets.topics\",\"previewuuid\":null,\"webcontentdefinitionid\":818084,\"pagecreatedtime\":1555145959428,\"usercreated\":12944,\"pagestatus\":\"on\",\"thumbnailimageurl\":null,\"videourl\":null,\"imageurl\":\"\",\"webcontentid\":65059,\"creator\":{\"lastname\":\"downey\",\"zipcode\":null,\"parentemail\":null,\"address2\":null,\"city\":null,\"address1\":null,\"phone2\":null,\"userid\":12944,\"enabled\":true,\"phone1\":null,\"firstname\":\"robert\",\"state\":null,\"usertype\":null,\"applicationid\":32,\"profileimageurl\":null,\"profileimagetype\":null,\"email\":\"robert\"},\"contentTemplateId\":null,\"appName\":\"services\",\"customHTML\":\"\",\"processedTime\":null,\"pageDesc\":\"CCD Grade 3-4\",\"editUrl\":\"\\/module\\/tweets-topics\\/edit-tweets-topics?webcontentid=818084\",\"pageKwd\":\"CCD Grade 3-4\",\"staticContent\":true,\"siteId\":45,\"pageUrl\":\"\\/tweets-topics\\/818084\\/1\\/ccd-grade-3-4\",\"linkType\":null,\"pageUpdatedDate\":1555927274279,\"swcmStatus\":null,\"userModified\":12944}]";
}

webContentList - это данные моей модели, эти данные мне нужны при загрузке файла App.xaml.cs. Как я могу проанализировать эти данные из DidReceiveRemoteNotification userInfo и загрузить App.xaml.cs?

1 Ответ

2 голосов
/ 09 июля 2019

Используйте Newtonsoft.Json для десериализации json и Messaging Center для передачи данных.

AppDelegate.cs

public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
    HandleMessage(userInfo);
    // Print full message.
    LogInformation(nameof(DidReceiveRemoteNotification), userInfo);        
    completionHandler(UIBackgroundFetchResult.NewData);

    var myData = JsonConvert.DeserializeObject<List<YourModel>>(userInfo[new NSString("webContentList")] as NSString);
    MessagingCenter.Send<object,List<YourModel>>(this,"PassData",myData);
}

App.cs

MessagingCenter.Subscribe<object, List<YourModel>>(this, "PassData", (object obj , List<YourModel> list)=>{

});
...