Jump to content
Vanar

Receive PUSH notifications in the background in the iOS app

Recommended Posts

Good afternoon!

Does anyone know how to receive PUSH notifications in the background in an iOS app?

PUSH notifications arrive on your phone,

but the OnReceiveNotificationEvent(Sender: TObject; const ANotification: TPushServiceNotification) event does not fire.

I need to process the PUSH data, perform some actions, and not just open the application.

Share this post


Link to post
4 minutes ago, Vanar said:

Does anyone know how to receive PUSH notifications in the background in an iOS app?

Do you have remote-notification selected in the UIBackgroundModes value, in the Version Info section of Project Options?

Share this post


Link to post

Yes

    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>remote-notification</string>
    </array>
 

Share this post


Link to post
7 hours ago, Vanar said:

I need to process the PUSH data, perform some actions, and not just open the application.

If you want to be able to process the notification without user interaction (i.e. not open the application visibly), you need to follow the rules set out here:

 

https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app?language=objc

 

Share this post


Link to post
4 minutes ago, Vanar said:

Are there any examples in Delphi on this topic?

I was referring to what needs to be in the payload of the notification being sent (i.e. nothing to do with the code in the Delphi app). See the "Create a background notification" section at that link.

 

Share this post


Link to post

Maybe I expressed myself incorrectly.
My PUSH contains all the data (it is well formed and carries useful information).

The situation is like this:
1. My application is in the background.
2. PUSH comes to the phone.
 
At what point can I receive PUSH data:
when PUSH came to the phone or
when do I activate the application?

The fact is that when I exit the background state of the application, I cannot read the information in PUSH.
I just need to read this information.
In what way can you get it, using what event?
If I receive PUSH information,
I will be able to not only wake up the application, but also perform some logic (depending on the content of the PUSH data).

Share this post


Link to post
16 minutes ago, Vanar said:

My PUSH contains all the data (it is well formed and carries useful information).

Does it contain content-available, as I mentioned?

16 minutes ago, Vanar said:

At what point can I receive PUSH data:
when PUSH came to the phone

Yes

16 minutes ago, Vanar said:

when do I activate the application?

What do you mean by "activate the application"? The OS "wakes up" the application in the background, and the message receive handler (in your case, apparently OnReceiveNotificationEvent) gets called, when the message is received.

16 minutes ago, Vanar said:

The fact is that when I exit the background state of the application, I cannot read the information in PUSH.

Possibly because you do not have the content-available member in the payload of the message.

16 minutes ago, Vanar said:

In what way can you get it, using what event?

As mentioned, in the message receive handler

16 minutes ago, Vanar said:

I will be able to not only wake up the application, but also perform some logic (depending on the content of the PUSH data).

. As per the section "Receive Background Notifications" in the same link, you have up to 30 seconds of processing time. Ignore the parts about the app delegate and completion handler - they are handled for you in the FMX code.

 

Incidentally, I've found that trying to make background notifications like this work is a complete nightmare, mainly because of this (from the same link):

 

"The system treats background notifications as low priority: you can use them to refresh your app’s content, but the system doesn’t guarantee their delivery. In addition, the system may throttle the delivery of background notifications if the total number becomes excessive. The number of background notifications allowed by the system depends on current conditions, but don’t try to send more than two or three per hour."


It makes testing such things extremely difficult. Whatever you're attempting to do, you might need to do it some other way.

Edited by Dave Nottage

Share this post


Link to post

Thank you!!!
 

Everything is as you said

The task is localized: OnReceiveNotificationEvent does not work in the background!

 

I did the following:
Placed the TNotificationCenter component on the form.
The OnReceiveLocaNotification event is used, which is fired when a PUSH is received.

But now the problem is that I can't get JSON from my PUSH.
TNotificationCenter does not have a "Json" field.
But I see the fields "Title", "Body",
all other fields are service fields or cannot be changed.

 

I did this:
When forming, PUSH changed the contents of the “Title” field.

The header consists of two lines:
Title = 'current title' + sLineBreak + URL;
The URL is the JSON content, it is the link you want to follow (within the application).

 

The user sees ONLY the first line in the PUSH system window (possibly an OS feature),
and the developer sees everything and can direct the application by URL

 

Problem solved!

 

Do you think this is an original solution or a crutch?🙂

Edited by Vanar

Share this post


Link to post
10 hours ago, Vanar said:

Problem solved!

Good to hear

10 hours ago, Vanar said:

Do you think this is an original solution or a crutch?🙂

Well, it's a solution, apparently? I assume whatever implementation you are using sends a local notification, which to my mind is unnecessary. I use Delphi's built-in FCM support, however even if the messages are not going via FCM, it should be a simple matter of subscribing to TPushRemoteNotificationMessage, e.g.:

  TMessageManager.DefaultManager.SubscribeToMessage(TPushRemoteNotificationMessage, PushRemoteNotificationMessageHandler);

..and in the handler:

procedure TForm1.PushRemoteNotificationMessageHandler(const Sender: TObject; const M: TMessage);
begin
  if M is TPushRemoteNotificationMessage then
    // Use this value (which is JSON): TPushRemoteNotificationMessage(M).Value.Notification
end;

 

  • Thanks 1

Share this post


Link to post
12 hours ago, Dave Nottage said:

procedure TForm1.PushRemoteNotificationMessageHandler(const Sender: TObject; const M: TMessage); begin if M is TPushRemoteNotificationMessage then // Use this value (which is JSON): TPushRemoteNotificationMessage(M).Value.Notification end;

This is, of course, beautiful code, but
it only works when the application is running and active

Edited by Vanar

Share this post


Link to post
13 minutes ago, Vanar said:

it only works when the application is running and active

It works when the app is not running, or not active too. As mentioned before the payload being sent must be correct for it to work, as well as having the correct UIBackgroundModes

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×