While the Airship SDK provides built-in Message Center UI, sometimes it can be useful to create a custom implementation that bypasses the default implementation’s view hierarchy. Message Center messages are just HTML, and so they can be displayed in any webview. However, there are a few integration steps needed to ensure that authorization and the Native Bridge function properly.
Authentication and Loading
Message Center messages are fetched with basic authentication using the UAUser
credentials
in base64 encoding. This class persists a unique username and password on the iOS Keychain,
and provides easy access to the information at runtime without needing to deal with the Keychain
directly.
The example below shows how to fetch the credentials, set auth on the request, and load a
message into the webview. This code assumes a custom view controller with an embedded
WKWebView
, as well as a UAInboxMessage
ready to be loaded.
NSMutableURLRequest *requestObj = [NSMutableURLRequest requestWithURL:self.message.messageBodyURL];
UA_WEAKIFY(self)
[[UAMessageCenter shared].user getUserData:^(UAUserData *userData) {
UA_STRONGIFY(self)
// set the auth
NSString *auth = [UAUtils authHeaderStringWithName:userData.username password:userData.password];
[requestObj setValue:auth forHTTPHeaderField:@"Authorization"];
// load the request
[self.webView loadRequest:requestObj];
} queue:dispatch_get_main_queue()];
let requestObj = NSMutableURLRequest(url:self.message.messageURL)
UAMessageCenter.shared().user.getData({ (data: UAUserData) in
// set the auth
let auth = UAUtils.authHeaderString(withName: data.username, password: data.password)
requestObj.setValue(auth, forHTTPHeaderField:"Authorization")
// load the request
self.webView.load(requestObj)
}, queue: DispatchQueue.main)
Setting up the Native Bridge
The Airship Native bridge works by intercepting all links with the uairship://
scheme and translating
specially URL-encoded paths into native commands and arguments. In order to do this in a custom webview, the
view controller containing the webview (or whichever class acts as the WKNavigationDelegate
) must
delegate navigation handling to the Native Bridge. To continue to receive these events, the original
delegate can sign up as a “forward delegate”, by implementing the WKNavigationDelegate
protocol. This
allows the Native Bridge to forward WKNavigationDelegate
calls to the original delegate.
The example code below shows how to do this, and assumes both native bridge property in the view controller,
and the view controller implement WKNavigationDelegate
- (void)viewDidLoad {
[super viewDidLoad];
// allow native bridge to intercept links
self.nativeBridge = [[UANativeBridge alloc] init];
self.webView.navigationDelegate = self.nativeBridge;
// forward navigation events back to self
self.nativeBridge.forwardDelegate = self;
...
}
override func viewDidLoad() {
super.viewDidLoad()
// allow native bridge to intercept links
self.nativeBridge = UANativeBridge()
self.webView.navigationDelegate = self.nativeBridge
// forward navigation events back to self
self.nativeBridge.forwardDelegate = self
}
Enabling the Close Command
Among other commands, the Native Bridge also exposes a UAirship.close()
command to the JavaScript layer,
which makes it possible for elements or JavaScript routines in the message to close the containing message
view. This is optional functionality, but if you would like to add this capability to your app,
you will need to implement an additional UANativeBridgeDelegate
method in the view controller containing
your webview.
- (void)closeWindowAnimated:(BOOL)animated {
// dismiss the webview here
}
override func closeWindow(animated: Bool) {
// dismiss the webview here
}