-
Notifications
You must be signed in to change notification settings - Fork 29
Migration Guide from SDK 2.x to 3.x
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.
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:
-
Install CocoaPods:
gem install cocoapods
-
Setup CocoaPods:
pod setup
-
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
-
Install the Webex iOS SDK from your MyWebexApp project directory:
pod install
-
set
ENABLE_BITCODE=No
-
To your app’s
Info.plist
, please add an entryGroupIdentifier
with the value as your app's GroupIdentifier. This is required so that we can get a path to store the local data warehouse. -
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. -
Modify the
Signing & Capabilities
section in your xcode project as follows
- 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
- 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. - We have transitioned from using a
ServiceResponse
class wrapped around aResult
object to just using aResult
class in our completion handlers - To your app’s
Info.plist
, please add an entryGroupIdentifier
with the value as your app's GroupIdentifier. This is required so that we can get a path to store the local data warehouse. -
Webex.getLogFileUrl()
: You can use this to extract the WebexSDK logs as a zip file. - 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("[email protected]", 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("[email protected]", 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
}
}
- 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.
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")
}
}
}
let clientId = "$YOUR_CLIENT_ID"
let clientSecret = "$YOUR_CLIENT_SECRET"
let redirectUri = "https://webexdemoapp.com/redirect"
let emailId = "[email protected]"
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")
}
}
}
}
- 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.
let authenticator = JWTAuthenticator()
let webex = Webex(authenticator: authenticator)
if !authenticator.authorized {
authenticator.authorizedWith(jwt: myJwt)
}
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")
}
}
})
}
}
Here are some other changes that are required to transition from Webex SDK v2 to Webex SDK v3:
-
Phone.register()
API is no more required because this happens at the time of login internally. You have to comment/remove this. -
Phone.deregister()
API is no more required. You have to comment/remove this. - Refreshing oauth access token logic is now automatically handled by the sdk using timers. So we've removed this API from OAuthAuthenticator.
- You can no longer use your own auth code for logging in. All OAuth logins have to be started through the SDK.
- 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. - 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 - Manually calling
Message.update()
is no longer required as this is updated automatically now. Hence this API is removed.