Silent Background Notifications won't keep app awake

Hey guys,


unfortunately, I'm also struggling to get silent remote notifications to work within my iOS app. By means of the Console I have gotten as far as having assessed that the silent notifications actually make it to my device. From the logs I can see that my app seems to actually get started for a millisecond (running-active - role: Background) but then gets put back to "suspended" state. I have attached a log at the bottom.


It seems that SpringBoard starts my app due to the silent push notification but the system kills the app right away for some reason so that the callback


func application(_: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandlercompletionHandler: @escaping (UIBackgroundFetchResult) -> Void)

is never called.

What works is starting the app with the "wait for the executable to be launched" scheme flag set and then sending the push notification. That actually triggers an app start and gives me the push notifications values in the launchOptions.

Is this an expected behaviour? Since I don't have any Background modes active (aside from "Remote notifications") my app should get suspended pretty much right away when the user minimizes it, correct? In that case the silent push notification would always run through


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool

and didReceiveRemoteNotification would never get called. Or am I missing something?


Here's the console log:


Cheers


default23:27:06.491141+0100SpringBoardReceived incoming message on topic de.myapp.app at priority 1
default23:27:06.494962+0100SpringBoard[de.myapp.app] Received remote notification request 20CB-40C3 [ waking: 0, hasAlertContent: 0, hasSound: 0 hasBadge: 0 hasContentAvailable: 1 hasMutableContent: 0 pushType: Background]
default23:27:06.495012+0100SpringBoard[de.myapp.app] Process delivery of push notification 20CB-40C3
default23:27:06.495052+0100SpringBoard[de.myapp.app] Request DUET delivers content-available push notification to application
default23:27:06.495398+0100SpringBoardGetting effectiveSectionInfo for section identifier: de.myapp.app
default23:27:06.495445+0100SpringBoard[de.myapp.app] Getting effective section info
default23:27:06.496212+0100dasdSubmitted Activity: com.apple.pushLaunch.de.myapp.app:386E64 at priority 5 <private>
default23:27:06.496258+0100SpringBoard[de.myapp.app] Got effective section info [ hasResult: 1 ]
default23:27:06.504451+0100dasdcom.apple.pushLaunch.de.myapp.app:386E64:[
{name: DeviceActivityPolicy, policyWeight: 5.000, response: {Decision: Can Proceed, Score: 0.36}}

] sumScores:93.828182, denominator:97.010000, FinalDecision: Can Proceed FinalScore: 0.967201}

default23:27:06.504497+0100dasd'com.apple.pushLaunch.de.myapp.app:386E64' DecisionToRun: 1 (Bypasses Predictions)
default23:27:06.505110+0100dasdcom.apple.pushLaunch.de.myapp.app:386E64:[
{name: DeviceActivityPolicy, policyWeight: 5.000, response: {Decision: Can Proceed, Score: 0.36}}

] sumScores:93.828182, denominator:97.010000, FinalDecision: Can Proceed FinalScore: 0.967201}

default23:27:06.506589+0100dasd[FBSSystemService][0xa606] Sending request to open "de.myapp.app"
default23:27:06.511280+0100SpringBoard[FBSystemService][0xa606] Received request to open "de.myapp.app" from dasd:146.
default23:27:06.511668+0100SpringBoardReceived trusted open application request for "de.myapp.app" from <FBProcess: 0x280f59ce0; daemon<com.apple.dasd>:146>.
default23:27:06.528820+0100SpringBoardExecuting request: <SBMainWorkspaceTransitionRequest: 0x281b4f980; eventLabel: OpenApplication(sceneID:de.myapp.app-default)ForRequester(dasd.146); display: Main; source: FBSystemService>
default23:27:06.540025+0100SpringBoardExecuting suspended-activation immediately: OpenApplication(sceneID:de.myapp.app-default)ForRequester(dasd.146)
default23:27:06.541018+0100SpringBoardAdding: <FBApplicationProcess: 0x125b72b30; application<de.myapp.app>:-1>
default23:27:06.541079+0100SpringBoardBootstrapping application<de.myapp.app> with intent background-utility
default23:27:06.543560+0100runningboarddAcquiring assertion targeting application<de.myapp.app> from originator [daemon<com.apple.SpringBoard>:57] with description <RBSAssertionDescriptor; FBApplicationProcess; ID: 27-57-684; target: application<de.myapp.app>> attributes = {

<RBSRunningReasonAttribute: 0x141f67800; runningReason: 10000>;

<RBSPreventIdleSleepGrant: 0x141f50260>;

<RBSDefineRelativeStartTimeGrant: 0x141f60d00>;

<RBSGPUAccessGrant: 0x141f5d6b0>;

<RBSCPUAccessGrant: 0x141f5a920; role: Background>;

}

