Contact usRequest a demo

Unblu iOS mobile SDK: migrating from version 3 to version 4

When you migrate from version 3 to version 4 of the Unblu mobile SDK, you have to make a number of changes to your code.

This article describes the changes for iOS. For Android, refer to Unblu Android mobile SDK: migrating from version 3 to version 4.

Requirements

The minimum supported iOS version for the Unblu iOS mobile SDK version 4 is iOS 13. If your project uses an iOS version below this, you will need to update your project to iOS version 13.0 or newer. The Unblu iOS mobile SDK will not be able to run otherwise.

The minimum supported Unblu Collaboration Server version is 7.x.x.

Installation

In version 3 of the iOS SDK, there were individual frameworks for visitor and agent functionality. In version 4, this is no longer the case. Instead, the functionality of these frameworks is bundled in the UnbluCoreSDK framework. You must therefore remove any imports of the frameworks that are no longer available.

We also recommend that you clean your Xcode project after this to make sure references are updated.

To install the Unblu iOS mobile SDK, drag the XCFrameworks you require into your Xcode project, then add them to your target. The available XCFrameworks are

  • UnbluCallModule.xcframework

  • UnbluMobileCoBrowsingModule.xcframework

  • UnbluCoreSDK.xcframework

  • UnbluFirebaseNotificationModule.xcframework

  • UnbluVisitorSDK.xcframework

When copying the XCFrameworks into your project, make sure to check the box Copy items if needed.

Initializing Unblu

The way Unblu is initialized and configured has changed in version 4.

  • The Unblu instance is no longer accessible via a singleton .instance property. Instead, you must create the Unblu instance and manage its lifecycle yourself.

  • The configuration object needed to initialize the Unblu instance is now called UnbluClientConfiguration. See below for further details.

Initializing Unblu therefore looks like the following code snippets:

Listing 1. Creating a configuration and initializing Unblu
// Version 3

let visitorConfig = UnbluApiConfiguration(...)
try? UnbluVisitorApi.instance.configureApi(configuration: visitorConfig)
UnbluVisitorApi.instance.<property_name>

let agentConfig = UnbluApiConfiguration(...)
try? UnbluAgentApi.instance.configureApi(configuration: agentConfig)
UnbluAgentApi.instance.<property_name>


// Version 4

let visitorConfig = UnbluClientConfiguration(...)
let unbluVisitor = Unblu.createVisitorClient(withConfiguration: visitorConfig)
unbluVisitor.<property_name>

let agentConfig = UnbluClientConfiguration(...)
let unbluAgent = Unblu.createAgentClient(withConfiguration: agentConfig)
unbluAgent.<property_name>

initApi() and deinitApi() are now called start and stop respectively.

Listing 2. Initializing and deinitializing Unblu
// Version 3
UnbluVisitorApi.instance.initApi(success: {

}) { (error) in

}

UnbluVisitorApi.instance.deinitApi()


// Version 4
unbluVisitor.start { result in
    // process the result
}

unbluVisitor.stop { result in
    // process the result
}

Configuring Unblu

As mentioned above, UnbluApiConfiguration is now called UnbluClientConfiguration.

The properties of the new object are largely the same as those of UnbluApiConfiguration, except with regard to the handling of external links.

The externalLinkPatternWhitelist property is no longer available on the configuration object. It has been superseded by the externalLinkHandler property and the new UnbluExternalLinkHandler protocol.

When you initialize UnbluClientConfiguration, you must provide an object that conforms to the UnbluExternalLinkHandler protocol. Unblu provides a default implementation of this protocol called UnbluDefaultExternalLinkHandler.

When a link is tapped in a conversation, Unblu calls the function decidePolicy(for: URL) → UnbluExternalLinkHandlingPolicy on the UnbluExternalLinkHandler. How Unblu proceeds depends on whether the function returns .open, .block, or .ignore.

UnbluClientConfiguration exposes the link handler via the new externalLinkHandler property.

