Using the iOS SDK
- Overview
- Lifecycle
- Configuration
- Authentication
- Callbacks
- Activation
- Deactivation
- Call
- Push notifications
Overview
The VoiceSDK
facade object is the starting point for all communications between the client and the Voice SDK.
Lifecycle
The Voice SDK is designed to fit the concept of account based applications where the application has login (auto-login) and logout actions.
The SDK client initializes the Voice SDK once and then may have multiple activation/deactivation cycles following user login or logout.
Configuration
To configure the Voice SDK you assign the user account configuration (Configuration
) as follows:
let sdk = VoiceSDK.shared
// …
sdk.configuration = Configuration(...)
The configuration can be updated at any time after SDK initialization.
struct Configuration: Hashable {
var accountId: String
var userId: String
// …
var displayName: String
var phoneNumber: String?
// …
var callKit: CallKitOptions
}
User account
The accountId
and userId
can only be changed when the SDK is in the .inactive
state.
CallKit
The SDK has a built-in integration with the CallKit framework.
The SDK client can use CallKitOptions
to customize the CallKit configuration.
struct CallKitOptions: Hashable {
var localizedName: String
// …
var ringtoneSound: String?
// …
var iconFileName: String?
}
The callKit
property can only be changed when there are no active calls.
Authentication
The SDK client passes the jwtToken
to the SDK by setting (updating) the authenticationContext
property of VoiceSDK
object as follows:
sdk.authenticationContext.jwtToken = jwtToken
sdk.authenticationContext.callback = { [weak self] token in
// token refresh is requested
self?.refreshToken()
}
Callbacks
You can modify certain aspects of SDK functionality by setting the following callbacks:
Log message
If the logMessageCallback
is set, the Voice SDK stops to print messages to the console and passes them to the client:
VoiceSDK.logMessageCallback = { module, message, level, context in
// print log message to the console
}
The log message logMessageCallback
can be set before Voice SDK initialization.
Contact resolution
If the contactResolverCallback
is set, the Voice SDK uses this callback to request the contact (caller) details when the incoming call notification (push) arrives on a device.
The Voice SDK uses the displayName
property value (from contact details) as the caller name on an incoming call screen.
struct ContactInfo: Contact {
var contactId: String
var displayName: String?
var avatarUrl: String?
var phoneNumber: String?
// …
}
…
VoiceSDK.contactResolverCallback = { context, completion in
// …
let contact = ContactInfo(contactId: context.callerId,
displayName: context.callerName,
avatarUrl: nil, phoneNumber: nil)
completion?(contact)
}
The SDK client adopts the Contact
protocol and returns the adjusted information in a completion
handler.
Audio session
The Voice SDK requests client to configure an Audio Session via audioSessionConfigurationCallback
.
VoiceSDK.audioSessionConfigurationCallback = { session in
do {
let mode: AVAudioSession.Mode = .voiceChat
try session.setCategory(.playAndRecord, mode: mode, options: [.allowBluetooth])
try session.overrideOutputAudioPort(.none)
try session.setPreferredIOBufferDuration(0.01)
} catch let error {
//…
}
}
The Voice SDK has audioSessionActivated
property which indicates if Audio Session is activated (or deactivated) by CallKit.
var audioSessionActivated: CurrentValueSubject<Bool, Never> { get }
Activation
To activate the VoiceSDK
, the client invokes the activate
function:
func activate(completion: @escaping (_ result: Result<Void, ErrorType>) -> Void)
sdk.activate { result in
switch result {
case .success:
//…
case .failure:
//…
}
}
Upon a .success
notification, the VoiceSDK
object transitions to the .active
state.
Otherwise, it comes back to the .inactive
state.
enum State {
case inactive, activating, active, deactivating
}
//…
sdk.state
The client can adopt the VoiceSDKObserverProtocol
protocol and receive notifications on the VoiceSDK
object state change:
func addObserver(_ observer: AnyObject)
sdk.addObserver(client)
//…
func handleStateChanged(_ state: VoiceSDK.State) {
// …
}
Deactivation
To deactivate the VoiceSDK
client, invoke the deactivate
function:
func deactivate(completion: @escaping (_ result: Result<Void, ErrorType>) -> Void)
sdk.deactivate { result in
switch result {
case .success:
//…
case .failure:
//…
}
}
Upon successful completion, the VoiceSDK
object transitions to an .inactive
state.
Call features
- Place an outgoing call
- Receive an incoming call
- Call observer protocol
- Mute a call
- Put a call on hold
- Hang up a call
Place an outgoing call
When an outgoing call is placed the following function is used:
func placeCall(callType: CallType, to callee: Contact,
completion: @escaping (Result<VoiceCall, ErrorType>) -> Void)
//…
let completionBlock: (Result<VoiceCall, ErrorType>) -> Void = { result in
switch result {
case .success(let call):
// present UI
default: break
}
completion(result)
}
let parameters = OutgoingCallParameters(callType: .voip, callee: callee)
sdk.placeCall(with: parameters, completion: completionBlock)
//…
Receive an incoming call
When you configure the SDK for incoming calls, the client adopts the CallSetObserverProtocol
protocol and registers the observer with the VoiceSDK
object:
class MyVoiceSDKClient: CallSetObserverProtocol {
//…
func handleCallAdded(_ call: VoiceCall) {
if call.direction == .inbound {
// present UI
}
}
//…
}
let client = MyVoiceSDKClient(...)
//…
sdk.addObserver(client)
Call observer protocols
The VoiceCall
object is observable.
The SDK client can subscribe for changes by adopting the following protocols:
VoiceCallStateObserverProtocol
VoiceCallConnectionQualityObserverProtocol
VoiceCallMutedStateObserverProtocol
and registering as an observer with the VoiceCall
object:
//…
call.addObserver(client)
//…
Mute a call
The VoiceCall
object has the muted
property which enables call muting as follows:
protocol VoiceCall: class {
//…
var muted: CallMutedState { get set }
//…
}
You can mute (or unmute) the call by assigning the corresponding value to the property:
call.muted = .on // .off
Put a call on hold
Use the following hold
function for call holding:
protocol VoiceCall: class {
//…
func hold(_ completion: ((CallActionCompletionStatus) -> Void)?)
func resume(_ completion: ((CallActionCompletionStatus) -> Void)?)
//…
}
call.hold { status in
switch status {
//
case .done:
//
case .canceled:
//
case .failed:
}
}
The execution of the hold (resume)
operation implicitly triggers the call state change.
Hang up a call
Use the hangup
function to end the call:
protocol VoiceCall: class {
//…
func hangup(_ completion: ((CallActionCompletionStatus) -> Void)?)
//…
}
call.hangup { status in
switch status {
case .done:
//
case .canceled:
//
case .failed:
}
}
On completion the call transitions to the disconnected
state.
Additionally, the Voice SDK removes the call from the calls
list.
Push Notifications
The Voice SDK handles PushKit notifications internally.
However, for debugging purpose, the SDK exposes the pushToken
property as part of the VoiceSDK
object.
Additionally, the client can monitor the push notification payload or observe the token change by using the PushNotificationObserverProtocol
protocol.
Updated over 1 year ago