default23:27:06.543629+0100runningboarddAssertion 27-57-684 (target:application<de.myapp.app>) will be created as active
default23:27:06.543962+0100runningboarddExecuting launch request for application<de.myapp.app> (FBApplicationProcess)
default23:27:06.544199+0100runningboarddSubmitting job: <RBLaunchdJob: 0x14312c410; UIKitApplication:de.myapp.app[8921][rb-legacy]>
default23:27:06.548104+0100runningboarddStarted job UIKitApplication:de.myapp.app[8921][rb-legacy]
default23:27:06.550736+0100runningboardd[application<de.myapp.app>:481] This process will be managed.
default23:27:06.551054+0100runningboarddNow tracking process: [application<de.myapp.app>:481]
default23:27:06.552365+0100runningboarddCalculated state for application<de.myapp.app>: running-active (role: Background)
default23:27:06.552647+0100powerdProcess runningboardd.27 Created SystemIsActive "application<de.myapp.app>27-57-684:FBApplicationProcess" age:00:00:00 id:51539644555 [System: PrevIdle SysAct]
default23:27:06.552696+0100SpringBoard[application<de.myapp.app>:481] Bootstrap success!
default23:27:06.552894+0100runningboarddFinished acquiring assertion 27-57-684 (target:application<de.myapp.app>)
default23:27:06.554378+0100SpringBoard[application<de.myapp.app>:481] Setting process task state to: Running
default23:27:06.556840+0100runningboarddAcquiring assertion targeting application<de.myapp.app>(com.apple.frontboard.workspace) from originator [daemon<com.apple.SpringBoard>:57] with description <RBSAssertionDescriptor; "injecting "com.apple.frontboard"-"com.apple.frontboard.workspace-service" to 481<com.apple.frontboard.workspace>"; ID: 27-57-685; target: 481<com.apple.frontboard.workspace>> attributes = {

<RBSHereditaryGrant: 0x141e53870> {

endowmentNamespace = com.apple.boardservices.endpoint-injection;

hasEncodedEndowment = YES;

};

}

default23:27:06.556886+0100runningboarddAssertion 27-57-685 (target:application<de.myapp.app>(com.apple.frontboard.workspace)) will be created as active
default23:27:06.558032+0100runningboarddFinished acquiring assertion 27-57-685 (target:application<de.myapp.app>(com.apple.frontboard.workspace))
default23:27:06.558087+0100runningboarddCalculated state for application<de.myapp.app>: running-active (role: Background)
default23:27:06.558139+0100runningboardd[application<de.myapp.app>:481] Set jetsam priority to 0 [0] flag[1]
default23:27:06.558188+0100runningboardd[application<de.myapp.app>:481] Resuming task.
default23:27:06.558396+0100runningboardd[application<de.myapp.app>:481] Set darwin role to: Background
default23:27:06.558444+0100runningboardd[application<de.myapp.app>:481] Set GPU priority to "allow"
default23:27:06.559346+0100mediaserverd-CMSessionMgr- CMSessionMgrHandleApplicationStateChange: CMSession: Client de.myapp.app with pid '481' is now Background Running. Background entitlement: NO ActiveLongFormVideoSession: NO WhitelistedLongFormVideoApp NO
default23:27:06.559395+0100mediaserverd-CMSessionMgr- CMSessionMgrHandleApplicationStateChange: CMSession: Sending stop command to de.myapp.app with pid '481' because client is not allowed to play in the background AND does not continue AirPlaying video when device locks
default23:27:06.561075+0100SpringBoardApplication process state changed for de.myapp.app: <SBApplicationProcessState: 0x2830ee0c0; pid: 481; taskState: Running; visibility: Unknown>
default23:27:06.564039+0100runningboarddAcquiring assertion targeting application<de.myapp.app> from originator [daemon<com.apple.dasd>:146] with description <RBSAssertionDescriptor; com.apple.das.backgroundFetch; ID: 27-146-686; target: 481> attributes = {

<RBSLegacyAttribute: 0x141d56150; requestedReason: BackgroundContentFetching; reason: BackgroundContentFetching; flags: PreventTaskSuspend>;

<RBSAcquisitionCompletionAttribute: 0x141d5f610; policy: 0>;

}

