iOS AppPush Setup

Retrieve APN Certificate

In order for Wunderkind to send APN’s on behalf of another an APN Certificate must be obtained:

  1. Open KeyChain on your Mac and click Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority.
  2. Complete the following fields and click Request is: Saved to Disk > Continue.
  3. Sign in to your Apple Developer account.
  4. Navigate to Certificates, Identifiers & Profiles.
  5. Select Identifiers from the sidebar.
  6. Select your app identifier then click the box next to Push Notifications, hit save, but do NOT click Configure.
  7. Go back to Identifiers, than go to Certificates, than click the plus.
  8. Select Apple Push Notification service SSL (Sandbox & Production) then Continue.
  9. Select the desired App ID then Continue.

Make sure to to only select a single App ID.

  1. Upload the .cerSigningRequest from Step 2 then download the resulting .cer .
  2. Open the .cer in Finder then open into KeyChain.
  3. In KeyChain go to Login > My Certificates,right click the .cer and click Export "Apple Push Services...".
  4. Name and save the .p12 file.

Upload APN Certificate

Once the APN Certificate(.p12) has been obtained, it must be uploaded to Wunderkind via Connect:

  1. Visit https://connect.wunderkind.co/websites/WEBSITEID/settings?tab=msdk (replacing WEBSITEID with your Website ID)
  2. Under iOS > Push Notification Certificate, click Click to Upload a .p12 File and upload your .p12.
  3. After a few seconds, the screen will update to show the time the certificate was uploaded

If the uploaded certificate needs to be removed, please reach out to Wunderkind for assistance.

App Setup

1. Configure Push Notification Capability

In Xcode, select your app/project then:

  1. Go to Signing & Capabilities
  2. Click + Capability
  3. Add Push Notifications
  4. Ensure you have a Provisioning Profile set

2) Update Info.plist

Add the following key to your Info.plist file:

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

3. Update AppDelegate.swift

The following code must be added to your app's AppDelegate.swift. Add the code inside each function to the function that it is found in. If the function is absent, add the function as well. Ensure AppDelegate extends UNUserNotificationCenterDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions
        launchOptions: [UIApplication.LaunchOptionsKey: Any]?)
        -> Bool {
        ...
        UNUserNotificationCenter.current().delegate = self
        UIApplication.shared.registerForRemoteNotifications()
        UNUserNotificationCenter.current()
            .requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
                if granted {
                    Wunderkind.shared.trackAppPushOptIn()
                } else {
                    Wunderkind.shared.trackAppPushOptOut()
                }
            }

        UNUserNotificationCenter.current().getNotificationSettings { settings in
            switch settings.authorizationStatus {
            case .authorized:
                Wunderkind.shared.trackAppPushOptIn()
            case .denied:
                Wunderkind.shared.trackAppPushOptOut()
            default:
                break
            }
        }
        return true
    }


    func applicationDidBecomeActive(_ application: UIApplication) {
        UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
            notifications
                .filter { $0.request.content.userInfo["wunderkindPayload"] != nil }
                .forEach { notification in
                    Wunderkind.shared.trackAppPushDelivered(appPush: notification)
                }
        }
    }


    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Wunderkind.shared.trackAppPushTokenSet(deviceToken: deviceToken)
    }


    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        UIApplication.shared.applicationIconBadgeNumber -= 1
        let notification = response.notification
        if let wunderkindPayload = notification.request.content.userInfo["wunderkindPayload"] as? [String: Any] {
            handleWunderkindItemIds(payload: wunderkindPayload)
            Wunderkind.shared.trackAppPushOpened(appPush: notification)
        }
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, with
        @escaping (UNNotificationPresentationOptions) -> Void) {
        if let wunderkindPayload = notification.request.content.userInfo["wunderkindPayload"] as? [String: Any] {
            handleWunderkindItemIds(payload: wunderkindPayload)
            Wunderkind.shared.trackAppPushOpened(appPush: notification)
            Wunderkind.shared.trackAppPushDelivered(appPush: notification)
        }
    }


    func handleWunderkindItemIds(payload: [String: Any]) {
        guard let wunderkindItemIds = payload["wunderkindItemIds"] as? String else {
            return
        }

        if wunderkindItemIds.contains(" , ") {
            let itemIdsArray = wunderkindItemIds.components(separatedBy: " , ")
            print(itemIdsArray)
            // Handle the array of item IDs as needed
        } else {
            // Handle the single item ID case
        }
    }
}