Add the event-handler skeleton using notifications

The application-delegate object UIApplicationDelegate manages the iOS app life cycle using events. You can decide how to implement the life cycle of events; the steps below provide an example that is based loosely on the Apple Breadcrumbs sample app (with differences in declarations and other key areas). Several of the sample apps included in the SDK also demonstrate the event handling lifecycle.
  1. Specify the entitlement ID (GDApplicationID) and entitlement version (GDApplicationVersion) in the Info.plist file. See Using an entitlement ID and version to uniquely identify a BlackBerry Dynamics app.
  2. In the info.plist file of the app, add a dictionary entry with the name BlackBerryDynamics. For the value, add another dictionary entry containing a single entry with the key CheckEventReceiver and its Boolean value set to NO.
    <plist version="1.0">
        <dict>
        ...
            <key>BlackBerryDynamics</key>
            <dict>
                <key>CheckEventReceiver</key>
                <false/>
            </dict>
        ...
        </dict>
    </plist>
  3. Import GDiOS.h and GDState.h. This example relies on a boolean variable named 'hasAuthorized'. An alternative approach is to declare the variable in your project's .m file.

    Objective-C:

    // AppDelegate.h
    #import <UIKit/UIKit.h>
    #import <GD/GDiOS.h>
    #import <GD/GDState.h>
        
    @interface AppDelegate : UIResponder <UIApplicationDelegate> {
        BOOL hasAuthorized;
    }
        
    @property (strong, nonatomic) UIWindow *window;
        
    - (void)handleStateChange:(GDState *)state;
    - (void)onAuthorized;
    - (void)onNotAuthorized:(GDAppResultCode)code;
        
    @end

    Swift:

    class AppDelegate : UIResponder , UIApplicationDelegate,  GDiOSDelegate {
        var hasAuthorized: Bool = false
    }
  4. Make your AppDelegate an observer for state changing notifications.

    Objective-C:

    // AppDelegate.m
        
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        [self addStateObserverUsingNotificationCenter];
        hasAuthorized = NO;
        [[GDiOS sharedInstance] authorize];
            
        return YES;
    }
        
    #pragma mark - BlackBerry Dynamics observer for state changes (Notification Center)
        
    - (void)addStateObserverUsingNotificationCenter
    {
        // register to receive notification center notifications for GD state changes
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(receiveStateChangeNotification:) name:GDStateChangeNotification object:nil];
    }
        
    - (void) receiveStateChangeNotification:(NSNotification *) notification
    {
        if ([[notification name] isEqualToString:GDStateChangeNotification]) {
            NSDictionary* userInfo = [notification userInfo];
            NSString *propertyName = [userInfo objectForKey:GDStateChangeKeyProperty];
            GDState* state = [userInfo objectForKey:GDStateChangeKeyCopy];
                
            // For the purposes of this example, we want to log a different message so that it is known
            // these calls are coming from Notification Center
            if ([propertyName isEqualToString:GDKeyIsAuthorized]) {
                NSLog(@"receiveStateChangeNotification - isAuthorized: %@", state.isAuthorized ? @"true" : @"false");
                [self handleStateChange:state];
                    
            } else if ([propertyName isEqualToString:GDKeyReasonNotAuthorized]) {
                NSLog(@"receiveStateChangeNotification - reasonNotAuthorized: %ld", (long) state.reasonNotAuthorized);
                    
            } else if ([propertyName isEqualToString:GDKeyUserInterfaceState]) {
                NSLog(@"receiveStateChangeNotification - userInterfaceState: %ld", (long) state.userInterfaceState);
                    
            } else if ([propertyName isEqualToString:GDKeyCurrentScreen]) {
                NSLog(@"receiveStateChangeNotification - currentScreen: %ld", (long) state.currentScreen);
            }
        }
    }

    Swift:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        //Register for notifications from Blackberry Dynamics
        NotificationCenter.default.addObserver(self, selector: #selector(receiveStateChangeNotification(_:)), name: Notification.Name.GDStateChange, object: nil)
    
        hasAuthorized = false
        
        //Call BlackBerry Dynamics to authorise the app
        GDiOS.sharedInstance().authorize()
        
        return true
    }
    
    @objc func receiveStateChangeNotification(_ notification: NSNotification) {
        if (notification.name == Notification.Name.GDStateChange) {
            let userInfo = notification.userInfo
            let propertyName = userInfo?[GDStateChangeKeyProperty] as! String
            let state = userInfo?[GDStateChangeKeyCopy] as! GDState
            
            // For the purposes of this example, we want to log a different message so that it is known
            // these calls are coming from Notification Center
            if (propertyName == GDKeyIsAuthorized) {
                print("receiveStateChangeNotification - isAuthorized: \(state.isAuthorized)")
                handleStateChange(state)
            } else if (propertyName == GDKeyReasonNotAuthorized) {
                print("receiveStateChangeNotification - reasonNotAuthorized: \(state.reasonNotAuthorized)")
            } else if (propertyName == GDKeyUserInterfaceState) {
                print("receiveStateChangeNotification - userInterfaceState: \(state.userInterfaceState)")
            } else if (propertyName == GDKeyCurrentScreen) {
                print("receiveStateChangeNotification - currentScreen: \(state.currentScreen)")
            }
        }
    }
  5. Use GDState to handle the state of the BlackBerry Dynamics Runtime.

    Objective-C:

    // AppDelegate.m
        
    #pragma mark - Good Dynamics handler methods for state changes
        
    - (void)handleStateChange:(GDState *)state
    {
        if (state.isAuthorized) {
            NSLog(@"gdState: authorized");
            [self onAuthorized];
                
        } else {
            GDAppResultCode errorCode = [state reasonNotAuthorized];
            NSLog(@"gdState: not authorized, error:%ld", (long) errorCode);
            [self onNotAuthorized:errorCode];
                
        }
    }
        
    - (void)onAuthorized
    {
        if (!hasAuthorized) {
            // launch application UI here
            hasAuthorized = YES;
               
        }
    }
        
    - (void)onNotAuthorized:(GDAppResultCode)code
    {
        /* Handle the Good Libraries not authorized event. */
            
        switch (code)
        {
            case GDErrorActivationFailed:
            case GDErrorProvisioningFailed:
            case GDErrorPushConnectionTimeout:
            case GDErrorSecurityError:
            case GDErrorAppDenied:
            case GDErrorAppVersionNotEntitled:
            case GDErrorBlocked:
            case GDErrorWiped:
            case GDErrorRemoteLockout:
            case GDErrorPasswordChangeRequired:
            {
                // an condition has occured denying authorization, an application may wish to log these events
                NSLog(@"gdState: not authorized, error:%ld", (long) code);
                break;
            }
            case GDErrorIdleLockout:
            {
                // idle lockout is benign & informational
                break;
            }
            default:
                NSAssert(false, @"Unhandled not authorized event");
                break;
        }
    }

    Swift:

    func handleStateChange(_ state: GDState) {
        if state.isAuthorized {
            print("gdState: authorized");
            onAuthorized()
        } else {
            print("gdState: not authorized, error \(state.reasonNotAuthorized)");
            onNotAuthorized(errorCode: state.reasonNotAuthorized)
        }
    }
    
    
    func onAuthorized() {
        // Handle the Good Libraries authorized event
        if (!hasAuthorized) {
            // launch application UI here
            hasAuthorized = true
    
        }
    }
    
    
    func onNotAuthorized(errorCode: GDAppResultCode) {
        // Handle the Good Libraries not authorized event
        switch errorCode {
        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:
            // an condition has occured denying authorization, an application may wish to log these events
            print("gdState: not authorized, error \(errorCode)")
        case .errorIdleLockout:
            // idle lockout is benign & informational
            break
        default: assert(false, "Unhandled not authorized event");
        }
    }