default23:27:06.564093+0100runningboarddAssertion 27-146-686 (target:application<de.myapp.app>) will be created as inactive as start-time-defining assertions exist
default23:27:06.564564+0100runningboarddFinished acquiring assertion 27-146-686 (target:application<de.myapp.app>)
default23:27:06.603030+0100EU 2020Identity resolved as application<de.myapp.app>
default23:27:06.605624+0100backboarddConnection added: IOHIDEventSystemConnection uuid:57E9CCED-52BE-4D2F-87CB-CA580CBCF52F pid:481 process:EU 2020 type:Passive entitlements:0x0 caller:BackBoardServices: <redacted> + 384 attributes:{

HighFrequency = 1;

bundleID = "de.myapp.app";

pid = 481;

} inactive:1 events:0 mask:0x0

default23:27:06.607364+0100SpringBoard[application<de.myapp.app>:481] Launch complete.
default23:27:06.613198+0100runningboarddAcquiring assertion targeting application<de.myapp.app> from originator [daemon<com.apple.SpringBoard>:57] with description <RBSAssertionDescriptor; "Subordinate Process"; ID: 27-57-687; target: 481> attributes = {

<RBSSubordinateProcessAttribute: 0x141d55d00>;

}

default23:27:06.613497+0100runningboarddAssertion 27-57-687 (target:application<de.myapp.app>) will be created as active
default23:27:06.616631+0100runningboarddCalculated state for application<de.myapp.app>: running-active (role: Background)
default23:27:06.616676+0100runningboarddFinished acquiring assertion 27-57-687 (target:application<de.myapp.app>)
default23:27:06.618202+0100SpringBoard[sceneID:de.myapp.app-default] Scene lifecycle state did change: Background
default23:27:06.618304+0100SpringBoard[sceneID:de.myapp.app-default] Sending scene action [Logical Activate][0x45f1] through WorkspaceServer: 0x282d15000
default23:27:06.618406+0100SpringBoard[sceneID:de.myapp.app-default] Scene activity state did change: BackgroundActive.
default23:27:06.620224+0100runningboarddAcquiring assertion targeting application<de.myapp.app> from originator [daemon<com.apple.SpringBoard>:57] with description <RBSAssertionDescriptor; "FBScene (BackgroundActive) <sceneID:de.myapp.app-default>"; ID: 27-57-688; target: 481> attributes = {

<RBSRunningReasonAttribute: 0x141f62260; runningReason: 10001>;

<RBSDefineRelativeStartTimeGrant: 0x141f5c4b0>;

<RBSGPUAccessGrant: 0x141f63ed0>;

<RBSCPUAccessGrant: 0x141f61140; role: NonUserInteractive>;

<RBSJetsamPriorityGrant: 0x141f531b0; priority: Background>;

<RBSDurationAttribute: 0x141f5c470; invalidationDuration: 20.00; warningDuration: 0.00; startPolicy: Fixed; endPolicy: Invalidate>;

<RBSResistTerminationGrant: 0x141f5c4a0; terminationResistance: NonInteractive>;

}

