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
Message Center messages are fetched with basic authentication using the User
credentials
in base64 encoding. This class persists a unique username and password to the device, and provides
easy access to the information at runtime.
User user = MessageCenter().shared().getUser();
String username = user.getId();
String password = user.getPassword();
if (user.getId() != null && user.getPassword() != null) {
// set auth here
}
val user = MessageCenter().shared().user
val username = user.id
val password = user.password
if (user.id != null && user.password != null) {
// set auth here
}
We will look at a more detailed example in the context of a custom webView further below.
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. To do this in a custom web view, use
or extend the MessageWebViewClient
, which handles the injection of JavaScript and related lifecycle
callbacks.
Setting MessageWebViewClient and Loading A Message
The example below shows how to put these pieces together in the context of a custom WebView class. An
anonymous inner class extends MessageWebViewClient to pass along auth credentials from the User
public class MyWebView extends WebView {
private final MessageWebViewClient webViewClient = new MessageWebViewClient();
public void initClient() {
setWebViewClient(webViewClient);
}
// load a message with auth set in the headers
public void loadMessage(Message message) {
User user = MessageCenter.shared().getUser();
// Send authorization in the headers if the web view supports it
HashMap<String, String> headers = new HashMap<>();
if (user.getId() != null && user.getPassword() != null) {
webViewClient.addAuthRequestCredentials(message.getMessageBodyUrl(), user.getId(), user.getPassword());
headers.put("Authorization", createBasicAuth(user.getId(), user.getPassword()));
}
loadUrl(message.getMessageBodyUrl(), headers);
}
// helper method for creating base64-encoded, basic auth header values
private String createBasicAuth(@NonNull String userName, @NonNull String password) {
String credentials = userName + ":" + password;
return "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
}
}
class MyWebView(context: Context) : WebView(context) {
val messageWebViewClient = MessageWebViewClient()
init {
this.webViewClient = messageWebViewClient
}
// load a message with auth set in the headers
fun loadMessage(message: Message) {
val user = MessageCenter.shared().user
// Send authorization in the headers if the web view supports it
var headers: HashMap<String, String> = HashMap()
if (user.id != null && user.password != null) {
messageWebViewClient.addAuthRequestCredentials(message.messageBodyUrl, user.id, user.password)
headers["Authorization"] = createBasicAuth(user.id!!, user.password!!);
}
loadUrl(message.messageBodyUrl, headers)
}
// helper method for creating base64-encoded, basic auth header values
private fun createBasicAuth(userName: String, password: String): String {
val credentials: String = "$userName:$password"
return "Basic " + Base64.encodeToString(credentials.toByteArray(), Base64.NO_WRAP)
}
}