In-App messages

Introduction

In-App messages are notifications, in various formats, that your application can display while users are browsing within your application. These messages can be targeted just like Push Notifications. It can be triggered in real time based on the user behaviour and their events (see event tracking). It also can be displayed in specific parts of your app if need be.

Their purpose is to stimulate a certain behaviour from your users, as they are probably just a click away from this behaviour, while push notifications primary objective is to drive users back inside the app.

Basic display

In-App messages can appear in various formats (banners, interstitials, native alert-box...) and be composed of simple text, or html content. You can customize the design of their templates, and you can adapt their content remotely thanks to the Accengage dashboard.

Once a user clicks on the In-App message, you can decide of various actions to trigger, such as redirect to a deep link, a landing page, send an email etc... The Accengage SDK allows the display of In-App messages very simply. There is no additional code to write to support In-App messages.

There are six different default In-App messages templates:

  • Text Banner: this In-App notification will appear as a view with a height of 50. It will contain a title and a text body. By default this banner will appear at the bottom of the page. The color of the background is black and text is white.
  • WebView Banner: this In-App message will appear as a view with a height of 50. It will contain a webView that will display the content of a URL. By default this banner will appear at the bottom of the page. The color of the background is black by default.
  • Text Interstitial: this In-App notification will appear in full screen. It will contain a title and a text body.
  • WebView Interstitial: this In-App notification will appear in full screen. It will contain a WebView that will display the content of an URL and which will be clickable.
  • WebView interstitial with NavBar: this In-App message will appear in full screen. It will contain a webView that will display the content of a URL. It also displays a navigation bar and can be browsed.
  • Native Alertbox: this In-App message is displayed as a native alertbox. It freezes the navigation, and contains, a title, a content, and can propose 1 to X buttons.

If you are wondering how to set up In-App campaigns, please find our tutorial about it.

Advanced display customization

In the sections below, you will see how to:

  • Customize the behaviour and appearance of those In-App messages
  • Prevent them from being displayed in irrelevant moments (such as splash screen, purchase funnel...)
  • Transmit custom parameters to your app or analytics when these In-App messages are displayed or clicked

In-App messages display customization

The Accengage SDK lets you customize many aspects of the In-App messages, such as the design, format, size of the templates, their position within a view, the display animation etc...

Please read the following to craft the best experience for your users.

Xib files

The In-App messages views are created using xib files that are provided with the SDK. The content that you will create remotely within the Accengage dashboard (Actions > In-App messages) will be displayed within these views.

You can modify those xib files (add other elements, change color, font etc...) or preferably add new xib files, as long as you keep the tag info.

5 xib files are provided for iPhone retina 3″5 portrait:

  • Text notification: BMA4SiPhoneTextNotifView
  • WebView notification: BMA4SiPhoneWebViewNotifView
  • Interstitial text notification: BMA4SiPhoneIntersticialTextNotifView
  • Interstitial webView notification: BMA4SiPhoneIntersticialWebViewNotifView
  • Interstitial webView notification (with navBar): BMA4SiPhoneIntersticialWebViewWithToolBarNotifView

These 5 files are also replicated for:

  • iPhone Landscape:

    • Landscape: with suffix -landscape
  • iPad:

    • Portrait: with suffix -iPad
    • Landscape: with suffix -landscape-iPad

To choose a custom position of an overlay In-App, add transitions animations and more, you need to set an In-App message data source object. Your object must adopt the BMA4SInAppNotificationDataSource protocol.

Objective-C:

[BMA4SInAppNotification setDataSource:yourObject];

Swift:

BMA4SInAppNotification.dataSource = yourObject

In-App view edition

By default the SDK loads the view from the XIB file. You can customize the loaded view programmatically.

Objective-C

- (UIView *)BMA4SViewForInAppMessage:(BMA4SInAppMessage *)message
                         defaultView:(UIView *)view {
    NSString *radiusString = message.displayCustomParams[@"radius"];
    if (radiusString) {
        view.layer.cornerRadius = radiusString.floatValue;
    }
    return view;
}

Swift:

func bma4SViewFor(_ message: BMA4SInAppMessage?, defaultView view: UIView?) -> UIView? {
    let radiusString = message?.displayCustomParams["radius"]
    if radiusString != nil {
        view?.layer.cornerRadius = CGFloat(Float(radiusString ?? "") ?? 0.0)
    }
    return view
}

You can also create the In-App message view programmatically. To do this you need to respect the following requirements.

First of all, there are two types of inApp messages: TextMessage & WebMessage . You can check the type by this way:

Objective-C:

- (UIView *)BMA4SViewForInAppMessage:(BMA4SInAppMessage *)message
                         defaultView:(UIView *)view {
    if ([message isKindOfClass:[BMA4SInAppTextMessage class]]) {
        // Some code ...
    }
    else if ([message isKindOfClass:[BMA4SInAppWebMessage class]]) {
        // Some code ...
    }
}