default23:27:06.620421+0100runningboarddAssertion 27-57-688 (target:application<de.myapp.app>) will be created as active
default23:27:06.620785+0100SpringBoard[application<de.myapp.app>:481] Setting process visibility to: Background
default23:27:06.621525+0100SpringBoard[sceneID:de.myapp.app-default] Now connected: sending pended scene actions.
default23:27:06.622172+0100runningboardd[application<de.myapp.app>:481] Set jetsam priority to 3 [0] flag[1]
default23:27:06.622217+0100runningboarddCalculated state for application<de.myapp.app>: running-active (role: NonUserInteractive)
default23:27:06.622267+0100runningboarddFinished acquiring assertion 27-57-688 (target:application<de.myapp.app>)
default23:27:06.622864+0100runningboardd[application<de.myapp.app>:481] Set darwin role to: NonUserInteractive
default23:27:06.623975+0100SpringBoardApplication process state changed for de.myapp.app: <SBApplicationProcessState: 0x283668e40; pid: 481; taskState: Running; visibility: Background>
default23:27:06.625063+0100SpringBoardApplication process state changed for de.myapp.app: <SBApplicationProcessState: 0x283652ec0; pid: 481; taskState: Running; visibility: Background>
default23:27:06.707652+0100EU 2020[de.myapp.app] Setting badge number to 0
default23:27:06.708309+0100locationd{"msg":"state transition", "event":"state_transition", "state":"DaemonClient", "id":"0x11f68e6b0", "property":"clientName", "old":"", "new":"de.myapp.app"}
default23:27:06.708883+0100locationdClient de.myapp.app connected with message name LocationManager/kCLConnectionMessageRegistration
default23:27:06.710964+0100SpringBoard[de.myapp.app] Setting badge to (null) [ old badge: (null) ]
default23:27:06.711088+0100SpringBoardClient "<BSProcessHandle: 0x2823fca40; SpringBoard:57; valid: YES>" is requesting to change the badge value of de.myapp.app to (null)
default23:27:06.711297+0100EU 2020[de.myapp.app] Set badge number [ hasCompletionHandler: 0 hasError: 0 ]
default23:27:06.711383+0100SpringBoardClient "<BSCnx:host:com.apple.uis.applicationStateService:0x2817b9770>" set the badge value of de.myapp.app to (null)
default23:27:06.714476+0100locationd{"msg":"update client authorization mask", "name":"de.myapp.app", "old":0, "new":0, "localAuthorizationChange":1}
default23:27:06.725384+0100runningboarddInvalidating assertion 27-146-686 (target:application<de.myapp.app>) from originator 146
default23:27:06.727555+0100locationd{"msg":"#PersistentSubscription PersistenceBackend removeAllPersistedDataForSubscription", "clientKey":"de.myapp.app", "storageName":"VisitMonitoring"}
default23:27:06.729938+0100dasdCOMPLETED com.apple.pushLaunch.de.myapp.app:386E64 at priority 5 <private>!
default23:27:06.730041+0100dasdNO LONGER RUNNING com.apple.pushLaunch.de.myapp.app:386E64 ...Tasks running in group [com.apple.dasd.defaultNetwork] are 0!
default23:27:06.738327+0100SpringBoard[sceneID:de.myapp.app-default] Scene action [Logical Activate][0x45f1] completed with success: 1
default23:27:06.739120+0100SpringBoard[sceneID:de.myapp.app-default] Scene activity state did change: BackgroundInactive.
default23:27:06.739523+0100runningboarddInvalidating assertion 27-57-688 (target:application<de.myapp.app>) from originator 57
default23:27:06.835628+0100runningboardd[application<de.myapp.app>:481] Set jetsam priority to 0 [0] flag[1]
default23:27:06.835776+0100runningboardd[application<de.myapp.app>:481] Set darwin role to: Background
default23:27:06.835855+0100runningboarddCalculated state for application<de.myapp.app>: running-active (role: Background)
default23:27:07.663908+0100runningboarddInvalidating assertion 27-57-684 (target:application<de.myapp.app>) from originator 57
default23:27:07.774523+0100runningboarddRemoved last relative-start-date-defining assertion for process application<de.myapp.app>
default23:27:07.777987+0100runningboarddCalculated state for application<de.myapp.app>: running-suspended (role: None)
default23:27:07.778116+0100runningboardd[application<de.myapp.app>:481] Suspending task.
default23:27:07.781121+0100runningboardd[application<de.myapp.app>:481] Shutdown sockets (SVC)
default23:27:07.781337+0100runningboardd[application<de.myapp.app>:481] Set darwin role to: None
default23:27:07.781575+0100runningboardd[application<de.myapp.app>:481] Set GPU priority to "deny"
default23:27:07.786770+0100runningboardd[application<de.myapp.app>:481] Shutdown sockets (ALL)
default23:27:07.788186+0100SpringBoard[application<de.myapp.app>:481] Setting process task state to: Suspended
default23:27:07.788307+0100SpringBoardApplication process state changed for de.myapp.app: <SBApplicationProcessState: 0x2837b5380; pid: 481; taskState: Suspended; visibility: Background>
default23:27:07.789727+0100powerdProcess runningboardd.27 Released SystemIsActive "application<de.myapp.app>27-57-684:FBApplicationProcess" age:00:00:01 id:51539644555 [System: PrevIdle]
default23:27:07.790122+0100mediaserverd-CMSessionMgr- CMSessionMgrHandleApplicationStateChange: CMSession: Client de.myapp.app with pid '481' is now Background Suspended. Background entitlement: NO ActiveLongFormVideoSession: NO WhitelistedLongFormVideoApp NO
default23:27:07.790180+0100mediaserverd-CMSessionMgr- CMSessionMgrHandleApplicationStateChange: CMSession: Sending stop command to de.myapp.app with pid '481' because client is background suspended and there is no AirPlay video session for it
default23:27:07.796139+0100locationdClient de.myapp.app disconnected

