iOS Notifications while app is closed

TravyDaleTravyDale USMember ✭✭

I want to start off by saying I think I am doing my notifications wrong so I am here asking for help as to how to do it the proper way.

My goal -- Show a notification to the user whenever my server pushes them out to the iOS devices. I want this to work even if the app is closed.

Currently, if I have my app open (in the foreground) or running in a sleep state (not active), my remote notifications will funnel into my app and I show a local notification based on the info sent to my app from the server. I do this by handling the DidReceiveRemoteNotification & ReceivedRemoteNotification methods. If one of those are called, I parse the notification message and create a local notification (UILocalNotification).

I do have the 'Remote Notifications' turned on in my plist file.

If it helps, here is the JSON of one sample message I am sending:
{"aps":{"content-available":1,"sound":""}, "message":"Foo Message", "title":"Foo Title"}

I am unsure if this is the correct way to handle notifications because if my app is not running, I do not get notifications to show up when one of pushed out. I have done some reading on this and there is this talk of if your app is 'force closed' it will not receive the notification. Side note -- this seems like a stupid rule for iOS to have lol. I feel like if I were to force close GMail, I will still get notifications for a new email arriving. How do they do it?

Going forward...how do I setup my iOS project to show a notification to the user whenever my server pushes one out no matter the state of my application?

Best Answer

