当应用程序位于前台但不在后台时,远程通知正在工作

时间:2014-12-26 08:05:45

标签: c# ios iphone xamarin.ios apple-push-notifications

我有一个Xamarin.iOS应用程序可以在应用程序在前台运行时成功接收APNS推送通知。但是,我还希望能够在应用程序在后台运行或根本不运行时处理推送通知。

Xamarin上的这个页面似乎说你确实可以这样做:

http://developer.xamarin.com/guides/ios/application_fundamentals/backgrounding/part_3_ios_backgrounding_techniques/updating_an_application_in_the_background/

我正在使用上面列出的远程通知策略。所以我实现了它所说的内容,包括更改info.plist以将远程通知作为后台操作。但是,当应用程序在后台运行时,我在DidFinishedLaunching或ReceivedRemoteNotification回调中没有得到任何调用。当应用程序在前台运行时,一切正常。不用说,这太令人沮丧了。

还有其他人遇到过这个问题吗?

非常感谢任何帮助!

以下是我用来注册远程通知的代码:

    public static void NotifyAppStart()
    {
        if (GetRemoteWipePreference())
        {
            if (Utils.CheckOsVersion(8, 0))
            {
                // iOS 8 version

                UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());  

                UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

                UIApplication.SharedApplication.RegisterForRemoteNotifications();

            }
            else
            {
                // Only works on iOS 7 and earlier

                UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
                UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
            }


        }

    }

这是我用来在服务器端发送推送通知的PushSharp代码:

push.RegisterAppleService(new ApplePushChannelSettings(appleCert, GetApplePwd()  ));
        push.QueueNotification(new AppleNotification()
                                   .ForDeviceToken( token ).WithContentAvailable(1)
                                   .WithCustomItem(msg, device.device_local_guid)  );

旁注:关于这个一般区域的堆栈溢出还有一些其他问题,但实际上没有一个是关于这个问题的。

2 个答案:

答案 0 :(得分:0)

if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
        {
            var settings = UIUserNotificationSettings.GetSettingsForTypes (UIUserNotificationType.Sound |
                UIUserNotificationType.Alert | UIUserNotificationType.Badge, null);

            UIApplication.SharedApplication.RegisterUserNotificationSettings (settings);
            UIApplication.SharedApplication.RegisterForRemoteNotifications ();
        }
        else
        {
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(UIRemoteNotificationType.Badge |
                UIRemoteNotificationType.Sound | UIRemoteNotificationType.Alert);
        }

你也需要这个

public override void RegisteredForRemoteNotifications (UIApplication application, NSData deviceToken)
    {
        var oldDeviceToken = NSUserDefaults.StandardUserDefaults.StringForKey("PushDeviceToken");

        var strFormat = new NSString("%@");
        var dt = new NSString(MonoTouch.ObjCRuntime.Messaging.IntPtr_objc_msgSend_IntPtr_IntPtr(new MonoTouch.ObjCRuntime.Class("NSString").Handle, new MonoTouch.ObjCRuntime.Selector("stringWithFormat:").Handle, strFormat.Handle, deviceToken.Handle));
        var newDeviceToken = dt.ToString().Replace("<", "").Replace(">", "").Replace(" ", "");
        string sql;

        if (string.IsNullOrEmpty(oldDeviceToken) || !deviceToken.Equals(newDeviceToken))
        {
            do someting
        }

        if (oldDeviceToken == newDeviceToken) 
        {
            do someting
        } else 
        {
            do something
        }

        NSUserDefaults.StandardUserDefaults.SetString(newDeviceToken, "PushDeviceToken");
        Console.WriteLine("Device Token: " + newDeviceToken);
    }

如果您的程序是前台,您可以像这样使用

void processNotification(NSDictionary options, bool fromFinishedLaunching)
    {
        if (null != options && options.ContainsKey(new NSString("aps")))
        {
            NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;

            string alert = string.Empty;
            string sound = string.Empty;
            int badge = -1;

            if (aps.ContainsKey(new NSString("alert")))
                alert = (aps[new NSString("alert")] as NSString).ToString();

            if (aps.ContainsKey(new NSString("sound")))
                sound = (aps[new NSString("sound")] as NSString).ToString();

            if (aps.ContainsKey(new NSString("badge")))
            {
                string badgeStr = (aps[new NSString("badge")] as NSObject).ToString();
                int.TryParse(badgeStr, out badge);
            }

            if (!fromFinishedLaunching) 
            {
                if (badge >= 0)
                    UIApplication.SharedApplication.ApplicationIconBadgeNumber = badge;

                if (sound == "xx.caf") 
                {
                    UIAlertView avAlert = new UIAlertView ("Dogrular App", alert, null, "Tamam", null);
                    avAlert.Show ();
                }

                if (sound == "yyy.caf") 
                {
                    UIAlertView avAlert = new UIAlertView ("Dogrular App", alert, null, "Tamam", null);
                    avAlert.Show ();

                    NSUrl request = new NSUrl("https://xxx.com");
                    UIApplication.SharedApplication.OpenUrl(request);
                }
            }
        }
    }

答案 1 :(得分:0)

你的json文件是否包含class布尔键是否为“false”? 示例:

content-available

以上json返回应该调用你的方法

{
   "to": "GCM Registration ID",
  "priority":"high",
  "data": {
        "notificationId":123,
        "title":"Spot you!",
        "message": "&lt;font color=\"red\"&gt;&lt;b&gt;Test RED Bold text maybe ?&lt;/b&gt;&lt;/font&gt;&lt;br/&gt;Normal second line.&lt;br/&gt;&lt;br/&gt;",
        "photoUrl": "http://babymetal.net/wp-content/uploads/2015/07/ladybeard-e1427784688234.jpg",
        "badge": 1
  },
   "dry_run" : false,       
   "time_to_live" : 4,
   "content_available" : false
}