Suggestions

close search

Getting started with Stringee Call API using iOS SDK

Step 1: Prepare

  1. Before using 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

  2. Create a Project on Stringee Dashboard Stringee create Project

  3. Buy a Number (optional) For app-to-phone, phone-to-app calling, buy a Number from Dashboard. If you only need app-to-app calling, skip this step. Stringee buy Number

  4. 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 a answer_url, to speed things up you can use the following answer_url:

https://v1.stringee.com/dev_urls/answer_url/from_internal-test.php

(Source code here: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/answer_url-from_internal.php)

But in a production application, you should use your own answer_url.

If you do not have a answer_url, to speed things up you can use the following answer_url:

https://v1.stringee.com/dev_urls/answer_url/from_external-test.php?userId=USER_ID

The call is routed to Your App which authenticated by USER_ID

(Source code here: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/answer_url-from_external.php)

But in a production application, you should use your own answer_url.

Step 2: Add SDK to Project

CocoaPods (preferred)

  1. Edit your project's Podfile

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're new to CocoaPods, see their official documentation for info on how to create and use Podfiles.

  1. In the "Build Settings" tab -> "Other linker flags" add "$(inherited)" flag

  2. In the "Build Settings" tab -> "Enable bitcode" select "NO"

Manual

To add the SDK in Xcode:

  1. Download the SDK: https://developer.stringee.com/download
  2. Unzip the archive to your project home directory
  3. Open your application's Xcode project.
  4. If you don't have a Frameworks group in your project, create one.
  5. Open your project home directory using Finder.
  6. Drag the Stringee.framework into the Frameworks group of Xcode's Project Navigator. In the displayed dialog, choose "Create groups" and select "Copy items if needed".

  1. Open Xcode's Build Settings tab in your project.
  2. Add $(SRCROOT) to the project's Framework Search Paths setting.

  1. Configure Xcode Project

Add the following libraries and frameworks to Target -> "Build Phases" -> "Link Binary With Libraries":

  1. In the "Build Settings" tab -> "Other linker flags" add "-ObjC" flag

  1. In the "Build Settings" tab -> "Enable bitcode" select "NO"

Step 3: Edit Info.plist

  1. Right-click the information property list file (Info.plist) and select Open As -> Source Code
  2. Insert the following XML snippet into the body of your file just before the final element:
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) uses Camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) uses Microphone</string>

Step 4: Connect to Stringee Server

In order to connect to Stringee Server, 3-parties 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

  1. Add a line to import the Stringee library:
#import <Stringee/Stringee.h>
  1. Implements the StringeeConnectionDelegate protocol

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);
}
  1. Start connecting
NSString* accessToken = @"...";

self.stringeeClient = [[StringeeClient alloc] initWithConnectionDelegate:self];
[self.stringeeClient connectWithAccessToken:accessToken];

Step 5: Make a call

When the client connects to Stringee Server, instantiate a StringeeCall object and call the makeCallWithCompletionHandler method:

- (void)didConnect:(StringeeClient *)stringeeClient isReconnecting:(BOOL)isReconnecting {
    NSLog(@"Successfully connected to Stringee Server, user ID: %@", stringeeClient.userId);

    StringeeCall * stringeeCall = [[StringeeCall alloc] initWithStringeeClient:self.stringeeClient isIncomingCall:NO from:@"+1273065979" to:@"+1909982888"];
    [stringeeCall makeCallWithCompletionHandler:^(BOOL status, int code, NSString * message){
        NSLog(@"Make call result: code=%d, message: %@", code, message);
    }];
}

Handle the call type

The type of the outgoing call (app-to-app or app-to-phone) is decided by Your Server via the project's answer_url. So you can definitely do it by yourself. But we provide an easy way that help you 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.

Step 6: Receiving call events

Implements 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;

Step 7: Receiving incoming call event

Implements 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;

Step 8: Answer a call

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);
    }];

Step 9: Hanging up a call

Call the following method to Hang up a call.

    [stringeeCall hangupWithCompletionHandler:^(BOOL status, int code, NSString *message) {
        NSLog(@"%@", message);
    }];

Step 10: Reject a call

Call the following method to reject a call.

    [stringeeCall rejectWithCompletionHandler:^(BOOL status, int code, NSString *message) {
        NSLog(@"%@", message);
    }];

Step 11: Video call

  1. A Stringee call is a voice call by default. If you want to make a video call, you must assign:
stringeeCall.isVideoCall = YES;
  1. Display local video
-(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];
    });
}
  1. Display remote video

Implements 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];
    });
}
  1. Loudspeaker
- (void)didChangeMediaState:(StringeeCall *)stringeeCall mediaState:(MediaState)mediaState {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (mediaState == MediaStateConnected) {
            [[StringeeAudioManager instance] setLoudspeaker:YES];
        }
    });
}

Step 12: Sample

You can view a completed version of this sample app on GitHub: https://github.com/stringeecom/ios-sdk-samples