Silent Push

Prev Next

Overview

Silent Push Notifications in iOS allow developers to send background updates to apps without notifying the user. These notifications are commonly used to refresh app content, update user settings, or trigger other silent actions.

Note:

Silent pushes sent through Mapp Engage arrive on the standard iOS push delivery path. The Mapp Engage SDK exposes two flags on APXPushNotification that identify the silent intent end-to-end:

  • isSilent — set when the payload contains "content-available": 1 and no user-visible alert.

  • isTriggerUpdate — set when Mapp Engage sent the push specifically to refresh device-level data (for example, to invalidate cached attributes).

Read both flags inside didReceiveRemoteNotification to decide whether to treat the payload as a Mapp-driven background sync or a generic silent push.

Use Case

  1. Purpose:

    • Deliver background updates silently without interrupting the user.

    • Trigger app-specific actions like syncing data or refreshing content.

  2. Benefits:

    • Keep the app updated in the background without user intervention.

    • Provide a seamless user experience by ensuring fresh content.

Implementation Details

  1. Silent Push Payload:

    • Include the content-available field in the payload to trigger background processing:

    {
        "aps": {
            "content-available": 1
        },
        "action": "sync_data",
        "data_id": "67890"
    }
    • The content-available field with a value of 1 indicates a silent push.

  2. Enable Background Modes:

    • Enable the Background Fetch and Remote Notifications capabilities in Xcode:

      • Go to Signing & Capabilities > Background Modes.

      • Check Remote notifications and Background fetch.

  3. Handle Silent Pushes: Implement application(_:didReceiveRemoteNotification:fetchCompletionHandler:) to process the silent push and check the Mapp-specific flags.

    func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
        let push = APXPushNotification(userInfo: userInfo)
        if push.isTriggerUpdate {
            // Mapp Engage requested a device-data refresh — let the SDK handle it.
            completionHandler(.newData)
            return
        }
    
        if let action = userInfo["action"] as? String, action == "sync_data",
           let dataID = userInfo["data_id"] as? String {
            syncData(dataID: dataID)
            completionHandler(.newData)
        } else {
            completionHandler(.noData)
        }
    }
    
    func syncData(dataID: String) {
        print("Syncing data with ID: \(dataID)")
    }
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    
        APXPushNotification *push = [[APXPushNotification alloc] initWithUserInfo:userInfo];
        if (push.isTriggerUpdate) {
            completionHandler(UIBackgroundFetchResultNewData);
            return;
        }
    
        NSString *action = userInfo[@"action"];
        if ([action isEqualToString:@"sync_data"]) {
            [self syncDataWithID:userInfo[@"data_id"]];
            completionHandler(UIBackgroundFetchResultNewData);
        } else {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    }
    
    - (void)syncDataWithID:(NSString *)dataID {
        NSLog(@"Syncing data with ID: %@", dataID);
    }

Keep in mind:

  • Silent pushes require the app to have the Remote Notifications capability enabled.

  • The app must handle the silent push quickly and efficiently to avoid timeouts.

  • Test silent push functionality across various scenarios, including app in the background, app terminated, and device sleep mode.