Skip to content
Last updated

Miscellaneous

Minimum requirements

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.

Note on Sinch.xcframework file size vs. linked size

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.

Restrictions on user IDs

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).

Local database file

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.

Call details

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.

Timestamps

SinchCallDetails provides timestamps for each stage of the call lifecycle. All timestamps are nil until that stage is reached.

PropertyDescription
startedTimeWhen the call was initiated
progressedTimeWhen the call started progressing
rungTimeWhen the call reached ringing state
answeredTimeWhen the call was answered
establishedTimeWhen media streams were established
endedTimeWhen the call ended

End cause

When a call ends, endCause indicates the reason. Before the call ends, the value is .none.

ValueDescription
noneCall has not ended yet
timeoutCall timed out
deniedCall was denied/rejected
noAnswerCallee did not answer
errorCall ended due to an error
hungUpCall was hung up normally
canceledCall was canceled before being answered
otherDeviceAnsweredCall was answered on another device
inactiveCall became inactive
voipCallDetectedAnother VoIP call was detected
gsmCallDetectedA cellular call was detected

Error information

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)")
    }
  }
}

iOS audio session

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)

Audio session categories

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.

Overriding audio session category options

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])
Use with care

Overriding category options affects route selection and mixing behavior for all SDK-managed calls. Only set options your app really needs.

Statistics

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

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.

Linking against the C++ standard library

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++

SDK static and dynamic libraries

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.framework in the target dependency from "Embed & Sign" to "Do not embed", or you may not be able to install the app on devices.
  • Add -ObjC to 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.

Encryption export regulations

Please see Encryption and Export Administration Regulations (EAR) and ensure that, if applicable, your application is registered for encryption regulations.

Deprecated features and APIs

Active connection in background

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.

Missed call push notifications

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

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).

Using Sinch SDK with React Native

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:

  1. Open your native iOS React Native application in Xcode. Use the xcworkspace file located at <YourReactNativeApp>/ios. If the file doesn't exist, run pod install inside the iOS folder.
  2. Drag the Sinch library .xcframework file to the Frameworks Xcode group.
  3. 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");
}

@end

After 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}
    />
  );
};
Note
  1. Because you're editing native iOS files, each time you change the code you'll need to rerun npx react-native run-ios to test your changes.
  2. 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 samples folder of the Sinch SDK archive. The snippet does not handle validations like ensuring the Sinch client is not already initialized or started.