Skip to content

Migration Guide from SDK 2.x to 3.x

Akshay Agarwal edited this page Mar 6, 2023 · 4 revisions

The Cisco Webex™ iOS SDK Version 3.0.0

The Cisco Webex iOS SDK Version 3.0.0 is a major rewrite of the version 2.x. It introduces a completely new architecture based on the same technology that powers the native Webex apps. This includes a lot of enhancements with the performance of the SDK most notably with the introduction of a local datawarehouse to cache all the spaces, messages, people, calls and much more. It also introduces a revolutionary new Catch up API that avoids redundant fetching of information from servers. Future updates and feature parity with the native clients will also be quicker than what it is at present. The v3 SDK is built in Swift 5 and requires iOS 13 or later. If you have developed an app with Cisco Webex SDK version 2.X, this guide will help you in transitioning from Webex SDK version 2 to version 3.

Table of Contents

Install

Assuming you already have an Xcode project, e.g. MyWebexApp, for your iOS app, here are the steps to integrate the Webex iOS SDK into your Xcode project using CocoaPods:

  1. Install CocoaPods:

    gem install cocoapods
  2. Setup CocoaPods:

    pod setup
  3. Create a new file, Podfile, with following content in your MyWebexApp project directory:

    source 'https://github.com/CocoaPods/Specs.git'
    
    use_frameworks!
    
    target 'MyWebexApp' do
      platform :ios, '13.0'
      pod 'WebexSDK'
    end
    
    target 'MyWebexAppBroadcastExtension' do
        platform :ios, '13.0'
        pod 'WebexBroadcastExtensionKit'
    end
  4. Install the Webex iOS SDK from your MyWebexApp project directory:

    pod install
  5. set ENABLE_BITCODE=No

  6. To your app’s Info.plist, please add an entry GroupIdentifier with the value as your app's GroupIdentifier. This is required so that we can get a path to store the local data warehouse.

  7. If you'll be using WebexBroadcastExtensionKit, You also need to add an entry GroupIdentifier with the value as your app's GroupIdentifier to your Broadcast Extension target. This is required so that we that we can communicate with the main app for screen sharing.

  8. Modify the Signing & Capabilities section in your xcode project as follows Signing and Capabilities

Major changes

  1. Starting from 3.0.0, We require new scope entitlements for your integrations to work with WebexSDK v3. Please follow this guide to set up a new integration for v3 SDKs
  2. Starting from 3.0.0, we have a new entry point for the SDK. i.e: webex.initialize(:completionHandler). This needs to be invoked before any other API(even before Auth). This method internally bootstraps the SDK and all it's components.
  3. We have transitioned from using a ServiceResponse class wrapped around a Result object to just using a Result class in our completion handlers
  4. To your app’s Info.plist, please add an entry GroupIdentifier with the value as your app's GroupIdentifier. This is required so that we can get a path to store the local data warehouse.
  5. Webex.getLogFileUrl(): You can use this to extract the WebexSDK logs as a zip file.
  6. Currently all resource ids that are exposed from the sdk are barebones GUIDs. You cannot directly use these ids to make calls to webexapis.com. You'll need to call Webex.base64Encode(:ResourceType:resource:completionHandler) to get a base64 encoded resource. But you're free to interchange between base64 encoded resource ids and barebones GUID while providing them as input to the sdk APIs.

Previous syntax:

webex.phone.dial("coworker@example.com", option: MediaOption.audioVideo(local: ..., remote: ...)) { (response: ServiceResponse<[Call]>) in
        switch response.result {
        case .success(let call):
            call.onConnected = {
                // ...
            }
            call.onDisconnected = { reason in
                // ...
            }
        case .failure(let error):
            // failure
        }
    }

New syntax:

webex.phone.dial("coworker@example.com", option: MediaOption.audioVideo(local: ..., remote: ...)) { (result: Result<[Call]>) in
        switch result {
        case .success(let call):
            call.onConnected = {
                // ...
            }
            call.onDisconnected = { reason in
                // ...
            }
        case .failure(let error):
            // failure
        }
    }

