Before using the Stringee Call API for the first time, you must have a Stringee account. If you do not have a Stringee account, sign up for free here: https://developer.stringee.com/account/register
Create a Project on the Stringee Dashboard.
Buy a Number (optional) Buy a number from Dashboard for app-to-phone and phone-to-app calling. If you only need app-to-app calling, skip this step.
Configure answer_url
For more information on answer_url, read Stringee Call API Overview. You can view answer_url sample code here: https://github.com/stringeecom/server-samples/tree/master/answer_url
If you do not have answer_url, you can use the following Project's answer_url to accelerate the process:
Project's answer_url for App-to-App call:
https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=false
Project's answer_url for App-to-Phone call:
https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=true
(Source code here: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/project_answer_url.php)
When building an application, you should use your own answer_url.
If you do not have answer_url, you can use the following Number's answer_url to accelerate the process:
Number's answer_url for Phone-to-App call (The call is routed to Your App which is authenticated by USER_ID):
https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=false&to_number=USER_ID
Number's answer_url for Phone-to-Phone call (The call is routed to TO_NUMBER):
https://developer.stringee.com/scco_helper/simple_number_answer_url?record=true&phoneToPhone=true&stringeeNumber=STRINGEE_NUMBER&to_number=TO_NUMBER
(Source code here: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/number_answer_url.php)
When building an application, you should use your own answer_url.
The simplest way to import the SDK into an iOS project is with CocoaPods. Open your project's Podfile and add this line to your app's target:
pod 'Stringee'
Then from the command line run:
pod install --repo-update
If you are new to CocoaPods, refer to their official documentation for more information on how to create and use Podfiles.
In the "Build Settings" tab -> "Other linker flags" add "$(inherited)" flag
In the "Build Settings" tab -> "Enable bitcode" select "NO"
To add the SDK in Xcode:
Add the following libraries and frameworks to Target -> "Build Phases" -> "Link Binary With Libraries":
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) uses Camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) uses Microphone</string>
To connect to the Stringee Server, 3-party authentication is required as described here: Client authentication
For testing purpose, go to Dashboard -> Tools -> Generate Access token and generates an access_token. In production, the access_token should be generated by your server, sample code generates access token here: https://github.com/stringeecom/server-samples/tree/master/access_token
#import <Stringee/Stringee.h>
In .h file
@interface ViewController : UIViewController <StringeeConnectionDelegate>
@property(strong, nonatomic) StringeeClient * stringeeClient;
@end
In .m file
- (void)requestAccessToken:(StringeeClient *)stringeeClient {
NSLog(@"requestAccessToken");
}
- (void)didConnect:(StringeeClient *)stringeeClient isReconnecting:(BOOL)isReconnecting {
NSLog(@"Successfully connected to Stringee Server, user ID: %@", stringeeClient.userId);
}
- (void)didDisConnect:(StringeeClient *)stringeeClient isReconnecting:(BOOL)isReconnecting {
NSLog(@"didDisConnect");
}
- (void)didFailWithError:(StringeeClient *)stringeeClient code:(int)code message:(NSString *)message {
NSLog(@"Failed connection to Stringee Server with error: %@", message);
}
NSString* accessToken = @"...";
self.stringeeClient = [[StringeeClient alloc] initWithConnectionDelegate:self];
[self.stringeeClient connectWithAccessToken:accessToken];
When the client connects to Stringee Server, instantiate a StringeeCall object and call the makeCallWithCompletionHandler method:
StringeeCall * stringeeCall = [[StringeeCall alloc] initWithStringeeClient:self.stringeeClient isIncomingCall:NO from:@"+1273065979" to:@"+1909982888"];
[stringeeCall makeCallWithCompletionHandler:^(BOOL status, int code, NSString * message, NSString *data){
NSLog(@"Make call result: code=%d, message: %@", code, message);
}];
The type of the outgoing call (app-to-app or app-to-phone) is decided by Your Server via the project's answer_url. Hence, you should be able to complete it independently. However, we offer an easy method for you to implement quickly by calling:
stringeeCall.customData = @"custom";
"custom" is a customizable text that be sent to Your Server via the project's answer_url. You can set it as: {'type': 'app-to-app'}, {'type':'app-to-phone'} or any other texts you want. Your Server will check this text to determine whether the call is app-to-app or app-to-phone.
Implement the StringeeCallDelegate protocol.
#import <Stringee/Stringee.h>
@interface ViewController : UIViewController <StringeeConnectionDelegate, StringeeCallDelegate>
@property(strong, nonatomic) StringeeClient * stringeeClient;
@end
in .m file:
//----------- StringeeCallDelegate -->
- (void)didChangeSignalingState:(StringeeCall *)stringeeCall signalingState:(SignalingState)signalingState reason:(NSString *)reason sipCode:(int)sipCode sipReason:(NSString *)sipReason {
NSLog(@"signalingState: %d", signalingState);
}
- (void)didChangeMediaState:(StringeeCall *)stringeeCall mediaState:(MediaState)mediaState {
NSLog(@"mediaState: %d", mediaState);
}
- (void)didReceiveDtmfDigit:(StringeeCall *)stringeeCall digit:(NSString *)digit {
NSLog(@"didReceiveDtmfDigit: %@", digit);
}
- (void)didReceiveLocalStream:(StringeeCall *)stringeeCall {
NSLog(@"didReceiveLocalStream");
}
- (void)didReceiveRemoteStream:(StringeeCall *)stringeeCall {
NSLog(@"didReceiveRemoteStream");
}
- (void)didReceiveCallInfo:(StringeeCall *)stringeeCall info:(NSDictionary *)info {
NSLog(@"didReceiveCallInfo: %@", info);
}
- (void)didHandleOnAnotherDevice:(StringeeCall *)stringeeCall signalingState:(SignalingState)signalingState reason:(NSString *)reason sipCode:(int)sipCode sipReason:(NSString *)sipReason {
NSLog(@"didAnsweredOnOtherDevice %d", signalingState);
}
//----------- StringeeCallDelegate <--
and set delegates for stringeeCall:
stringeeCall.delegate = self;
Implement the StringeeIncomingCallDelegate protocol
#import <Stringee/Stringee.h>
@interface ViewController : UIViewController <StringeeConnectionDelegate, StringeeCallDelegate, StringeeIncomingCallDelegate>
@property(strong, nonatomic) StringeeClient * stringeeClient;
@end
in .m file:
- (void)incomingCallWithStringeeClient:(StringeeClient *)stringeeClient stringeeCall:(StringeeCall *)stringeeCall {
NSLog(@"incomingCallWithStringeeClient, from: %@, to: %@", stringeeCall.from, stringeeCall.to);
}
and set incomingCallDelegate for stringeeClient:
self.stringeeClient.incomingCallDelegate = self;
When the client receives an incoming call
- (void)incomingCallWithStringeeClient:(StringeeClient *)stringeeClient stringeeCall:(StringeeCall *)stringeeCall {
NSLog(@"incomingCallWithStringeeClient, from: %@, to: %@", stringeeCall.from, stringeeCall.to);
stringeeCall.delegate = self;
}
Call the following method to initialize resources:
[stringeeCall initAnswerCall];
Call the following method to answer and start the conversation:
[stringeeCall answerCallWithCompletionHandler:^(BOOL status, int code, NSString *message) {
NSLog(@"%@", message);
}];
Call the following method to Hang up a call.
[stringeeCall hangupWithCompletionHandler:^(BOOL status, int code, NSString *message) {
NSLog(@"%@", message);
}];
Call the following method to reject a call.
[stringeeCall rejectWithCompletionHandler:^(BOOL status, int code, NSString *message) {
NSLog(@"%@", message);
}];
stringeeCall.isVideoCall = YES;
-(void) didReceiveLocalStream:(StringeeCall *)stringeeCall {
dispatch_async(dispatch_get_main_queue(), ^{
[stringeeCall.localVideoView setFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
[self.view insertSubview:stringeeCall.localVideoView atIndex:0];
});
}
Implement the StringeeRemoteViewDelegate protocol
#import <Stringee/Stringee.h>
@interface ViewController : UIViewController <StringeeConnectionDelegate, StringeeCallDelegate, StringeeIncomingCallDelegate, StringeeRemoteViewDelegate>
@property(strong, nonatomic) StringeeClient * stringeeClient;
@end
in .m file:
- (void)videoView:(StringeeRemoteVideoView *)videoView didChangeVideoSize:(CGSize)size {
NSLog(@"StringeeRemoteVideoView didChangeVideoSize: %fx%f", size.width, size.height);
}
Modify the implementation code of the didReceiveRemoteStream method:
-(void) didReceiveRemoteStream:(StringeeCall *)stringeeCall {
dispatch_async(dispatch_get_main_queue(), ^{
[stringeeCall.remoteVideoView setFrame:CGRectMake(0, 0, self.containRemoteView.bounds.size.width, self.containRemoteView.bounds.size.height)];
stringeeCall.remoteVideoView.delegate = self;
[self.containRemoteView addSubview:stringeeCall.remoteVideoView];
});
}
- (void)didChangeMediaState:(StringeeCall *)stringeeCall mediaState:(MediaState)mediaState {
dispatch_async(dispatch_get_main_queue(), ^{
if (mediaState == MediaStateConnected) {
[[StringeeAudioManager instance] setLoudspeaker:YES];
}
});
}
You can view the full version of this sample app on GitHub: https://github.com/stringeecom/ios-sdk-samples