Answers

  • TravyDaleTravyDale USMember ✭✭

    Bump. Still need some guidance on this please.

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai

    Hi @TravyDale,

    While your app is not running, and it receives a push notification, I believe the OS handles displaying the banner. It will parse the json payload and display the message and title. There is a specific structure that a PN json message is, and I believe this is part of the reason why. You might want to simplify your message and test if it's working. Try this:

    {"aps":{"alert":"Foo Message"}}

    If the user taps on the banner displayed, the AppDelegate.FinishedLaunching method is called. The NSDictionary of options passed in will contain UIApplication.LaunchOptionsRemoteNotificationKey to let you know the app was launched because of a push notification. You can check for this and handle it accordingly for your app. i.e. Display an alert, navigate to a page, etc.

  • TravyDaleTravyDale USMember ✭✭

    @JohnMiller
    Oh ok. That makes more sense. Thanks for the reply. Is there any way the app will get notified when the push notification comes (while it is closed)? I was working on a solution that lets the user disable notifications at certain times of the day. If the app doesn't get notified when a notification comes through, then I can't conditionally show/suppress the notification.

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai

    @TravyDale,

    Is there any way the app will get notified when the push notification comes (while it is closed)?

    Yes, this is handled by the OS and it obeys whatever settings your user has allowed for the app. i.e. Badges, Sounds, Banners, etc. These are what you request permission for. Typically the code looks like this:

    if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
    {
        UIUserNotificationType userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
        UIUserNotificationSettings notificationSettings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, null);
        UIApplication.SharedApplication.RegisterUserNotificationSettings(notificationSettings);
        UIApplication.SharedApplication.RegisterForRemoteNotifications();
    }
    else
    {
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
        UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
    }
    
  • TravyDaleTravyDale USMember ✭✭

    @JohnMiller

    So I have this (see below....similar to yours but not exact) and my app does not get opened up and get told of a notification. As in, it isn't opened or sleeping. It is completely closed. If I have the alert in my payload, I do get the notification, but I want to see if my app will be able to conditionally choose whether to show or suppress that notification before it gets shown to the Notification Center. Hope that makes more sense.

    if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
    {
        var pushSettings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());
    
        UIApplication.SharedApplication.RegisterUserNotificationSettings(pushSettings);
        UIApplication.SharedApplication.RegisterForRemoteNotifications();
    }
    else
    {
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound | UIRemoteNotificationType.NewsstandContentAvailability;
        UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
     }
    

    I have tried different flavors of my notification payload to get it to work and have failed. I do have both methods overridden: DidReceiveRemoteNotification & ReceivedRemoteNotification.

  • TravyDaleTravyDale USMember ✭✭

    Ok thanks. I did try it without the sound attribute because I did see that little bit about making sure other stuff is excluded. My app didnt get notified still. I am guessing I am unable to do what I am trying to achieve since the OS wants to process the notifications rather than the app processing them.

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai

    I also got confused by this:

    My app didnt get notified still.

    I understood that as the device never getting the notifications. However, it seems you were always getting the notification, just not getting the FinishedLaunching or DidReceiveRemoteNotification method call as you were expecting. I hope we've cleared up any confusion.

  • TravyDaleTravyDale USMember ✭✭

    That is correct. I am a bit surprised there isn't a way to have the app notified even if it isn't running. Kinda like you can do with Android and having a broadcast listener.

  • PaulDistonPaulDiston USUniversity ✭✭✭✭

    @JohnMiller The documentation you linked to with the following section :-

    Use this method to process incoming remote notifications for your app. Unlike the application:didReceiveRemoteNotification: method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.

    Does not clearly state which method it is referring to. For example, "Use this method to process incoming remote notifications for your app." - What method is this?

    Thanks

    Paul Diston

  • JohnMillerJohnMiller USForum Administrator, Xamarin Team Xamurai

    @PaulDiston,

    Sorry for the confusion. It's referring to application:didReceiveRemoteNotification:fetchCompletionHandler:. It's noted under the Declaration paragraph, slightly above the blurb I quoted. The link is a little tricky because it's expanded the section under that method to see the text.

    That translates to this method:

    public virtual Void DidReceiveRemoteNotification (UIApplication application, NSDictionary userInfo, [MonoTouch.ObjCRuntime.BlockProxy(typeof(MonoTouch.ObjCRuntime.Trampolines/NIDActionArity1V4))] Action<UIBackgroundFetchResult> completionHandler)
    
  • Hi

    From Apple Docs

    Instead of using this method, create a delegate object that adopts the UNUserNotificationCenterDelegate protocol and implement the userNotificationCenter:willPresentNotification:withCompletionHandler: and userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: methods. Assign this object to the delegate property of the singleton UNUserNotificationCenter object.

  • JordanMaxJordanMax USMember ✭✭

    @JohnMiller said:
    @PaulDiston,

    Sorry for the confusion. It's referring to application:didReceiveRemoteNotification:fetchCompletionHandler:. It's noted under the Declaration paragraph, slightly above the blurb I quoted. The link is a little tricky because it's expanded the section under that method to see the text.

    That translates to this method:

    public virtual Void DidReceiveRemoteNotification (UIApplication application, NSDictionary userInfo, [MonoTouch.ObjCRuntime.BlockProxy(typeof(MonoTouch.ObjCRuntime.Trampolines/NIDActionArity1V4))] Action<UIBackgroundFetchResult> completionHandler)
    

    That method is only for when the app is open. What about if the app is closed or in background? What method can we latch onto to parse the data being received from notification?

  • DaveHuntDaveHunt USMember ✭✭✭✭✭

    No, application:didReceiveRemoteNotification: is called when the app is open. It corresponds to ReceivedRemoteNotification in Xamarin.

    application:didReceiveRemoteNotification:fetchCompletionHandler: is called in the background/not running cases. It corresponds to DidReceiveRemoteNotification in Xamarin.

  • Can anyone tell me , when DidReceiveRemoteNotification get called exactly? Because i received notification when app is in background , but unable to get when app is killed...

  • DaveHuntDaveHunt USMember ✭✭✭✭✭

    @chetanchopade.7979 said:
    Can anyone tell me , when DidReceiveRemoteNotification get called exactly? Because i received notification when app is in background , but unable to get when app is killed...

    You will not get notifications after the app is killed. You have to start the app again to begin receiving notifications. This is by design and well documented in the Apple notification programming guide.

  • PhilippSumiPhilippSumi USMember ✭✭✭

    @DaveHunt said:

    You will not get notifications after the app is killed. You have to start the app again to begin receiving notifications. This is by design and well documented in the Apple notification programming guide.

    Actually, apps like Messenger don't have a problem with this. After all, killing all the running apps is a common thing a lot of users do just to clean up the stack of running apps. I'd be surprised if that rendered their ability to react to incoming messages useless.

  • DaveHuntDaveHunt USMember ✭✭✭✭✭

    @PhilippSumi said:
    Actually, apps like Messenger don't have a problem with this. After all, killing all the running apps is a common thing a lot of users do just to clean up the stack of running apps. I'd be surprised if that rendered their ability to react to incoming messages useless.

    From the Local and Remote Notification Programming Guide:

    On an iOS device, if a user force-quits your app using the app multitasking UI, the app does not receive remote notifications until the user relaunches it.

    Comparing the capabilities of first class applications (i.e. the built in apps) with those of 3rd party apps is unwise. First class apps are granted a lot more freedom than 3rd party apps.

  • RAMGOPAL.0311RAMGOPAL.0311 USMember ✭✭

    When the app is running in the background, it works fine. The notification is receiving and the app triggered and event also getting.However, when the app is not running or manually killed app and a push notification is receiving but event not getting. So many developers saying that OS not trigger. I have doubt if not trigger event whenever user kills the app then WhatsApp display custom notification they decrypting message and showing notification, so I think event is possible some where missing Identifications is biggest job.

  • DaveHuntDaveHunt USMember ✭✭✭✭✭

    You can doubt all you want. I'm just quoting Apple's own documentation.

    As to the events not triggering when they should, the most common problem is a failure to understand the breaking changes Apple keeps making in the API. Most of the tutorials and examples on the internet don't get updated to match those changes, so the problem continues.

    Developing iOS applications absolutely requires that you stay familiar and current with Apple's documentation, whether you're using Obj-C, Swift, or C#. Non-Apple samples/tutorials must be checked against Apple's documentation before you decide to use the implementation in your app. There is more bad code and misinformation on the internet than not.

    As to how WhatsApp does what it does, they are likely using notification extensions and message extensions among other things. That's just a guess since I don't have access to their code. ;-)

  • RabbitDarkRabbitDark USMember ✭✭

    I could not receive notification when app are closed, i believe that DaveHunt is correct.
    But, someone got it working?

  • JoshuaTantonJoshuaTanton USMember ✭✭

    I Disagree with Dave Hunt on this one. When I close my application I am able to get notifications through the following message. But so far ONLY ones sent through the firebase console, not through the proper ways my app sends these (sendbird, and webserver).

    [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
    public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action completionHandler)
    {
    completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound | UNNotificationPresentationOptions.Badge);
    }

    This triggers when app is shutdown. When app is in background or foreground the DidReceiveRemoteNotification handles my other cases.

    However the above method may not give me what I need, I'm just about to debug now to see if I can extract the needed data.

  • Rameshbodh_Rameshbodh_ Member ✭✭
    edited June 29

    @DaveHunt
    @JoshuaTanton > @JoshuaTanton said:

    I Disagree with Dave Hunt on this one. When I close my application I am able to get notifications through the following message. But so far ONLY ones sent through the firebase console, not through the proper ways my app sends these (sendbird, and webserver).

    [Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
    public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action completionHandler)
    {
    completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound | UNNotificationPresentationOptions.Badge);
    }

    This triggers when app is shutdown. When app is in background or foreground the DidReceiveRemoteNotification handles my other cases.

    However the above method may not give me what I need, I'm just about to debug now to see if I can extract the needed data.

    In my case I'm not able to receive notification for iphone x(but its working fine in iphone 5) when app is killed.
    please help.

  • Rameshbodh_Rameshbodh_ Member ✭✭

    @DaveHunt @JoshuaTanton
    kindly help
    thanks

Sign In or Register to comment.