Authentication

  1. Instantiating OAuthAuthenticator. We were using client scope as a constructor argument which is now removed because scope is added internally. Also now we require a valid email to be passed in, as this required to discover which cluster the user belongs to.

Previous syntax for OAuth:

    let clientId = "$YOUR_CLIENT_ID"
    let clientSecret = "$YOUR_CLIENT_SECRET"
    let scope = "spark:all"
    let redirectUri = "https://webexdemoapp.com/redirect"

    let authenticator = OAuthAuthenticator(clientId: clientId, clientSecret: clientSecret, scope: scope, redirectUri: redirectUri)
    let webex = Webex(authenticator: authenticator)

    if !authenticator.authorized {
        authenticator.authorize(parentViewController: self) { success in
            if !success {
                print("User not authorized")
            }
        }
    }

New Syntax for OAuth

    let clientId = "$YOUR_CLIENT_ID"
    let clientSecret = "$YOUR_CLIENT_SECRET"
    let redirectUri = "https://webexdemoapp.com/redirect"
    let emailId = "user@example.com"


    let authenticator = OAuthAuthenticator(clientId: clientId, clientSecret: clientSecret, redirectUri: redirectUri, emailId: emailId)
    let webex = Webex(authenticator: authenticator)
    webex.enableConsoleLogger = true 
    webex.logLevel = .verbose // Highly recommended to make this end-user configurable incase you need to get detailed logs.

    webex.initialize { isLoggedIn in
            if isLoggedIn {
                print("User is authorized")
            } else {
                authenticator.authorize(parentViewController: self) { result in
                    if result == .success {
                        print("Login successful")
                    } else {
                        print("Login failed")
                    }
                }
            }
        }
  1. If you are using Guest Issuer (JWT-based) authentication using JWTAuthenticator. In this version, we have added completion handler which gets invoked when authorization process is done. All operations have to be performed after the completion handler has been invoked.

Previous syntax

    let authenticator = JWTAuthenticator()
    let webex = Webex(authenticator: authenticator)

    if !authenticator.authorized {
        authenticator.authorizedWith(jwt: myJwt)
    }

New syntax

    let authenticator = JWTAuthenticator()
    let webex = Webex(authenticator: authenticator)
    webex.enableConsoleLogger = true 
    webex.logLevel = .debug // Highly recommended to make this end-user configurable incase you need to get detailed logs.
    webex.initialize { [weak self] isLoggedIn in
        guard let self = self else { return }
            if isLoggedIn {
                print("User is authorized")
            } else {
                authenticator.authorizedWith(jwt: myJwt, completionHandler: { result in
                    switch result {
                    case .failure(let error):
                        print("Login failed")
                    case .success(let authenticated):
                        if authenticated {
                            print("JWT Login successful")
                        }
                        else {
                            print("JWT Login failed")
                        }
                    }
                })
            }
        }

Other changes

Here are some other changes that are required to transition from Webex SDK v2 to Webex SDK v3:

  1. Phone.register() API is no more required because this happens at the time of login internally. You have to comment/remove this.
  2. Phone.deregister() API is no more required. You have to comment/remove this.
  3. Refreshing oauth access token logic is now automatically handled by the sdk using timers. So we've removed this API from OAuthAuthenticator.
  4. You can no longer use your own auth code for logging in. All OAuth logins have to be started through the SDK.
  5. All resource ids that are exposed from the sdk are barebones GUIDs. You cannot directly use these ids to make calls to webexapis.com. You'll need to call Webex.base64Encode(:ResourceType:resource:completionHandler) to get a base64 encoded resource. However, you're free to interchange between base64 encoded resource ids and barebones GUID while providing them as input to the sdk APIs.
  6. A new API Webex.getLogFileUrl() has been introduced that provides a local zip file url of all the SDK logs. Please use this method to grab the log files for debugging
  7. Manually calling Message.update() is no longer required as this is updated automatically now. Hence this API is removed.