We officially support iOS 12.0 as iOS Deployment Target. You can try older versions but there are no guarantees it will work as expected.
The Sinch.xcframework file includes a FAT-binary containing the architectures arm64 and x86_64. When linking an application target against the Sinch.xcframework targeting an iOS device, it will add approximately 9.5 MB for arm64.
User IDs must not be longer than 255 bytes, must only contain URL-safe characters, and are restricted to the following character set:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghjiklmnopqrstuvwxyz0123456789-_=If you need to use User IDs containing characters outside the allowed set above, consider base64-encoding the raw User IDs using a URL-safe base64 alphabet as described in RFC 4648 Section 5. Note that the allowed character set overlaps with the URL-safe base64 alphabet but does not allow characters in the non-URL-safe alphabet, such as / (forward slash) and + (plus sign).
The Sinch SDK requires a local database file to operate properly. It is located in the application support directory (NSApplicationSupportDirectory) in the sinch/db/rtc/ subfolder. The application must not delete this folder.
The SinchCallDetails class holds metadata about a call, including timestamps for various call states, the end cause, and any error information. Call details are available through the details property on a SinchCall object.
SinchCallDetails provides timestamps for each stage of the call lifecycle. All timestamps are nil until that stage is reached.
| Property | Description |
|---|---|
startedTime | When the call was initiated |
progressedTime | When the call started progressing |
rungTime | When the call reached ringing state |
answeredTime | When the call was answered |
establishedTime | When media streams were established |
endedTime | When the call ended |
When a call ends, endCause indicates the reason. Before the call ends, the value is .none.
| Value | Description |
|---|---|
none | Call has not ended yet |
timeout | Call timed out |
denied | Call was denied/rejected |
noAnswer | Callee did not answer |
error | Call ended due to an error |
hungUp | Call was hung up normally |
canceled | Call was canceled before being answered |
otherDeviceAnswered | Call was answered on another device |
inactive | Call became inactive |
voipCallDetected | Another VoIP call was detected |
gsmCallDetected | A cellular call was detected |
When endCause is .error, the error property contains details about what went wrong:
func callDidEnd(_ call: SinchCall) {
if call.details.endCause == .error {
if let error = call.details.error {
print("Call failed: \(error.localizedDescription)")
}
}
}During calls, the Sinch SDK manages the shared audio session (AVAudioSession).
If your app integrates CallKit or LiveCommunicationKit, the system activates/deactivates the audio session. You must forward these events to the SDK using:
sinchClient?.callClient.didActivate(audioSession: audioSession)
sinchClient?.callClient.didDeactivate(audioSession: audioSession)At the beginning of an incoming or outgoing call, the SDK sets the category to AVAudioSession.Category.playAndRecord with mode AVAudioSession.Mode.voiceChat.
At the end of each call, the SDK restores audio session category, options, and mode to their original values.
By default, the SDK enables .allowBluetooth and .allowBluetoothA2DP options for the playAndRecord category.
If you need different AVAudioSession.CategoryOptions during calls, you can override the defaults before starting a call. The options you set will be applied for calls that start after the method is invoked.
sinchClient?.audioController.setAudioSessionCategoryOptions([.allowBluetooth, .allowBluetoothA2DP, .defaultToSpeaker])Overriding category options affects route selection and mixing behavior for all SDK-managed calls. Only set options your app really needs.
The Sinch SDK client uploads statistics to the Sinch servers at the end of a call, a call failure, or similar event. The statistics are used for monitoring of network status, call quality, and other aspects regarding the general quality of the service.
Some of the information is not anonymous and may be associated with the User ID of call participants.
The statistics upload is done by the client in the background.
App Extensions is a feature introduced in iOS 8. App extensions are compiled into executables that are separate from the main application executable. The Sinch SDK uses parts of the iOS SDK APIs that are unavailable to app extensions, thus it's not supported to use the Sinch SDK in an app extension.
Since Sinch SDK version 3.4.0, it's required to link against libc++. If your application is also dependent on libstdc++ (which is now considered deprecated by Apple for use on iOS), you can link against both libc++ and libstdc++ by passing the following linker flags:
- Other Linker Flags ->
-ObjC -Xlinker -lc++ -Xlinker -lstdc++
The SDK is available as both a static library and a dynamic library. If you're unsure which to use, prefer the dynamic library as it's less likely to require additional configuration.
If you switch from using the dynamic to the static version of the SDK, you may need to:
- Change the "Embed" field for
Sinch.frameworkin the target dependency from "Embed & Sign" to "Do not embed", or you may not be able to install the app on devices. - Add
-ObjCto your app's "Other Linker Flags" (Build Settings → All → Other Linker Flags) if you experience runtime errors such as "selector not recognized". See Apple Technical Q&A QA1490 for details.
Please see Encryption and Export Administration Regulations (EAR) and ensure that, if applicable, your application is registered for encryption regulations.
Since iOS 10 Apple has discontinued support for maintaining a VoIP control connection alive via -[UIApplication setKeepAliveTimeout:handler:]. Attempting to use this method on an iOS device running iOS 10 results in the following warning log: Legacy VoIP background mode is deprecated and no longer supported. The Sinch feature Active connection in background was using the keep alive handler API and is no longer supported on iOS. It's recommended to use VoIP Push Notifications and CallKit to achieve the equivalent functionality.
The Sinch SDK primarily uses VoIP push notifications. Since iOS 13 Apple imposed stricter limitations and requirements on how each VoIP push notification that an application receives must be reported to CallKit as an incoming call. As a result, the Sinch SDK no longer supports separate "Missed Call" push notifications.
We recommend using your own non-VoIP push notification mechanism to deliver "Missed Call" push notifications.
See also Apple Developer documentation on this topic.
Bitcode support was removed in Sinch SDK version 5.18.0. Bitcode is deprecated by Apple and is no longer enabled by default in Xcode 14. If your app previously used Bitcode, you must disable it explicitly in your Xcode project's build settings (Build Options → Enable Bitcode → No).
With an extra layer of NativeModule, you can embed the Sinch iOS library into your React Native application. Note that by doing this the SDK will only work on React Native apps running on iOS devices. To support other platforms, you must implement a NativeModule for each platform separately using the corresponding platform-specific Sinch SDKs.
To add the Sinch library to a React Native application:
- Open your native iOS React Native application in Xcode. Use the
xcworkspacefile located at<YourReactNativeApp>/ios. If the file doesn't exist, runpod installinside the iOS folder. - Drag the Sinch library
.xcframeworkfile to theFrameworksXcode group. - To access the Sinch SDK API from your React Native application, follow the iOS Native Module Guide.
Example SinchModule to create a client for a given user ID:
Header file:
#ifndef RCTSinchModule_h
#define RCTSinchModule_h
#import <React/RCTBridgeModule.h>
#import <Sinch/Sinch.h>
@interface RCTSinchModule : NSObject <RCTBridgeModule>
@property (nonatomic, strong) _Nullable id<SINClient> client;
@end
#endif /* RCTSinchModule_h */Implementation:
#import "RCTSinchModule.h"
#import <React/RCTLog.h>
#pragma mark - SINCallClientDelegate
@interface RCTSinchModule (SINCallClientDelegate) <SINCallClientDelegate>
@end
#pragma mark - SINClientDelegate
@interface RCTSinchModule (SINClientDelegate) <SINClientDelegate>
@end
@implementation RCTSinchModule
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(createClient:(NSString *)userId)
{
dispatch_async(dispatch_get_main_queue(), ^{
RCTLogInfo(@"Creating iOS client for userId %@", userId);
NSError *error;
self.client = [Sinch clientWithApplicationKey:@"<your-app-key>"
environmentHost:@"ocra.api.sinch.com"
userId:userId
error:&error];
self.client.delegate = self;
self.client.callClient.delegate = self;
[self.client start];
});
}
@end
@implementation RCTSinchModule (SINClientDelegate)
- (void)client:(id<SINClient>)client requiresRegistrationCredentials:(id<SINClientRegistration>)registrationCallback {
[registrationCallback registerWithJWT:@"user-jwt"];
}
- (void)clientDidStart:(id<SINClient>)client {
NSLog(@"Client did start");
}
- (void)clientDidFail:(id<SINClient>)client error:(NSError *)error {
NSLog(@"Client did fail");
}
@endAfter registering that module, you can call createClient from JavaScript:
const { SinchModule } = NativeModules;
const MainScreen = ({ navigation }) => {
const onPress = () => {
SinchModule.createClient('myUserId');
};
return (
<Button
title="LOGIN"
onPress={onPress}
/>
);
};- Because you're editing native iOS files, each time you change the code you'll need to rerun
npx react-native run-iosto test your changes. - This snippet is only an entry point to show how to interact with the Sinch SDK from a React Native app. For more complete use cases that handle errors and various callbacks, see the
samplesfolder of the Sinch SDK archive. The snippet does not handle validations like ensuring the Sinch client is not already initialized or started.