For more information, please review the Unblu iOS mobile SDK reference entries of the following types:

UnbluView

In version 3 of the Unblu mobile SDK all Unblu UI content was rendered in a UIWindow that was managed internally by Unblu. To show the Unblu UI, you had to call showUi(true/false) explicitly.

Now, Unblu provides you with a subclass of UIView called UnbluView. The entire Unblu UI is rendered into this view.

Providing a UIView makes integrating Unblu into your application simpler and enables a greater degree of control over where the Unblu UI is displayed in your app.

The UnbluView is available as a view property on the Unblu client instance. A typical approach is to add the UnbluView to a UIViewController when viewDidLoad is called:

class MyViewController: UIViewController {

  var unbluVisitor: UnbluVisitorClient!

  override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(unbluVisitor.view)
  }
}

How you position the UnbluView within your app is entirely up to you. It supports autolayout constraints and/or setting the .frame property.

Show and hiding the Unblu UI

Because there is no longer a call to showUi(true/false), Unblu no longer knows for sure when it is visible in your app. It is important that Unblu knows this information in order to correctly display notifications.

The UnbluView itself tries to work out whether it is visible or not by reading its UIView.isHidden property. In some circumstances, however, this won’t be sufficient. For example, you might have another UIView on top of the UnbluView, thereby obscuring it from view.

In such a situation, we ask that you try as best you can to keep Unblu informed when the UnbluView is visible. There are two functions in the UnbluView that facilitate this:

In most circumstances it won’t be necessary to use these functions, but you should bear them in mind when integrating the UnbluView.

New type for conversations

In version 4 of the mobile SDK, there’s a new type, UnbluConversation, that represents a specific conversation. You can now always retrieve the current open conversation via the UnbluClient.openConversation property.

Additionally, when a conversation is opened or closed, Unblu calls the delegate function unblu(didChangeOpenConversation:).

Unblu events

Version 4 of the iOS mobile SDK no longer uses the NotificationCenter to dispatch events. Instead, events are dispatched using delegates that you can adopt and assign to your Unblu instance.

Contrast the following examples from version 3 and version 4:

Listing 3. Comparison of event dispatch in version 3 and version 4
// Version 3
NotificationCenter.default.addObserver(self, selector: #selector(...), name: .UnbluUiVisibilityRequest, object: UnbluVisitorApi.instance)

// Version 4
let unbluVisitor = Unblu.createVisitorClient(...)
unbluVisitor.visitorDelegate = <assign-your-delegate> (1)

class ExampleDelegate: UnbluVisitorClientDelegate {

  func unblu(didRequestShowUi reason: UnbluUiRequestReason, requestedByUser: Bool) {

  }
}
1 Replace <assign-your-delegate> with the delegate

Below is a list of the Notification types in version 3 and the functions provided by the delegate protocols in version 4 that replace them. For information on additional delegate protocols you can adopt, please refer to the iOS SDK reference documentation.

  • Notification.Name.UnbluApiIsInitialized

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unbluDidInitialize() {
        //...
      }
    
      func unbluDidDeinitialize() {
        //...
      }
    }
  • Notification.Name.UnbluUiReady

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unbluUiIsReady() {
        //...
      }
    }
  • Notification.Name.UnbluUiPreloaded

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unbluDidPreloadUi() {
        //...
      }
    }
  • Notification.Name.UnbluUnreadMessagesCountChanged

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didUpdateUnreadMessages count: Int) {
        //...
      }
    }
  • Notification.Name.UnbluPersonChanged

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didUpdatePersonInfo personInfo: PersonInfo) {
        //...
      }
    }
  • Notification.Name.UnbluError

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didReceiveError type: UnbluApiErrorType, description: String) {
        //...
      }
    }
  • Notification.Name.UnbluUiVisibilityTransition

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didTransitionUiWithTransition transition: UnbluUiVisibilityTransition) {
        //...
      }
    }
  • Notification.Name.UnbluUiOpenConversationChanged

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didChangeOpenConversation openConversation: UnbluConversation?) {
        //...
      }
    }
  • Notification.Name.UnbluUiVisibilityRequest

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didRequestShowUi reason: UnbluUiRequestReason, requestedByUser: Bool) {
        //...
      }
    }
  • Notification.Name.UnbluUiHideRequest

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didRequestHideUi reason: UnbluUiHideRequestReason, conversationId: String?) {
        //...
      }
    }
  • Notification.Name.UnbluUiCallUiOpenChanged

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didToggleCallUi isOpen: Bool) {
        //...
      }
    }
  • Notification.Name.UnbluAgentAvailable

    class ExampleDelegate: UnbluVisitorClientDelegate {
    
      func unblu(didUpdateAgentAvailability isAvailable: Bool) {
        //...
      }
    }
  • Notification.Name.UnbluMobileCoBrowsingChanged

    class ExampleDelegate: UnbluMobileCoBrowsingModuleDelegate {
    
      func unbluMobileCoBrowsingModuleDidStartCoBrowsing(_ unbluMobileCoBrowsingModuleApi: UnbluMobileCoBrowsingModuleApi) {
        //...
      }
    
      func unbluMobileCoBrowsingModuleDidStopCoBrowsing(_ unbluMobileCoBrowsingModuleApi: UnbluMobileCoBrowsingModuleApi) {
        //...
      }
    }
  • Notification.Name.UnbluCallActiveChanged