Swift:

func bma4SViewFor(_ message: BMA4SInAppMessage?, defaultView view: UIView?) -> UIView? {
    if (message is BMA4SInAppTextMessage) {
        // Some code ...
    } else if (message is BMA4SInAppWebMessage) {
        // Some code ...
    }
}

Here is the list of the subviews of each message type:

BMA4SInAppTextMessage:

  • Text label: UILabel with tag BMA4SInAppOverlayViewBodyTag (required)
  • Close button: UIButton with tag BMA4SInAppOverlayViewCloseTag (optional)

BMA4SInAppWebMessage:

  • Web view: ACCWKWebView with tag BMA4SInAppOverlayViewBodyTag (required)
  • Close button: UIButton with tag BMA4SInAppOverlayViewCloseTag (optional)
  • Go Back Button: UIButton with tag BMA4SInAppOverlayViewBackTag (optional)
  • Go Forward Button: UIButton with tag BMA4SInAppOverlayViewForwardTag (optional)
  • Reload Button: UIButton with tag BMA4SInAppOverlayViewReloadTag (optional)
  • Stop loading Button: UIButton with tag BMA4SInAppOverlayViewStopTag (optional)
  • Open in Safari Button: UIButton with tag BMA4SInAppOverlayViewSafariTag (optional)
  • Loader: UIActivityIndicatorView with tag BMA4SInAppOverlayViewActivityTag (optional)
  • Toolbar: UIToolbar with tag BMA4SInAppOverlayViewToolbarTag (optional)

Objective-C:

- (UIView *)BMA4SViewForInAppMessage:(BMA4SInAppMessage *)message
                               defaultView:(UIView *)view {
        if ([message isKindOfClass:[BMA4SInAppTextMessage class]]) {
          BMA4SInAppView *customView = [[BMA4SInAppView alloc] initWithFrame:CGRectInset(view.frame, 20, 0)];
          customView.layer.masksToBounds = YES;
          customView.layer.cornerRadius = 5.;
          customView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];
          customView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

          // Set auto sizing disabled
          customView.autosizingDisabled = YES;

          UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(customView.bounds, 10, 10)];
          label.backgroundColor = [UIColor clearColor];
          label.textColor = [UIColor whiteColor];
          label.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
          label.tag = BMA4SInAppOverlayViewBodyTag;
          label.text = [(BMA4SInAppTextMessage*)message body];
          label.numberOfLines = 0;

          UIButton *close = [UIButton buttonWithType:UIButtonTypeCustom];
          close.frame = customView.bounds;
          close.tag = BMA4SInAppOverlayViewCloseTag;

          [customView addSubview:label];
          [customView addSubview:close];
          return customView;
        }

      return view;
    }
}

Changing the default position of an overlay In-App

By default, In-App banners are displayed at the bottom of the screen.

Each time the SDK will show an overlay In-App, your data source object will be asked to return a BMA4SOverlayInAppPosition option.

Objective-C:

- (BMA4SOverlayInAppPosition)BMA4SOverlayInAppMessagePosition:(BMA4SInAppMessage *)message
                                                         size:(CGSize)templateSize {
    if ([message.templateNibName isEqualToString:@"BMA4SiPhoneTextNotifView"]) {
        return BMA4SOverlayInAppPositionCustom;
    }
    if (templateSize.height == templateSize.width) {
        return BMA4SOverlayInAppPositionCenterLeft;
    }
    return BMA4SOverlayInAppPositionDefault;
}

If your data source object returned BMA4SOverlayInAppPositionCustom option, it will be asked to return the origin point of the In-App view.

Objective-C:

- (CGPoint)BMA4SOverlayInAppMessageCustomPosition:(BMA4SInAppMessage *)message
                                             size:(CGSize)templateSize
    if ([message.templateNibName isEqualToString:@"BMA4SiPhoneTextNotifView"]) {
        return CGPointMake(0, 66);
    }

    return CGPointZero;
}

Animated transitions

By default, the SDK applies a Fadein animation when In-App messages are displayed. You can disable the default animation for a specific In-App message or for all In-App messages by implementing this method:

Objective-C:

- (BOOL)BMA4SEnableDefaultDisplayAnimationForInAppMessage:(BMA4SInAppMessage*)message {
    if ([message.templateNibName isEqualToString:@"BMA4SiPhoneTextNotifView"]) {
        return NO;
    }
    return YES;
}

You can also apply custom transition animations by implementing the following methods:

Objective-C:

