• BlackBerry Dynamics
  • Runtime library for iOS applications
  • 12.0.1.79
Application User Interface Restrictions

The BlackBerry Dynamics runtime monitors the application user interface in order to enforce a number of enterprise security policies. For example, there may be a policy that the user must always enter their security password when the application makes the transition from background to foreground. There may also be a policy that the user interface must be locked after a period of inactivity.

The application user interface must observe a number of restrictions in order to enable monitoring by the runtime. The application code mustn't depend on having control of the user interface at all times.

User interface control

BlackBerry Dynamics will, from time to time, take control of the application user interface. It does this in order to enforce enterprise security policies. A BlackBerry Dynamics application's user interface (UI) is divided into the following parts, for the purposes of control.

Runtime UI. The screens and other user interface elements that are built in to the BlackBerry Dynamics runtime. This includes the screens on which the end user sets and enters their security password, for example.

Application UI. All user interface elements that aren't part of the runtime UI, above. These could be defined in the application code or in another third party library, for example.

When BlackBerry Dynamics takes control of the user interface, the runtime UI is displayed in front of the application UI, which is therefore hidden.

User interface programming

If the application UI is in front, general user interface programming features can be used, with the following restrictions.

  • The application mustn't close nor release the application window.
  • Access to the application window must be via the window property of the main app delegate, see under Access to the application window, below.
  • Programming with multiple windows isn't supported.

If the runtime UI is in front:

  • The application code can create new UI elements but:
    • These elements will be hidden, like the rest of the application UI.
    • It has been found that elements of the native UI programming interface, Cocoa Touch, can have unexpected and undocumented behaviours when hidden. For this reason, it may be best to avoid UI programming if the runtime UI is in front. See below for how to monitor which UI is in front.
  • The application code can remove and destroy elements of the application UI, in the usual way.
  • Restrictions that apply when the application UI is in front, see above, also apply.

The runtime UI will only stay in front for as long as is necessary to enforce enterprise policies. For example, if the user is required by policy to enter their password then the runtime UI will stay in front until they have done so. After that, the runtime UI will be removed and the application UI will be revealed.

The application code can monitor which UI is in front, see the code snippets for Monitoring user interface control, below.

Access to the application window

The main UIApplication instance and the main app delegate have a number of window properties whose values are modified by BlackBerry Dynamics. Supported use is as follows.

  • Main app delegate window property.
    Use this property to obtain a window object, UIWindow instance, in which to display the application UI. The object will be suitable to have its root view controller set to the initial view controller of the main storyboard, for example. See under Instantiating the application user interface, below, for sample code.
  • UIApplication keyWindow property.
    Don't use this property to obtain a reference to the application window. It will sometimes refer to an element in the runtime UI. Elements of the runtime UI mustn't be modified nor operated upon by the application code.
  • UIApplication windows property.
    Don't use this property to obtain a reference to the application window. The value of this property will be an array of window objects, some of which will be part of the runtime UI. Elements of the runtime UI mustn't be modified nor operated upon by the application code.

Code Snippets

The following code snippets illustrate some common tasks.

Instantiating the application user interface

The following code snippet shows an approach, sometimes known as programmatic storyboard loading, to instantiation of the application user interface.

// Call this when the end user is authorized, i.e. in the handling of one of:
// - GDStateChangeNotification in which GDState isAuthorized became true
// for the first time.
// - First GDAppEvent with type GDAppEventAuthorized.
- (void)instantiateUI {
// Only initialize the UI once.
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// Instantiate the Main storyboard.
UIStoryboard *uiStoryboard = [UIStoryboard storyboardWithName:@"Main"
bundle:nil];
// Instantiate the intial view controller.
UIViewController *viewController =
[uiStoryboard instantiateInitialViewController];
// Set the root view controller of the application window to the initial
// view controller so that the Main storyboard gets loaded.
[UIApplication sharedApplication].delegate.window.rootViewController =
viewController;
});
}

The above snippet illustrates the following approach.

  • The application has a first or only storyboard, named Main.
  • No main storyboard is configured for automatic loading, i.e. there isn't a UIMainStoryboardFile property in the Info.plist file (not shown in the snippet).
  • The application code initiates BlackBerry Dynamics authorization of the end user in its didFinishLaunchingWithOptions: implementation (not shown in the snippet).
  • When authorization of the end user is notified, the application instantiates its main storyboard, and the corresponding intial view controller, and sets it as the root view controller so that the storyboard gets loaded.