class ExampleDelegate: UnbluCallModuleDelegate {

  func unbluCallModuleDidStartCall(_ unbluCallModuleApi: UnbluCallModuleApi) {
    //...
  }

  func unbluCallModuleDidEndCall(_ unbluCallModuleApi: UnbluCallModuleApi) {
    //...
  }
}

Changes to UnbluCoBrowsingModule

The UnbluCoBrowsingModule is now called UnbluMobileCoBrowsingModule. This change makes it more explicit which co-browsing layer the module manipulates, namely the mobile co-browsing layer.

There have been a number of other changes to the UnbluMobileCoBrowsingModule. We have added a number of APIs to UnbluMobileCoBrowsingModuleApi: * addPrivateArea(withId:x:y:width:height) * removePrivateArea(withId:) * maxWindowCapturingLevel * preferredStatusBarStyle

The module also has a new delegate, UnbluMobileCoBrowsingModuleDelegate, and a new struct for configuring the module, UnbluMobileCoBrowsingModuleConfiguration. Please refer to the iOS mobile SDK reference documentation for more details.

The UnbluMobileCoBrowsingModuleProvider doesn’t have api instance you can use like the UnbluCoBrowsingModuleProvider in version 3 did. This affects several existing APIs:

  • To use the API of the UnbluMobileCoBrowsingModule, UnbluMobileCoBrowsingModuleProvider now provides a create(config:) function:

    // Version 3
    let coBrowsingModule = UnbluCoBrowsingModuleProvider.module
    
    // Version 4
    let mobileCoBrowsingModuleConfig = UnbluMobileCoBrowsingModuleConfiguration(...)
    let mobileCoBrowsingModule = UnbluMobileCoBrowsingModuleProvider.create(config: mobileCoBrowsingModuleConfig)
  • Because of the lack of an api instance in UnbluMobileCoBrowsingModuleProvider, the following tasks are also different in version 4:

    • Adding and removing private views:

      // Version 3
      import UnbluCoBrowsingModule
      
      //...
      
      UnbluCoBrowsingModuleProvider.api.addPrivateView(withTag: ...)
      
      //...
      
      UnbluCoBrowsingModuleProvider.api.removePrivateView(withTag: ...)
      
      // Version 4
      let mobileCoBrowsingModule: UnbluMobileCoBrowsingModuleApi
      mobileCoBrowsingModule.addPrivateView(withTag: ...)
      
      //...
      
      mobileCoBrowsingModule.removePrivateView(withTag: ...)
    • Checking for active mobile co-browsing sessions:

      // Version 3
      import UnbluCoBrowsingModule
      
      //...
      
      UnbluCoBrowsingModuleProvider.api.isMobileCoBrowsingActive { isActive in
        //...
      } failure: { error in
        //...
      }
      
      // Version 4
      let mobileCoBrowsingModule: UnbluMobileCoBrowsingModuleApi
      mobileCoBrowsingModule.isMobileCoBrowsingActive { isActive in
        //...
      } failure: { error in
        //...
      }
      
      // You can also check for an active mobile co-browsing session via a conversation
      let conversation: UnbluConversation
      let isMobileCoBrowsingActive = conversation.isMobileCoBrowsingActive
    • Stopping active mobile co-browsing sessions:

      // Version 3
      import UnbluCoBrowsingModule
      
      //...
      
      UnbluCoBrowsingModuleProvider.api.stopMobileCoBrowsing {
        //...
      } failure: { error in
        //...
      }
      
      // Version 4
      let mobileCoBrowsingModule: UnbluMobileCoBrowsingModuleApi
      mobileCoBrowsingModule.stopMobileCoBrowsing {
        //...
      } failure: { error in
        //...
      }
      
      // it is also possible via a conversation
      let conversation: UnbluConversation
      conversation.stopMobileCoBrowsing { result in
        //...
      }

