Implement In-App Messaging on iOS

To use certain in-app messaging features, such as button actions, some SDK configurations are needed. The following sections describe these configurations.

Enable In-App Module 

To enable and configure In-App Messaging, extend the initialization code described in the Configure the SDK section. The code example shows how to enable the In-App module for the iOS SDK.

SDK for iOS
1func configureSdk() -> Bool {
2 
3     ...
4 
5     // InAppMessageFeatureConfiguration
6     let iamFeatureConfiguration = InAppMessagingFeatureConfigBuilder()
7         .setEventDelegate(self)
8         .setURLHandlingDelegate(self)
9         .setInAppMessageFont(name: "HelveticaNeue")
10         .build()
11     configBuilder = configBuilder
12         .setInAppMessagingFeature(config: iamFeatureConfiguration)
13 
14     // Set the completion handler to take action when all modules initialization is completed.
15     // Seting the completion handler is optional.
16 
17     let completionHandler: ((_ status: [ModuleInitStatus]) -> Void) = { [weak self] status in
18         DispatchQueue.main.async {
19             self?.handleSDKInitializationCompletion(status: status)
20         }
21     }
22 
23     SFMCSdk.initializeSdk(configBuilder.build(), completion: completionHandler)
24 
25     return true
26 }
27 
28 // MARK: - SDK Initialization Completion Handler
29 
30 private func handleSDKInitializationCompletion(status: [ModuleInitStatus]) {
31     var allSuccessful = true
32 
33     for moduleStatus in status {
34         print("Module: \(moduleStatus.moduleName.rawValue), Status: \(moduleStatus.initStatus.rawValue)")
35 
36         if moduleStatus.initStatus == .success {
37             // Handle successful initialization for each module
38             switch moduleStatus.moduleName {
39             case .engagement:
40                 // Handle successful initialization for Marketing cloud module
41             case .pushFeature:
42                 // Handle successful initialization for Push Feature module
43             case .inappMessagingFeature:
44                 // Handle successful initialization for In-App Feature module
45             default:
46                 break
47             }
48         } else if moduleStatus.initStatus == .error {
49             allSuccessful = false
50             // module failed to initialize, check logs for more details
51         } else if moduleStatus.initStatus == .cancelled {
52             allSuccessful = false
53             // module initialization was cancelled (for example due to re-confirguration triggered before init was completed)
54         } else if moduleStatus.initStatus == .timeout {
55             allSuccessful = false
56             // module failed to initialize due to timeout, check logs for more details
57         }
58     }
59     if allSuccessful {
60         print("SDK initialization completed successfully")
61     } else {
62         print("SDK initialization completed with errors - check logs above")
63     }
64  }

Required Methods for Button Actions 

The SDK handles actions for Notification Settings and Location Settings, while actions for Web URL and App URL require that you implement URL handling.

Optional Methods 

To control aspects of message display and to get information about the in-app message display lifecycle, use the SDK’s optional delegate functionality.

setEventDelegate 

To make your application a delegate of the SDK’s in-app messaging functionality, use setEventDelegate, as shown in these examples.

This code example shows how to set the event delegate using the SDK.

1// adhere to the InAppMessageEventDelegate protocol in your class declaration
2class MyViewController: UIViewController, InAppMessageEventDelegate
3...
4// somewhere in your implementation, set your class as the delegate of the SDK for In-App Message events
5// this should be done early in your class’s initialization, if possible
6InAppMessagingFeature.requestSdk { iam in
7  iam?.setEventDelegate(self)
8}

didShow and didClose 

The didShow and didClose delegate methods help ensure that you can appropriately manage your app’s view state. In-app messages are shown as the top view controller in your app’s hierarchy. Your application must be able to respond to a view appearing or disappearing.

1func didShow(inAppMessage message: InAppMessageDetails) {
2    // message shown
3}
4
5func didClose(inAppMessage message: InAppMessageDetails, action: InAppMessageCloseAction) {
6    // message closed
7}

Prevent or Delay Message Display 

You can delay or prevent an in-app message’s display using the shouldShow method. For example, you can choose to prevent an in-app message from displaying during the loading process, sign-in flow, and other situations. To prevent or delay message display, set the shouldShow method to return false.

1func shouldShow(inAppMessage message: InAppMessageDetails) -> Bool {
2    // using your app's logic, can this message be shown?
3    if (self.messageCanBeShown) {
4        return true
5    }
6    else {
7        // capture the message id in the event
8        self.showMessageId = message.id
9    }
10    return false
11}

Furthermore, you can capture in-app message data and use it for displaying the specific message at a later time. For example, you can present the message after an end user has successfully signed in.

The message ID is accessed directly via the InAppMessageDetails object within the delegate, and the display is triggered through the InAppMessagingFeature module. Use these methods:

  • message.id (property of InAppMessageDetails)
  • showInAppMessage
1// if you've previously captured the messageId, you can show the In-App Message later
2// (for instance, you've returned false from shouldShow(inAppMessage message: InAppMessageDetails) because
3// your UI or application logic couldn’t be interrupted)
4if (self.showMessageId != nil) {
5    InAppMessagingFeature.requestSdk { iam in
6        iam?.showInAppMessage(messageId: self.showMessageId)
7    }
8}

Configure Push Permission Authorization 

When a Push Primer is displayed and the user taps the permission button, the SDK triggers the standard iOS notification authorization request.

To customize which permissions are requested (such as alerts, sounds, or badges), use the setNotificationAuthorizationOptions method during SDK initialization.

:::note If you do not explicitly configure these options, the SDK defaults to requesting .alert, .sound, and .badge. :::

The code example shows how to configure push permission authorization for the iOS SDK.

SDK for iOS
1func configureSdk() -> Bool {
2
3    ...
4
5    // InAppMessageFeatureConfiguration
6    let iamFeatureConfiguration = InAppMessagingFeatureConfigBuilder()
7        .setEventDelegate(self)
8        .setURLHandlingDelegate(self)
9        .setInAppMessageFont(name: "HelveticaNeue")
10        .setNotificationAuthorizationOptions([.alert, .sound])
11        .build()
12    configBuilder = configBuilder
13        .setInAppMessagingFeature(config: iamFeatureConfiguration)
14
15    ...
16}

Customize Display 

By default, in-app messages use your device’s system font. However, you can override the default font face to customize the appearance of an in-app message’s title, body, button, and tertiary text labels.

You can’t change the font size because it’s defined by the design of the message.

Note

To set the display font, use the setInAppMessageFont method to pass the SDK a valid font name for the device’s installed fonts, or your app’s custom fonts.

1InAppMessagingFeature.requestSdk { iam in
2    iam?.setInAppMessageFont(name: "Zapfino")
3}

If the font is invalid, the SDK returns false and reverts to using the system font.