Sendbird Calls SDK for iOS is used to initialize, configure, and build voice and video calling functionality into your iOS client app. In this repository, you will find the steps you need to take before implementing the Calls SDK into a project, and a sample app which contains the code for implementing voice and video call.
Note: You can only integrate one Sendbird application per app for your service regardless of the platforms. All users within your Sendbird application can communicate with each other across all platforms. This means that your iOS, Android, and web client app users can all make and receive calls with one another without any further setup. Note that all data is limited to the scope of a single application, and users in different Sendbird applications can't make and receive calls to each other.
Find out more about Sendbird Calls for iOS on Calls for iOS doc. If you need any help in resolving any issues or have questions, visit our community.
This section shows you the prerequisites you need for testing Sendbird Calls for iOS sample app.
The minimum requirements for Calls SDK for iOS sample are:
- Mac OS with developer mode enabled
- Xcode
- Homebrew
- At least one physical iOS device running iOS 9.0 and later
- Swift 4.0 and later
Installing the Calls SDK is simple if you’re familiar with using external libraries or SDKs in your projects. After creating your Sendbird application from your dashboard, you can choose to install the Calls SDK using Swift Package Manager, CocoaPods or Carthage.
Go to your Swift Package Manager's File
tab and select Swift Packages
. Then choose Add package dependency
.
Add the SendBirdCalls
framework into your Package Repository with the following URL: https://github.com/sendbird/sendbird-calls-ios.
To add the package, select an appropriate dependency rule and click Add Package
.
Open a terminal window. Navigate to the project directory, and then open the Podfile
by running the following command:
$ open Podfile
Make sure that the Podfile
includes the following:
platform :ios, '9.0'
target 'Project' do
use_frameworks!
pod 'SendBirdCalls'
end
Install the SendBirdCalls
framework via CocoaPods.
$ pod install
You can also use Carthage to integrate the SendBirdCalls
framework into your Xcode project.
- Install Carthage into your project by running
brew install carthage
in your project directory or choose any of other installation options. - Create a
Cartfile
in the same directory where your .xcodeproj or .xcworkspace is. - Add
github “sendbird/sendbird-calls-ios”
and github“sendbird/sendbird-webrtc-ios”
dependencies to yourCartfile
. - Run carthage update.
- A
Cartfile.resolved
file and a Carthage directory will appear in the same directory where your .xcodeproj or .xcworkspace is. - Drag the built .framework binaries from Carthage/Build/iOS into your application’s Xcode project.
- On your application targets’ Build Phases settings tab, click the + icon and choose New Run Script Phase. Create a Run Script in which you specify your shell (ex:
/bin/sh
), add the following contents to the script area below the shell:usr/local/bin/carthage copy-frameworks
- Add the paths to the frameworks you want to use under Input Files. For example:
$(SRCROOT)/Carthage/Build/iOS/SendBirdCalls.framework
$(SRCROOT)/Carthage/Build/iOS/WebRTC.framework
- Add the paths to the copied frameworks to the Output Files. For example:
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/SendBirdCalls.framework
$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/WebRTC.framework
- For more information, refer to the Carthage’s guide.
If you would like to try the sample app specifically fit to your usage, you can do so by following the steps below.
- Login or Sign-up for an account on Sendbird Dashboard.
- Create or select a call-activated application on the dashboard.
- Keep your Sendbird application ID in a safe place for future reference.
- On the Sendbird dashboard, navigate to the Users menu.
- Create at least two new users: one as a
caller
, and the other as acallee
. - Note the
user_id
of each user for future reference.
As shown below, the SendBirdCall
instance must be initiated when a sample client app is launched. To initialize the sample with your Sendbird application, go to the Sendbird dashboard, create a Sendbird application, and then specify the APP_ID
inside the sample app’s source code.
In the source code, find the application(_:didFinishLaunchingWithOptions:)
method from AppDelegate.swift
. Replace SAMPLE_APP_ID
with APP_ID
of your Sendbird application created earlier.
SendBirdCall.configure("SAMPLE_APP_ID")
- Verify that Xcode is open on your Mac system and the sample app project is open.
- Plug the primary iOS device into the Mac running Xcode
- Unlock the iOS device
- Run the application by pressing the
▶
Run button or typing⌘+R
- Open the newly installed app on the iOS device
- If two iOS devices are available, repeat these steps to install the sample app on each device.
VoIP Push Notification enables receiving calls even when the app is in the background or in the terminated state.
To make and receive calls, authenticate the user with Sendbird server with the SendBirdCall.authenticate(with:)
method and register a VoIP push token to Sendbird server.
You can register a VoIP push token (specific, the current user’s) by passing it as an argument to a parameter either in the authenticate()
method during authentication, or in the SendBirdCall.registerVoIPPush(token:)
method after completing the authentication.
Furthermore, a valid VoIP Services certificate or Apple Push Notification Service certificate also needs to be registered on the Sendbird Dashboard which you can do so on Add certificate under Application > Settings > Notifications.
For more details about generating certificates, refer to How to Generate a Certificate for VoIP Push Notification.
To handle a native-implementation of receiving incoming calls, implement Apple’s PushKit and CallKit frameworks. To implement the frameworks, register the push tokens associated with Sendbird Applications and handling of appropriate events. For more information, refer to Apple’s Voice Over IP (VoIP) Best Practices
- Log in to the sample app on the primary device with the user ID set as the
caller
. - Log in to the sample app on the secondary device using the ID of the user set as the
callee
. Alternatively, you can also use the Calls widget found on the Calls dashboard to log in as thecallee
. - On the primary device, specify the user ID of the
callee
and initiate a call. - If all steps are followed correctly, an incoming call notification will appear on the device of the
callee
. - Reverse the roles. Initiate a call from the other device.
- If the two testing devices are near each other, use headphones to make a call to prevent audio feedback.
Instead of PushKit and CallKit, you can also choose to receive remote push notifications for incoming calls.
For a sample app with remote push notifications, refer to the feature/remote-push-notifications branch.
When using CallKit to process your call, there may be times where a user makes a call without allowing media permission for audio and/or video access. Without such permission, the call will proceed without audio and/or video, which may not deliver the intended user experience. On the other hand, some other calling apps implement different user flow and require a media permission before starting a call.
Thus, you may face some issues regarding implementation because CallKit requires every VoIP Push Notifications to report a new incoming call instantaneously as specified on Apple's Documentation. When you face an issue related to this matter, refer to the following steps:
First, make sure that PushKit usage is in sync with the device's media permission state. If media permission is not allowed, destroy the existing push token to stop receiving VoIP Push and to ignore any incoming calls. Be sure to test your implementation and refer to Apple's guidelines on VoIP Push Notifications and CallKit.
Second, to ignore an incoming call if the media permission is not allowed and to prevent any future calls from being delivered to the device, on your AppDelegate's pushRegistry(_:didReceiveIncomingPushWith:for:completion:)
, add the following:
guard AVAudioSession.sharedInstance().recordPermission == .granted else { // Here, we check if the audio permission is granted
// If it is not granted, we will destroy current push registration to stop receiving push notifications
self.voipRegistry?.desiredPushTypes = nil
// We will ignore current call and not present a new CallKit view. This will not cause crashes as we have destroyed current PushKit usage.
completion()
return
}
// Media permissions are granted, we will process the incoming call.
SendBirdCall.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type) { uuid in
...
Third, if you would like to register VoIP Push Notification only if the media permission is allowed, on your AppDelegate's application(_:didFinishLaunchingWithOptions:)
, add the following:
if AVAudioSession.sharedInstance().recordPermission == .granted {
self.voipRegistration()
}
Note: Destroying existing PKPushRegistry will prevent any future VoIP Push Notifications to be sent to the device. If you want to start receiving VoIP Push Notifications again, you must re-register PKPushRegistry by using
self.voipRegistry?.desiredPushTypes = [.voIP]
.
You can create a current user's local video view and customize its appearance before accepting an incoming call. Follow the steps below to customize the current user’s local video view:
- Add a
UIView
to your storyboard. - Create a view with the frame you want by using the
SendBirdVideoView
object. - To add a subview, embed the
SendBirdVideoView
to theUIView
from Step 1. - Find an appropriate camera device by accessing the
availableVideoDevice
property ofDirectCall
. - Start capturing video contents from the camera by calling the
DirectCall.selectVideoDevice(_:completionHandler:)
method.
@IBOutlet weak var localVideoView: UIView?
// Create SendBirdVideoView
let localSBVideoView = SendBirdVideoView(frame: self.localVideoView?.frame ?? CGRect.zero)
// Embed the SendBirdVideoView to UIView
self.localVideoView?.embed(localSBVideoView)
// Start rendering local video view
guard let frontCamera = (call.availableVideoDevice.first { $0.position == .front }) else { return }
call.selectVideoDevice(frontCamera) { (error) in
// TODO: handle an error
}
Currently Sendbird Calls only supports a one-to-one call and the call waiting feature isn’t available yet. Using the SendBirdCall.getOngoingCallCount()
method, you can retrieve the number of the current user’s ongoing calls and end a call if the call count has reached its limit.
if SendBirdCall.getOngoingCallCount() > 1 {
call.end()
}
If you’re using Apple’s CallKit framework, you should use CXProviderConfiguration
instead to set the allowed number of the current user’s ongoing calls as shown below:
let configuration = CXProviderConfiguration(localizedName: "Application Name")
configuration.maximumCallsPerCallGroup = 1
configuration.maximumCallGroups = 1
...
let provider = CXProvider(configuration: configuration)
You can use different sound effects to enhance the user experience for events that take place while using Sendbird Calls.
To add sound effects, use the SendBirdCall.addDirectCallSound(_:forType:)
method for the following events: dialing, ringing, reconnecting, and reconnected. Remember to set sound effects before the mentioned events occur. To remove sound effects, use the SendBirdCall.removeDirectCallSound(_:forType:)
method.
// Play on a caller’s side when making a call.
SendBirdCall.addDirectCallSound("dialing.mp3", forType: .dialing)
// Play on a callee’s side when receiving a call.
SendBirdCall.addDirectCallSound("ringing.mp3", forType: .ringing)
// Play when a connection is lost, but the SDK immediately attempts to reconnect.
SendBirdCall.addDirectCallSound("reconnecting.mp3", forType: .reconnecting)
// Play when the connection is re-established.
SendBirdCall.addDirectCallSound("reconnected.mp3", forType: .reconnected)
If you’re using Apple’s CallKit framework, you should use CXProviderConfiguration.ringtoneSound
instead to add sound effects as ringtones like the following:
let configuration = CXProviderConfiguration()
...
configuration.ringtoneSound = "ringing.mp3"
For more information about sound effects, see the SDK for iOS README for Sound effects.
For further detail on Sendbird Calls for iOS, refer to Sendbird Calls SDK for iOS README.