Changes to UnbluCallModule

The UnbluCallModule has also undergone some changes in version 4.

  • Firstly, it provides a new delegate, UnbluCallModuleDelegate.

  • As with UnbluMobileCoBrowsingModuleProvider, UnbluCallModuleProvider no longer has an api instance you can use. To use the API of the module, you must now call the create() function:

    // Version 3
    let callModule = UnbluCallModuleProvider.module
    
    // Version 4
    let callModule = UnbluCallModuleProvider.create()
  • Because of the lack of an api instance in UnbluCallModuleProvider, checking for an active call works differently in version 4:

    // Version 3
    UnbluCallModuleProvider.api.isCallActive { isActive in
      //...
    }
    
    // Version 4
    let callModule: UnbluCallModuleApi
    
    callModule.isCallActive { isActive in
      //...
    } failure: { error in
      //...
    }
    
    // You can also check for an active call via a conversation
    let conversation: UnbluConversation
    let isCallActive = conversation.isCallActive

Other renamed or deprecated properties and functions

Version 3 Version 4

UnbluVisitorApi.instance.startAudioCall()

UnbluConversation.startAudioCall()

UnbluVisitorApi.instance.startVideoCall()

UnbluConversation.startVideoCall()

UnbluVisitorApi.instance.isCallUiOpen()

UnbluConversation.isCallUiOpen

UnbluVisitorApi.instance.getOpenConversationId()

UnbluClient.openConversation

UnbluVisitorApi.instance.setNamedArea()

UnbluClient.namedArea

UnbluVisitorApi.instance.setCustomCookies()

UnbluClient.customCookies

UnbluVisitorApi.enableDebugOutput

UnbluClient.enableDebugOutput

UnbluVisitorApi.enableCapturingPerformanceLogging

Set using UnbluMobileCoBrowsingModuleConfiguration when you create an UnbluMobileCoBrowsingModule instance

UnbluVisitorApi.logLevel

UnbluClient.logLevel

UnbluVisitorApi.preventScrollingByKeyboard

UnbluClient.preventScrollingByKeyboard

UnbluVisitorApi.instance.showUi()

deprecated

UnbluVisitorApi.instance.uiWindowConfiguration

deprecated

UnbluVisitorApi.instance.preloadUi()

deprecated

UnbluVisitorApi.instance.isUiVisible

deprecated

UnbluVisitorApi.instance.setUiMargins

deprecated

UnbluVisitorApi.instance.uiBottomMargin

deprecated

UnbluVisitorApi.instance.uiTopMargin

deprecated