Support a scene-based life cycle
UIApplicationDelegate and UISceneDelegate objects manage the app life cycle using events. You decide how to implement the life cycle of events. The steps below provide an example that is based on the Apple Breadcrumbs sample app, with modifications made to declarations and other key areas. Several of the sample apps included in the SDK package demonstrate the event handling life cycle.- Configure the
UISceneDelegateto own theUIWindowwhen the scene connects. Do not create aUIWindowindidFinishLaunchingWithOptions. Defer loading of the main UI until the user is authorized by the BlackBerry Dynamics SDK. Register the scene delegate with yourGDiOSDelegateso the authorized UI can be installed later.Swift:
import UIKit import BlackBerryDynamics.Runtime class AppSceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = scene as? UIWindowScene else { return } if let keyWin = windowScene.keyWindow { window = keyWin } else { window = UIWindow(windowScene: windowScene) window?.makeKeyAndVisible() } AppGDiOSDelegate.shared.sceneDelegate = self } func launchApplicationUI() { let storyboard = UIStoryboard(name: "Main", bundle: nil) window?.rootViewController = storyboard.instantiateInitialViewController() } } - In
AppDelegate, start authorization in didFinishLaunchingWithOptions and connect the scene delegate class to the system scene configuration. Do not create aUIWindowindidFinishLaunchingWithOptions.Swift:import UIKit import BlackBerryDynamics.Runtime @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Call BlackBerry Dynamics to authorise the app. GDiOS.sharedInstance().authorize(AppGDiOSDelegate.shared) return true } func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { let sceneConfig = UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) sceneConfig.delegateClass = AppSceneDelegate.self sceneConfig.sceneClass = UIWindowScene.self return sceneConfig } } - Import
BlackBerryDynamics.Runtimeand implement a skeletonGDiOSDelegateprotocol. The following Swift example relies on a boolean variable namedstarted. Alternatively, you can declare the variable in your project's implementation file. Hold a weak reference to the scene delegate so that the main UI can be loaded after authorization.Swift:
import UIKit import BlackBerryDynamics.Runtime class AppGDiOSDelegate: NSObject, GDiOSDelegate { static let shared = AppGDiOSDelegate() weak var sceneDelegate: AppSceneDelegate? private var started = false } - Use
GDAppEventto process events. Move the application launch code fromdidFinishLaunchingWithOptionsto theGDAppEventhandler method. Add the following method toAppGDiOSDelegate. Handle each event type in the switch statement. The cases below are shown as a skeleton and can be filled in as your application requires.Swift:
func handle(_ anEvent: GDAppEvent) { /* Called from GDiOS when events occur, such as system startup. */ switch anEvent.type { case .authorized: onAuthorized(anEvent: anEvent) break case .notAuthorized: onNotAuthorized(anEvent: anEvent) break case .remoteSettingsUpdate: // A change to application configuration or other settings. break case .servicesUpdate: // A change to services-related configuration. break case .policyUpdate: // A change to application-specific policy settings. break case .entitlementsUpdate: // A change to the entitlements data of the end user. break case .backgroundAuthorized: // Authorized following background authorization processing. break case .backgroundNotAuthorized: // Not authorized following background authorization processing. break default: print("handleEvent \(anEvent.message)") } } - Handle
onNotAuthorizedevents. Verify that the app can handle authorization errors or functionality, including remote wipe, a lockout, or blocking events. Add the following method toAppGDiOSDelegate.Swift:
func onNotAuthorized(anEvent: GDAppEvent) { /* Handle the BlackBerry Libraries not authorized event. */ switch anEvent.code { case .errorActivationFailed: break case .errorProvisioningFailed: break case .errorPushConnectionTimeout: break case .errorSecurityError: break case .errorAppDenied: break case .errorAppVersionNotEntitled: break case .errorBlocked: break case .errorWiped: break case .errorRemoteLockout: break case .errorPasswordChangeRequired: // A condition has occurred denying authorization; an application may wish to log these events. print("onNotAuthorized \(anEvent.message)") case .errorIdleLockout: // Idle lockout is benign and informational. break default: assertionFailure("Unhandled not authorized event") } } - On authorization, start the app. Initialize and start the UI with the
onAuthorizedfunction. Add the following method toAppGDiOSDelegate.TheGDErrorNoneevent is returned by the BlackBerry Dynamics Runtime whenever a container is opened and no error occurs.Swift:
func onAuthorized(anEvent: GDAppEvent) { /* Handle the BlackBerry Libraries authorized event. */ switch anEvent.code { case .errorNone: // started was declared in step 3. if !started { // Show the user UI. started = true sceneDelegate?.launchApplicationUI() } default: assertionFailure("Authorized startup with an error") } }