Get Started

Twilio Client for iOS Quickstart Tutorial

Make Outgoing Calls

The Xcode project

Next, open the "HelloMonkey.xcodeproj" Xcode project in HelloMonkey 1.0. This is a project based on the "View-based Application" template for iPhone that has already been configured to work with the Twilio Client library. Please see the "Getting Started" guide in the SDK documentation for details on modifying an Xcode project to use Twilio Client.

The HelloMonkey app is very simple, presenting "Dial" and "Hangup" buttons, and a text field for who the app should call. The user interface elements have already been wired up to the HelloMonkeyViewController class in Interface Builder but don't actually do anything.

In this Quickstart you'll fill in the code to give the app its behavior, learning how to use the Twilio Client iOS SDK in the process.

Creating a Device

An instance of TCDevice, an Objective-C class, represents a soft device that knows how to speak to Twilio services. You'll use a TCDevice to initiate outgoing calls and listen for incoming calls. Let's create an instance and wire it up!

There's a class called MonkeyPhone that represents a central coordinator object to talk to the Twilio Client APIs, and this is where the bulk of the functionality will live.

Add a member variable of type TCDevice to MonkeyPhone.h like so:

MonkeyPhone.h
#import <Foundation/Foundation.h>

#import "TCDevice.h"

@interface MonkeyPhone : NSObject
{
@private
    TCDevice* _device;
}

@end

Let's initialize it and dispose of it properly in init and dealloc, respectively.

To initialize a device, you'll change the URL to point to your server's auth.php file and pass the resulting string to -initWithCapabilityToken:delegate:. We'll also dispose of the device in dealloc.

Make sure you swap in your Capability Token URL for the sample URL in MonkeyPhone's `init` method.
MonkeyPhone.m
-(id)init
{
    if ( self = [super init] )
    {
        NSURL* url = [NSURL URLWithString:@"http://companyfoo.com/auth.php"];
        NSURLResponse* response = nil;
        NSError* error = nil;
        NSData* data = [NSURLConnection sendSynchronousRequest:
            [NSURLRequest requestWithURL:url] 
            returningResponse:&response
            error:&error];
        if (data)
        {
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;

            if (httpResponse.statusCode == 200)
            {
                NSString* capabilityToken = 
                    [[[NSString alloc] initWithData:data
                    encoding:NSUTF8StringEncoding] 
                    autorelease];

                _device = [[TCDevice alloc] initWithCapabilityToken:capabilityToken
                    delegate:nil];
            }
            else
            {
                NSString*  errorString = [NSString stringWithFormat:
                    @"HTTP status code %d",                          
                    httpResponse.statusCode];
                NSLog(@"Error logging in: %@", errorString);
            }
        }
        else
        {
            NSLog(@"Error logging in: %@", [error localizedDescription]);
        }
    }
    return self;
}


-(void)dealloc
{
    [_device release];
    [super dealloc];
}

If you compile and run this code, you should see the following:

iOS app with Dial and Hangup buttons

Now we've got an app that can create outgoing connections and receive incoming connections.

For the time being we'll focus on making an outgoing connection. The connection will call a Twilio sample application that responds with a friendly greeting.

Dialing Out

Let's add a method to MonkeyPhone to initiate a connection. We'll keep track of the connection we've created as a member variable of type TCConnection. To make a connection, we call the TCDevice's connect:(NSDictionary*) delegate:(id<TCConnectionDelegate>)delegate method. Just pass in nil parameters and a nil delegate for the moment; we'll do more with these arguments later.

MonkeyPhone.h
#import "TCDevice.h"
#import "TCConnection.h"

@interface MonkeyPhone : NSObject
{
@private
    TCDevice* _device;
    TCConnection* _connection;
}

-(void)connect;

@end
MonkeyPhone.m
#import "MonkeyPhone.h"

@implementation MonkeyPhone

// … unchanged code omitted for brevity

-(void)dealloc
{
    [_device release];
    [_connection release];
    [super dealloc];
}

-(void)connect
{
    _connection = [_device connect:nil delegate:nil];
    [_connection retain];
}

@end

If you take a look at the HelloMonkeyAppDelegate, you'll notice it has a property MonkeyPhone* phone specified. When the App Delegate is launched, it initializes a MonkeyPhone object and sets it as the value of the phone property.

So now in the -(IBAction)dialButtonPressed:(id)sender method, fetch the MonkeyPhone from the app delegate, and invoke -(void)connect on it like so:

HelloMonkeyViewController.m
#import "HelloMonkeyViewController.h"
#import "HelloMonkeyAppDelegate.h"
#import "MonkeyPhone.h"

@implementation HelloMonkeyViewController

// … unchanged code omitted for brevity
-(IBAction)dialButtonPressed:(id)sender
{
    HelloMonkeyAppDelegate* appDelegate = (HelloMonkeyAppDelegate*)[UIApplication sharedApplication].delegate;
    MonkeyPhone* phone = appDelegate.phone;
    [phone connect];
}

// … unchanged code omitted for brevity

@end

If you now compile the app and run it, you should be able to click the "Dial" button and hear the greeting. Awesome!

Wouldn't it be nice if you could also hang up on a connection if you don't want to hear the whole thing? Let's go do that now.


Next: Hanging up from your iOS Device »