Using the Twilio API / SDK to Build a Basic Phone App on iOS
Twilio documentation suggests building a simple iOS app that hosts and accepts calls. There is even a sample project. An example project called MonkeyPhone has ARC bugs, so it refuses to start.
Broader question: Is Twilio the best API / platform for consuming and receiving calls in an ios or Android app?
source to share
You can use the TCConnectionDelegate methods for this. It handles your calling procedure automatically.
Here are a few steps you will need to follow.
1.> First you need to create a twilio account and get the sid and auth id
2.> After that go to Dev Tools -> TWIML Apps
Create a new twiml app and build
Please provide the request URL where you will submit your phone number.
3.> Send your phone number to TCConnectionDelegate connection method
YourTwilioDeviceClass *phone = appDelegate.phone;
[phone connect:self.textFieldPhoneNumber.text];
4.> Now get an authentication token by passing accountSid, authToken, appId to the auth.php file on the server.
#pragma mark -
#pragma mark TCDevice Capability Token
-(NSString*)getCapabilityToken:(NSError**)error
{
//Creates a new capability token from the auth.php file on server
NSString *capabilityToken = nil;
NSString *accountSid = [[NSUserDefaults standardUserDefaults] objectForKey:@"accountSid"];
NSString *authToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"authToken"];
NSString *appId = [[NSUserDefaults standardUserDefaults] objectForKey:@"appId"];
//Make the URL Connection to your server
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.yourauthfilepath.com/twillo/auth.php?accountSid=%@&authToken=%@&appSid=%@",accountSid,authToken,appId]];
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url]
returningResponse:&response error:error];
if (data)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (httpResponse.statusCode==200)
{
capabilityToken = [[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding] autorelease];
}
else
{
//*error = [ConferencePhone errorFromHTTPResponse:httpResponse domain:@"CapabilityTokenDomain"];
}
}
// else there is likely an error which got assigned to the incoming error pointer.
return capabilityToken;
}
-(BOOL)capabilityTokenValid
{
//Check TCDevice capability token to see if it is still valid
BOOL isValid = NO;
// NSLog(@"_device.capabilities %@",_device.capabilities);
NSNumber *expirationTimeObject = [_device.capabilities objectForKey:@"expiration"];
long long expirationTimeValue = [expirationTimeObject longLongValue];
long long currentTimeValue = (long long)[[NSDate date] timeIntervalSince1970];
if ((expirationTimeValue-currentTimeValue)>0)
isValid = YES;
return isValid;
}
#pragma mark -
#pragma mark Device Network connect and disconnect
-(void)connect:(NSString*)phoneNumber
{
// first check to see if the token we have is valid, and if not, refresh it.
// Your own client may ask the user to re-authenticate to obtain a new token depending on
// your security requirements.
HelloMonkeyAppDelegate *appDelegate=(HelloMonkeyAppDelegate*)[[UIApplication sharedApplication]delegate];
if (![self capabilityTokenValid] || (!appDelegate.isTokenGet))
{
//Capability token is not valid, so create a new one and update device
[self login];
}
if (![self reachabiltyCheck])
{
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"5", nil] forKeys:[NSArray arrayWithObjects:CPLoginDidFailWithError, nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
HelloMonkeyAppDelegate *appDelegate=(HelloMonkeyAppDelegate*)[[UIApplication sharedApplication]delegate];
appDelegate.isTokenGet=FALSE;
}
else
{
NSDictionary* parameters = nil;
if ( [phoneNumber length] > 0 )
{
parameters = [NSDictionary dictionaryWithObject:phoneNumber forKey:@"PhoneNumber"];
}
NSLog(@"parameters ===%@",parameters);
_connection = [_device connect:parameters delegate:self];
[_connection retain];
}
}
-(void)disconnect
{
[_connection disconnect];
[_connection release];
_connection = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:@"hideCallingView" object:nil];
}
#pragma mark -
#pragma mark - TCConnection Delegate Methods
-(void)connectionDidDisconnect:(TCConnection*)connection
{
NSLog(@"Call disconnected");
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"4", nil] forKeys:[NSArray arrayWithObjects:@"Disconnected", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)connection:(TCConnection*)connection didFailWithError:(NSError*)error
{
NSLog(@"Failed %@",[error description]);
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"3", nil] forKeys:[NSArray arrayWithObjects:@"Error", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)connectionDidStartConnecting:(TCConnection*)connection
{
NSLog(@"Calling..");
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", nil] forKeys:[NSArray arrayWithObjects:@"Calling", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)connectionDidConnect:(TCConnection*)connection
{
NSLog(@"In call..");
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"2", nil] forKeys:[NSArray arrayWithObjects:@"In call", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)dealloc
{
[_device release];
[_connection release];
[super dealloc];
}
5.> Finally, use the TCConnectionDelegate methods
#pragma mark -
#pragma mark TCDevice Capability Token
-(NSString*)getCapabilityToken:(NSError**)error
{
//Creates a new capability token from the auth.php file on server
NSString *capabilityToken = nil;
NSString *accountSid = [[NSUserDefaults standardUserDefaults] objectForKey:@"accountSid"];
NSString *authToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"authToken"];
NSString *appId = [[NSUserDefaults standardUserDefaults] objectForKey:@"appId"];
//Make the URL Connection to your server
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.e-home.com/twillo/auth.php?accountSid=%@&authToken=%@&appSid=%@",accountSid,authToken,appId]];
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url]
returningResponse:&response error:error];
if (data)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (httpResponse.statusCode==200)
{
capabilityToken = [[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding] autorelease];
}
else
{
//*error = [ConferencePhone errorFromHTTPResponse:httpResponse domain:@"CapabilityTokenDomain"];
}
}
// else there is likely an error which got assigned to the incoming error pointer.
return capabilityToken;
}
-(BOOL)capabilityTokenValid
{
//Check TCDevice capability token to see if it is still valid
BOOL isValid = NO;
// NSLog(@"_device.capabilities %@",_device.capabilities);
NSNumber *expirationTimeObject = [_device.capabilities objectForKey:@"expiration"];
long long expirationTimeValue = [expirationTimeObject longLongValue];
long long currentTimeValue = (long long)[[NSDate date] timeIntervalSince1970];
if ((expirationTimeValue-currentTimeValue)>0)
isValid = YES;
return isValid;
}
#pragma mark -
#pragma mark Device Network connect and disconnect
-(void)connect:(NSString*)phoneNumber
{
// first check to see if the token we have is valid, and if not, refresh it.
// Your own client may ask the user to re-authenticate to obtain a new token depending on
// your security requirements.
HelloMonkeyAppDelegate *appDelegate=(HelloMonkeyAppDelegate*)[[UIApplication sharedApplication]delegate];
if (![self capabilityTokenValid] || (!appDelegate.isTokenGet))
{
//Capability token is not valid, so create a new one and update device
[self login];
}
if (![self reachabiltyCheck])
{
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"5", nil] forKeys:[NSArray arrayWithObjects:CPLoginDidFailWithError, nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
HelloMonkeyAppDelegate *appDelegate=(HelloMonkeyAppDelegate*)[[UIApplication sharedApplication]delegate];
appDelegate.isTokenGet=FALSE;
}
else
{
NSDictionary* parameters = nil;
if ( [phoneNumber length] > 0 )
{
parameters = [NSDictionary dictionaryWithObject:phoneNumber forKey:@"PhoneNumber"];
}
NSLog(@"parameters ===%@",parameters);
_connection = [_device connect:parameters delegate:self];
[_connection retain];
}
}
-(void)disconnect
{
[_connection disconnect];
[_connection release];
_connection = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:@"hideCallingView" object:nil];
}
#pragma mark -
#pragma mark - TCConnection Delegate Methods
-(void)connectionDidDisconnect:(TCConnection*)connection
{
NSLog(@"Call disconnected");
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"4", nil] forKeys:[NSArray arrayWithObjects:@"Disconnected", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)connection:(TCConnection*)connection didFailWithError:(NSError*)error
{
NSLog(@"Failed %@",[error description]);
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"3", nil] forKeys:[NSArray arrayWithObjects:@"Error", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)connectionDidStartConnecting:(TCConnection*)connection
{
NSLog(@"Calling..");
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", nil] forKeys:[NSArray arrayWithObjects:@"Calling", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)connectionDidConnect:(TCConnection*)connection
{
NSLog(@"In call..");
NSDictionary *dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"2", nil] forKeys:[NSArray arrayWithObjects:@"In call", nil]];
[[NSNotificationCenter defaultCenter] postNotificationName:@"showCallingStatusView" object:nil userInfo:dict];
}
-(void)dealloc
{
[_device release];
[_connection release];
[super dealloc];
}
Hope this helps you. Please let me know if you have any problems.
source to share