-
Notifications
You must be signed in to change notification settings - Fork 21
WebRTC Calls and UI
Find more info about Voice/Video Calls and WebRTC features in Infobip docs.
- Intro
- Migration guide
- Quick start guide
- Important notes
- Stopping and restarting the service
- Taking control over the calls
- Customising the calls UI
- Troubleshooting
WebRTCUI is an easy to use, plug-and-play component, that allows you to connect to Infobip RTC by just invoking one single method. This assumes, though, that the initial setups of Mobile Push Notifications and the Infobip RTC exists in both, your account and your mobile app profile.
WebRTCUI takes care of everything: the registration of your device (in order to receive and trigger calls), the handle of the calls themselves, and offers you a powerful user interface with all the features your customer may need: ability to capture video through both, front and back camera, option to mute and use the speaker, ability to capture and share the screen of your mobile device, option to minimise the call UI in a picture-on-picture mode, and more.
WebRTCUI also allows you to take control in any step of the flow, if you wish or needs so: you can intercept the calls to checks its content, become a delegate for the WebRTC service, use our UI to build on top of it, or use your own custom user interface to handle the calls; it is up to you.
Following the major release of Infobip RTC SDK 2.0, content and setup exclusive of RTC SDK 1.x will be deprecated on 31/10/2023. If you were using WebRTCUI previously (version 10.X or older), please update to the latest version and read carefully the Quick Start Guide below. You will need a new setup and probably change your method to enable calls. Things to consider:
- Portal UI for handling WebRTC has been replaced with REST API calls.
- The previous WebRTC application you used must be replaced with two new separate models: Application and Configuration.
- The WebRTCApplicationId you used before to enable calls in mobile needs to be replaced with a new WebRTCConfigurationId.
- If you want to use WebRTCUI and InAppChat together (meaning, you want to receive calls from Infobip Conversation's agents), you need to use the new withInAppChatCalls method, instead of the previous withCalls.
The guide below will go into more details for each point:
-
Make sure you have setup the core of Mobile Messaging SDK and that you are able to successfully receive push registration Ids (the console debug logs will give you a hint about it).
-
Create your WebRTC application entity with our Platform API. Some comments:
- Both the applicationName and the applicationId are entirely up to you, so choose values that you will be able to recognise in the future (for example, a name to identify mobile apps, or customers). The only requirement is for the values (that can be equal) to be URL encodable. Also note that two WebRTC applications cannot have the same name and id.
- Remember/copy the applicationId that you defined, as it will be needed in the next step.
-
Create your WebRTC configuration with the dedicated Rest API. Some explanation on the body parameters:
- The applicationId needs to match the value you defined in the previous point. There is a pairing of 1 applicationId to 1 configurationId, so be careful when doing a POST over this API as you may overwrite existing values unknowingly.
- Password is entirely optional, though it is recommended as it increases the security (i.e: if your Infobip credentials are compromised, the certificate's won't).
- apnsCertificateFileName is for you to recognise the configuration in the future (for example, you can define it as mySandboxCert.p12 or myProdCert.p12, depending on your APNS certificate). This certificate filename has no other function but readability; it doesn't need to match your actual filename.
- apnsCertificateFileContent is the string base64 value of your p12 certificate. There are many ways to convert from p12 to base64 formats, but one easy way on Mac OS, that would read your p12 file in the desktop, and write the base64 in a text file also in desktop, is:
cat ~/Desktop/mySandboxCert.p12 | base64 > ~/Desktop/myCertTextfile
- The response in the previous step provided you the unique Id of your newly created configuration. This configurationId is a required initialisation param that you can hardcode into your app. But now that you have everyhing you need to enable calls, it is time to consider your use case: Are you using WebRTC together witn InAppChat? Then this is the method you need to use to enable calls: withInAppChatCalls(configurationId:)
MobileMessaging.withApplicationCode(
<your push application code>,
notificationType: .alert)?.
withInAppChat().
withInAppChatCalls(configurationId: <your webrtc configuration Id>).
start()
If you plan on offering a use case of WebRTC without using InAppChat (which means, you want to handle the call identities on your own, disconnected from Infobip Conversations), you can either inject your own custom identity, or let the SDK use the push RegistrationId (the default mode), by selecting an identity mode in the method __withCalls(configuration:mode:)_:
MobileMessaging.withApplicationCode(
<your push application code>,
notificationType: .alert)?.
withCalls(configurationId: <your webrtc configuration Id>, mode: .custom("my identity")).
start()
// or
MobileMessaging.withApplicationCode(
<your push application code>,
notificationType: .alert)?.
withCalls(configurationId: <your webrtc configuration Id>, mode: .default).
start()
- And that's it! Your app is now set to receive calls in a real device.
While WebRTCUI is plug-and-play, there are few things you should handle in your app before it is submitted to the Apple Store, in order to avoid problems:
- We suggest you ask for permissions for microphone use in your app before a WebRTC call is triggered. This will avoid the case where a first call is received, but the client is forced-muted until the permissions are granted. Camera permissions are not that critical. In any case, our WebRTCUI component will prompt an alert for the cases above if a lack of the needed permissions is detected.
AVAudioSession.sharedInstance().requestRecordPermission({ granted in
if !granted { print("Microphone permission denied.") }
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
AVCaptureDevice.requestAccess(for: AVMediaType.video) { granted in
if !granted { print("Camera permission denied.") }
}
}
})
- iOS will always display, for incoming calls, the system UI (either banner of fullscreen). This is unavoidable, though it will be in background when your app is in foreground. But that's not the case when your device is locked: the operating system will offer its UI, and there will be a button that links the call to your app. This button needs an icon provided by you, that must be a png with alpha channel. The system will present it as a monochrome equivalent icon, so consider this fact (colours will be ignored) when choosing its design. See the setup of it in the ChatExample project included in the SDK:
MobileMessaging.webRTCService?.callAppIcon = UIImage(named: "alphaLogo")
-
The WebRTCUI allows you to set the sounds your app will produce for inbound ringing, outbound ringing and call disconnected. See the section of customisation and the Chat Example for more details. The customisation for this sounds is entirely optional - system sounds or the default WebRTCUI sounds will be used if undefined otherwise.
-
WebRTC is not allowed in the People's Republic of China. Offering it risks an Apple Store rejection. If you are releasing world wide or in that territory, you need to add, in your app release notes in AppStoreConnect, a text similar to: "In this version and onwards, we do not use CallKit features for users in China. We detect the user's region using NSLocale". Our WebRTCUI already checks the region and disable its functionality for you.
-
Currently, WebRTCUI is oriented to calls with Infobip Conversation's agents; P2P calls and channel specific call types are not yet supported (though you can still manually integrate them with Infobip RTC SDK.
-
APSN certificates (p12) usually have an expiration of 1 year. It is your responsibility to update new certificates to your WebRTC configuration before they expire, in order for the calls to continue working without issues (check the Quick start guide for details).
- The method withInAppChatCalls/withCalls, used for the initialisation of the MobileMessaging in the Quick start guide above, will register for calls whenever the app has received a push registration id. But if your app needs authenticated users, you can skip that method altogether in order decide when a device is allowed to receive calls. This is easily done by invoking, anytime (for example, when the user of your app has successfully logged in), the method:
MobileMessaging.webRTCService?.configurationId = <your webrtc Configuration Id> // Do not forget to set it once before calling start() method
MobileMessaging.webRTCService?.identityMode = <your selected identity mode> // i.e. .inAppChat
MobileMessaging.webRTCService?.start({ result in
print("Calls process started successfully \(result)")
})
- You may also need to stop the calls from being possible at some point (for example, when your user manually logs out). You can do it so by invoking:
MobileMessaging.webRTCService?.stopService({ result in
print("Calls were stopped successfully \(result)")
})
- You can then call the webrtcService?.start method when the user logs in again.
WebRTCUI is plug-and-play, and you do not need to intercept any part of the logic: it will handle automatically any call and present the UI it needs. But you can become a delegate of the service if you wish so:
MobileMessaging.webRTCService?.delegate = self
By becoming a MMWebRTCDelegate, you need to implement the following methods:
-
callRegistrationEnded: this method is triggered when the registration for webrtc calls is completed. It will let you know if succeded or there was an error (and its kind). Registration may fail due to network or configuration problems. You can check the nature of the error to decide if a retry is needed (otherwise, your app won't be able to receive or trigger any call). A further description of any problem will also appear as a console debug log.
-
callUnregistrationEnded: this method is triggered when an unregistration for webrtc calls is completed (the process of asking to stop receiving calls). Same as above, you can interpret the result and act appropiately.
-
inboundCallEstablished: This method will be triggered when a webrtc call is being received. You can then present our default UI (as seen below), or present a UI of your own:
if let callController = MobileMessaging.webRTCService?.getInboundCallController(
incoming: applicationCall, establishedEvent: callEstablishedEvent) {
PIPKit.show(with: callController) // This allows you to use the picture-on-picture/maximising-minimising feature.
}
The UI for interacting with the calls is important. For this reason, we allow you to use your own, build on top of ours, or customize easily the provided UI within the SDK. The WebRTCUI service has a settings variable where you can define all colours, icons and even sounds of the interface:
MobileMessaging.webRTCService?.settings.inboundCallSoundFileName = "MMInboundCall.wav" // filename for inbound audio file that must exist in your project
// example on overwritting a color directly
MobileMessaging.webRTCService?.settings.backgroundColor = .darkGray
// example on overwritting a sound (wav or mp3 must be in your main bundle)
MobileMessaging.webRTCService?.settings.soundEndCall = NSDataAsset(name: "phone-ringing-sound")
// example on overwritting an icon (file must be in your main bundle)
MobileMessaging.webRTCService?.settings.iconAvatar = UIImage(named: "icon-user-border")
Check the whole list of possible options in the class MMWebRTCSettings.
To customize the order (and presence) of call action buttons, use MobileMessaging.webRTCService?.settings.customButtons
. First 3 buttons are visible in main area (half-expanded state of bottom sheet), together with HangUp button, while the rest is visible in a full expanded state (secondary buttons). Available are the following button types:
case hangup // presented always at first place by default
case screenshare((() -> Void)?)
case microphone((() -> Void)?)
case video((() -> Void)?)
case flipCamera((() -> Void)?)
case speakerphone((() -> Void)?)
case custom(MMCallButtonModel)
Screenshare, microphone, video, flipcamera and speakerphone buttons accept optional completion handler that will be called after the buttons are executed. A custom button type accepts a button model as seen below:
public struct MMCallButtonModel {
public var icon: UIImage?
public var iconSelected: UIImage?
public var color: UIColor
public var selectedColor: UIColor?
public var text: String?
public var action: (UIButton) -> Void
}
Other (non custom) buttons types need to modify their appearance following MobileMessaging.webRTCService?.settings parameters, as per the general customization
WebRTCUI allows you to replace the caller name on the incoming call push notification (and full screen view) to a custom string of your own. This is useful when you want to display your corporate name as caller, instead of a default RTC identifier. In order to achieve this, just set a customCallerValue as in this example:
MobileMessaging.webRTCService?.settings.customCallerValue = "Your custom value"
Setting a customCallerValue is entirely optional, and leaving it nil will display the actual caller identifier.
-
Q: "When invoking call start and stop methods for restarting/pausing the WebRTC service, it has no immediate effect. Why?".
A: It is very common, by the async nature of WebRTC, that these methods suffer a latency of around 20 to 30 seconds in wort case scenarios, even if their completion return "success". This cannot be avoid it.
-
Q: "The ringing sounds lasts only few seconds, then it becomes quiet or decreases its volume, even if the user did not hang up. Why?".
A: There is feature in iPhone, called Attention Aware, under Face ID & Passcode settings, in which the phone detects your face and silent the ringing. User needs to manually disabled it so this behaviour stops.
-
Q: "I am not receiving a call, that I know is being triggered by other end. Why?"
A: There is a wide range of reasons for a call failing to ring in client's side. Some are: - Your APNS certificate is not the same in your Mobile Push App and the WebRTC App in Customer Portal, or your certificates are expired, or do not match the enviroment you are using (sandboxing vs production). You will need to recheck your setup in Apple Developer/App Profiles, Xcode and Costumer Portal. - User has "Do not disturb" mode enabled. - You app did not handled push registration properly, or someone in your team with management access in Infobip's Customer Portal changed something it should have not changed. As registrations rely on a valid installation data, this problems are usually fixable by uninstalling/reinstalling the app. - Something else is wrong. Usually, an error explaining the reason in the console should be enough to find the root cause. If there are no logs, you may need to edit the log levels in Mobile Messaging SDK with MobileMessaging.logger = MMDefaultLogger(). The logs, and comparing your own app with the Chat Example project, should be enough. It not, please contact support for further help.
-
Q: "I'm building my application using Xcode 15 and getting following issue:
DT_TOOLCHAIN_DIR cannot be used to evaluate LIBRARY_SEARCH_PATHS, use TOOLCHAIN_DIR instead
" for theIBGoogleWebRTC
andInfobipRTC
pods. How can I fix it?"A: This issue should be fixed after updating to the 1.13.0 CocoaPods version, but before it's released, this workaround could be used. Don't forget to re-integrate pods (perform
pod deintegrate
,pod install
) after adding those lines to the Podfile. -
Q: I am having errors of the kind "dyld: Library not loaded @rpath" and cannot build.
A: There are many reason for this (too unrelated to be mentioned here), but a very simple one you may check (and try) is to add, in your project's settings "Runpath Search Paths", the value: "@executable_path/Frameworks", if it is not already there.
If you have any questions or suggestions, feel free to send an email to [email protected] or create an issue.
- Library events
- Server errors
- Users and installations
- Messages and notifications management
- Inbox
- Geofencing service
- Privacy settings
- In-app chat
- WebRTC Calls and UI