/* Display animation */
- (void)BMA4SDidDisplayInAppMessage:(BMA4SInAppMessage *)message
                              view:(UIView *)view {
    // Save the inApp final frame
    CGRect frame = view.frame;

    // Change the frame
    view.frame = CGRectMake(0, -frame.size.height, frame.size.width, frame.size.height);

    // Apply your animation
    [UIView animateWithDuration:0.3
                     animations:^{
        view.frame = frame;
    }];
}

 - (void)BMA4SWillDismissInAppMessage:(BMA4SInAppMessage *)message
                                 view:(UIView *)view
                    completionHandler:(void (^)())completionHandler {

    [UIView animateWithDuration:0.3
                     animations:^{
        CGRect frame = view.frame;
        view.frame.origin.y = -frame.size.height;
        view.frame = frame;
    }
                     completion:^(BOOL finished) {
        // Call the completionHandler
        if (completionHandler) {
            completionHandler();
        }
    }];
 }

For more details, please check the BMA4SInAppNotificationDataSource documentation.

HTML5 video inline playback

Inline video playback is supported starting from version 6.4.1. To play a video inline, add a display custom parameter acc-inline-media to your In-App message.

Full In-App customization

Accengage dashboard and SDK allows you to create fully customized In-App messages. This sample shows how to use the custom parameters to achieve this.

On the SDK side, you can retrieve the parameters using the above mentioned BMA4SInAppNotificationDataSource callback method BMA4SViewForInAppMessage:defaultView:

The BMA4SInAppMessage object contains the following properties:

displayCustomParameters - parameters specified on the Accengage dashboard for a specific In-App message

clickCompletionHandler - block to execute when the user clicks on your custom In-App . You can also pass the button ID as a parameter if it corresponds to your use case.

displayCompletionHandler - block to execute when your custom In-App is displayed.

dismissCompletionHandler - block to execute when your custom In-App is dismissed.

Handling actions

In-App message observers

You can be notified when the SDK displays or closes an In-App message or when a user clicks on it.

You can add an observer like this:

Objective-C:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inAppNotifClicked:) name:BMA4SInAppNotification_Clicked object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inAppNotifDidAppear:) name:BMA4SInAppNotification_DidAppear object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inAppNotifClosed:) name:BMA4S_InAppNotification_Closed object:nil];
    //...
}

- (void) inAppNotifClicked:(NSNotification*) notif {
    NSLog(@"inApp Was Clicked : %@", notif.userInfo);
}

- (void) inAppNotifDidAppear:(NSNotification*) notif {
    NSLog(@"inApp Did Appear : %@", notif.userInfo);
}

- (void) inAppNotifClosed:(NSNotification*) notif {
    NSLog(@"inApp Was Closed : %@", notif.userInfo);
}

Swift:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    //...
    NotificationCenter.default.addObserver(self, selector: #selector(self.inAppNotifClicked(notification:)), name: Notification.Name(BMA4SInAppNotification_Clicked), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.inAppNotifDidAppear(notification:)), name: Notification.Name(BMA4SInAppNotification_DidAppear), object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.inAppNotifClosed(notification:)), name: Notification.Name(BMA4S_InAppNotification_Closed), object: nil)
    //...
}

@objc private func inAppNotifClicked(_ notification: Notification) {
    print("inApp Was Clicked : \(notif.userInfo));
}

@objc private func inAppNotifDidAppear(_ notification: Notification) {
    print("inApp Did Appear : \(notif.userInfo));
}

@objc private func inAppNotifClosed(_ notification: Notification) {
    print("inApp Was Closed : \(notif.userInfo));
}

Custom parameters

You can set up In-App messages in the Accengage dashboard so that custom parameters are transmitted to your application when the In-App message is displayed, or clicked.

This can be useful if you would like to redirect the user to a deep link, trigger a feature, or if you would like to transmit the information to your analytics.

You can be notified when the SDK sends data, by adding an observer like this:

Objective-C:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataAvailable:) name:BMA4S_InAppNotification_DataAvailable object:nil];
    ...
}

- (void) dataAvailable:(NSNotification*) notif {
    NSLog(@"Data Available : %@", notif.userInfo);
}

Swift:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    ...
    NotificationCenter.default.addObserver(self, selector: #selector(self.dataAvailable(notification:)), name: Notification.Name(BMA4S_InAppNotification_DataAvailable), object: nil)
    ...
}

@objc private func dataAvailable(_ notification: Notification) {
    print("dataAvailable : \(notif.userInfo));
}

You can also use the previously mentioned In-App message observers to extract custom parameters.

Prevent In-App message display

The Accengage SDK will display your In-App message as soon as all conditions you've specified in the Accengage dashboard are met. Therefore it can be useful sometimes to prevent the display of In-App messages, when it is irrelevant, for instance during the splash screen, if an ad is displayed, or if the user is performing a critical action.

For this reason, the Accengage SDK provides a "Lock" option.

You can prevent the display of any In-App message, by calling:

Objective-C:

[BMA4SInAppNotification setNotificationLock:YES];

Swift:

BMA4SInAppNotification.setNotificationLock(true)

To reenable the In-App messages, you can call:

Objective-C:

[BMA4SInAppNotification setNotificationLock:NO];

Swift:

BMA4SInAppNotification.setNotificationLock(false)