This is an example implementation of the SDK in an iOSApp. The App will have a login flow and will enable / disable In Apps to only show them to users that are logged in.

First we need to set the PULAuthorizationData. If possible set this data in the AppDelegate didFinishLaunchingWithOptions callback.

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let authData: PULAuthorizationData = try PULAuthorizationData(withAppId: appid, andAppKey: appkey)
        let pulsateManager = try PULPulsateFactory.getInstance(withAuthorizationData:authData,
                                                        withLocationEnabled: true,
                                                        withPushEnabled: true,
                                                        withLaunchOptions: launchOptions,
                                                        withPulsateAppDelegate: true,
                                                        andPulsateNotificationDelegate: true)
    }
}

In our Login Screen we will check if the user is logged in or not and turn In Apps on for logged in users.

class LoginViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let pulsateManager = try PULPulsateFactory.getDefaultInstance()
        
        // We want to show some type of loading indicator and block the login screen while we check if the user is logged in
        showSpinner()
        let isUserLoggedIn = mLoginViewModel.isUserLoggedIn()
        if (isUserLoggedIn) {
            // If the user is logged in we want to enable in app notifications and navigate to the main screen
            pulsateManager?.enable(inAppNotification: true)
            navigateToMainScreen()
        } else {
            // If the user is not logged in we hide the loading indicator and unblock the login screen
            hideSpinner()
            setupLoginScreen()
        }
    }
}

We do not want to start the Pulsate session on the Login Screen, because the Pulsate session is an async call that does network calls in the background and on success it will try to attach an In App to the Login Screen which will soon be destroyed. Attaching the In App to a screen that will shortly be destroyed can possibly cause the In App to not render at all. In the Main Screen we will be starting the session and ask the SDK to show any In Apps that might be waiting to render.

class MainViewController : UIViewController {
  override func viewDidLoad() {
        super.viewDidLoad()
        let pulsateManager = try PULPulsateFactory.getDefaultInstance()

        pulsateManager?.startPulsateSession(forAlias: alias) { success, error in 
        		 pulsateManager?.enable(inAppNotification: true)
             pulsateManager?.showLastInAppNotification(true)
        }
    }
}

This will start a Pulsate session, enable In Apps if they are disabled for any reason and show any In Apps that are waiting to be shown. We do not want to call "enable(inAppNotification" multiple times with different values, because these are async database calls and can result in a race condition where either the wrong value is set or the In Apps are in the middle of rendering and we suddenly block them from showing.

Once the user leaves our App we still want him to receive push notifications, but don't want him to see any In Apps until he logs in again and is on the Main Screen. To achieve this we can use the applicationWillEnterForeground callback in our AppDelegate class.

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let authData: PULAuthorizationData = try PULAuthorizationData(withAppId: appid, andAppKey: appkey)
        let pulsateManager = try PULPulsateFactory.getInstance(withAuthorizationData:authData,
                                                        withLocationEnabled: true,
                                                        withPushEnabled: true,
                                                        withLaunchOptions: launchOptions,
                                                        withPulsateAppDelegate: true,
                                                        andPulsateNotificationDelegate: true)
    }
 
    func applicationDidEnterBackground(_ application: UIApplication) {
        let pulsateManager = try PULPulsateFactory.getDefaultInstance()
        pulsateManager?.enable(inAppNotification: false)
    }
}

This implementation will allow Pulsate to still be active in the background and trigger geofences / beacons / pushes / manage sessions and you will only show In Apps to logged in users. If needed you can also disable push notifications by just adding pulsateManager.setPushNotificationEnabled(true) and pulsateManager.setPushNotificationEnabled(false).