Documentation > iOS

In-App Messaging

Batch 1.10 introduces In-App Messaging

Requirements

In-App Messaging takes full advantage of mobile landings: if they are already working in your app, In-App Messaging should work out of the box.
Your app must have:

  • Batch SDK 1.10 or higher
  • A minimum iOS version of 8.0

Displaying In-App messages

Fully automatic mode

There is no code required to make In-App Messages work in automatic mode. Create some campaigns on your dashboard, and they will start coming up in your app.
If they don't, please head over to the troubleshooting section.

The automatic mode will only work properly if Batch is well integrated into ALL of your activities.

Controlling the display using "Do Not Disturb mode"

You can also get more control on when messages are displayed without giving up on the automatic mode, by using the "Do Not Disturb" (DnD) mode.
It allows you to tell Batch to hold on a mobile landing for you, rather than display it without using the fully manual mode.
For example, if launching your app results in a splash screen or a fullscreen ad, you might find it undesirable to have Batch display something on top of it.

Turning on "Do Not Disturb" mode will make Batch enqueue the latest mobile landing, rather than display it.

Toggling DnD

Now, when you don't want Batch to automatically display, turn on Do Not Disturb:

BatchMessaging.doNotDisturb = YES;
BatchMessaging.doNotDisturb = true

Once you want to start showing landings automatically, call the method with false to turn it off.

Note: Disabling Do Not Disturb mode does NOT make Batch show the enqueued message

Displaying pending mobile landings

After coming back from DnD mode, you might want to show the enqueued message, as Batch will not do that automatically. Batch exposes two properties/methods for managing the queue:

  • BatchMessaging.hasPendingMessage , allowing you to peek into the queue.
  • BatchMessaging.popPendingMessage() , allowing you to fetch the pending message (if any). Since calling this makes Batch delete its reference to it to save memory, further calls might return nil.
  • BatchMessaging.showPendingMessage() , allowing you to try to show the pending message, if any.

Here is a quick example of how they can be used:

- (void)splashScreenDidDisappear {
  BatchMessaging.doNotDisturb = NO;
  [BatchMessaging showPendingMessage];
}
func splashScreenDidDisappear() {
  BatchMessaging.doNotDisturb = false
  BatchMessaging.showPendingMessage()
}

Note: Only the latest message is queued: if a mobile landing arrives while one is still pending, it will overwrite the previous one.

Manual mode

Like Mobile Landings, you may want to take full control over how in-app messaging behaves. Batch allows you to disable automatic displaying, and handle that yourself. For compatibility reasons, BatchMessaging.setAutomaticMode(false) does not control this behavior like it does on mobile landings.

In order to handle messages yourself, you will have to implement a new method of the BatchMessagingDelegate protocol on your lifecycle delegate implementation.
By implementing this method, you opt-in to manual message handling, and showing them becomes your responsibility.

Here is an example:


// Application delegate

@property InAppMsgDelegate *inAppMsgDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.inAppMsgDelegate = [InAppMsgDelegate new];
  [BatchMessaging setDelegate:self.inAppMsgDelegate];
}

// InAppMsgDelegate implementation

@interface InAppMsgDelegate : NSObject <BatchMessagingDelegate>
@end

@implementation InAppMsgDelegate

- (void)batchInAppMessageReady:(nonnull BatchInAppMessage*)message
{
  // Sample implementation that prevents messages from being displayed if the logged in user isn't the right one
  // "loggedInUsername" is an hypothetical property that returns the logged in username as a string, if logged in
  if ([[UserManager loggedInUsername] isEqualToString:message.customPayload["username"]])
  {
    NSError *err;
    UIViewController *vc = [BatchMessaging loadViewControllerForMessage:message error:&err];
    if (vc)
    {
      // Present it
    }
    else
    {
      // Handle the error
    }
  }
}

@end


// Application delegate

var inAppMsgDelegate = InAppMsgDelegate()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  BatchMessaging.setDelegate(inAppMsgDelegate)
}

// InAppMsgDelegate implementation

@objc
class InAppMsgDelegate: NSObject, BatchMessagingDelegate {
    func batchInAppMessageReady(message: BatchInAppMessage) {
        // Sample implementation that prevents messages from being displayed if the logged in user isn't the right one
        // "loggedInUsername" is an hypothetical property that returns the logged in username as a string, if logged in
        if (UserManager.loggedInUsername == message.customPayload?["username"] as? String) {
            do {
                try BatchMessaging.loadViewController(for: message)
                // Present it
            } catch let error as NSError {
                // Handle the error
            }
        }
    }
}

Troubleshooting

In-App messages fail to show

This can come from multiple things:

  • Batch might not be able to display the message: make sure all of the prerequisites are satisfied by your app.
    If you have a non standard UI architecture.

  • The In-App campaign might not have been synchronized yet. Try to kill and restart your app: backgrounding it might not be enough.

  • If the trigger is "next session", you might just not have triggered a new session yet. Try killing (as in swiping it up on the task manager) and restarting the app, or wait 5 minutes with the app in the background.
    Restarting the app might be needed twice: once to sync the campaigns, and one to trigger the "next session" event.

  • If you triggered any In-App message, you will not be able to show another without waiting at least one minute between them.
    This might change into the future.

  • If an In-App message is triggered while a view controller is being dismissed (especially a modally presented one), showing the message can fail. You can try displaying it manually, or tracking the event that triggers an in-app message after the dismiss animation.

If that does not fix the problem, please check the logs in Xcode/Console.app and see if Batch or UIKit outputs anything.
If not, you can always contact our support team with information about your problem.