Replies

Quick addon: When running the app on the phone, attached to the XCode debugger, then minimizing the app, locking the phone and then sending it a silent push notification I also don't succeed in getting


func application(_: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

to get called.

In the Console at some point it says:


COMPLETED com.apple.pushLaunch.de.myapp.app:0ADB2E at priority 5 !
NO LONGER RUNNING com.apple.pushLaunch.de.myapp.app:0ADB2E ...Tasks running in group [com.apple.dasd.defaultNetwork] are 0!

The only suspicious logs I can see before that are:


-CMSessionMgr- CMSessionMgrHandleApplicationStateChange: CMSession: Sending stop command to de.myapp.app with pid '494' because client is not allowed to play in the background AND does not continue AirPlaying video when device locks
[sceneID:de.myapp.app-default] Scene action [SceneLifecycleEventOnly][0xe7ca] completed with success: 1
[sceneID:de.myapp.app-default] Scene activity state did change: BackgroundInactive.
Invalidating assertion 27-57-731 (target:application) from originator 57

Ok, after some more digging it seems like what I speculated above is actually true.


When you don't have an app that has any other background modes active (like location or audio) your app will be suspended (most of the times) when the users minimize/close it. When you then send a silent push notification to the app it is not running in the background and thus the callback "didReceiveRemoteNotification" will not get called.

Instead, your app will be started in the background and the silent push notification's parameters will get passed into the initial func


application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:...


as "launchOptions". So on app start you should check the launchOptions dictionary for your silent push notification's data and process it accordingly.

  • Is there any solution to resume suspended app ?

Add a Comment

Hi, did you got a fix for it? I'm facing this issue too.
The console says: "com.app.myapp: Foreground: False" seconds after minimizing my app.
If i send a local notification between the minimize action and the console print, the app works as intended on the foreground, but afther the console output, the process doesn't really run. 😟