Monitoring user interface control with native notification

The following code snippets shows how to monitor user interface control by using the native notification mechanism, NSNotification.

// Register an observer.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(gdStateChanged:)
object:nil];
// Method invoked on state change.
- (void)gdStateChanged:(NSNotification*)notification
{
NSDictionary* userInfo = [notification userInfo];
NSString *propertyName = [userInfo objectForKey:GDStateChangeKeyProperty];
GDState* state = [userInfo objectForKey:GDStateChangeKeyCopy];
// User Interface state and Current Screen
if ([propertyName isEqualToString:GDKeyUserInterfaceState])
{
// ToDo: User interface changed - inspect ‘state.userInterfaceState’
}
else if ([propertyName isEqualToString:GDKeyIsAuthorized])
{
// Authorization state changed - inspect ‘state.isAuthorized’
if (state.isAuthorized) [self instantiateUI];
}
// Note: can also be used to receive notification of change in current
// screen and 'reasonNotAuthorized':
// GDKeyCurrentScreen - inspect ‘state.currentScreen’
// GDKeyReasonNotAuthorized - inspect ‘state.reasonNotAuthorized’
}

The above snippet illustrates the following.

  • The BlackBerry Dynamics runtime will dispatch an NSNotification when its state changes. The constant GDStateChangeNotification gives the name of the notification.
  • The application code can register to receive the state-change notification using the native programming interface, for example NSNotificationCenter addObserver.
  • The control state can be checked by inspecting the GDiOS.state object, which will be an instance of the GDState class. The userInterfaceState property will have the value GDUIStateGDLibraryInFront if the runtime UI is in front.
See also
GDState class reference.

Monitoring user interface control with key-value observing

The following code snippets shows how to monitor user interface control by using key-value observing (KVO).

// Get a reference to the GDState object from the singleton GDiOS instance.
GDState *state = [GDiOS sharedInstance].state;
// Register KVO observers.
NSKeyValueObservingOptions keyValueOptions =
(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld);
[state addObserver:self
options:keyValueOptions
context:NULL];
[state addObserver:self
forKeyPath:GDKeyIsAuthorized
options:keyValueOptions
context:NULL];
// Note: GDState also allows observation of the following key paths:
// - GDKeyCurrentScreen.
// - GDKeyReasonNotAuthorized.
// Implement KVO method.
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqualToString:GDKeyUserInterfaceState]) {
[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
}
else if ([keyPath isEqualToString:GDKeyIsAuthorized]) {
BOOL isAuthorized = (BOOL)
[[change objectForKey:NSKeyValueChangeNewKey] boolValue];
if(isAuthorized) [self instantiateUI];
}
else {
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
// Note: can also be used to monitor change in current screen and
// 'reasonNotAuthorized':
// GDKeyCurrentScreen - GDLibraryScreen
// GDKeyReasonNotAuthorized - NSString
}

The above snippet illustrates the following.

  • The BlackBerry Dynamics programming interface includes objects with properties that comply with KVO. One example is the GDiOS.state object, which will be an instance of the GDState class.
  • The application code can register observers for these properties using the native programming interface, for example NSObject addObserver.
  • The control state can be checked by observing the property with the key path given by the GDKeyUserInterfaceState constant, which will be the GDState userInterfaceState property. It will take the value GDUIStateGDLibraryInFront if the runtime UI is in front.
See also
GDState class reference.
GDiOS
BlackBerry Dynamics Runtime object interface, including authorization.
Definition: GDiOS.h:271
GDStateChangeKeyProperty
NSString *const GDStateChangeKeyProperty
Key in the NSNotification userInfo dictionary for the name of the property that changed.
GDUserInterfaceState
GDUserInterfaceState
User interface states.
Definition: GDState.h:173
GDKeyIsAuthorized
NSString *const GDKeyIsAuthorized
Path for KVO of the GDState isAuthorized property.
GDState::isAuthorized
BOOL isAuthorized
BlackBerry Dynamics authorization state.
Definition: GDState.h:348
GDKeyUserInterfaceState
NSString *const GDKeyUserInterfaceState
Path for KVO of the GDState userInterfaceState property.
GDStateChangeKeyCopy
NSString *const GDStateChangeKeyCopy
Key in the NSNotification userInfo dictionary for the as-after copy of the GDState object.
GDState
BlackBerry Dynamics run-time state.
Definition: GDState.h:322
GDStateChangeNotification
NSString *const GDStateChangeNotification
NSNotification name for GDState change notifications.