How to request an Access Token from iOS

Looking to add Voice, Video, Chat, or Sync to your iOS mobile application? You'll need to provide an access token from your server to the Twilio library for that product. 

There are two steps to getting this set up - the first is to create an access token for your end user's mobile application from your server. For instance, based on their user profile, they could have the ability to join a video room for a tutoring session with another user. You can learn more about how to create access tokens from the programming language of your choice (Java, C#, Ruby, Python, PHP, or Node.js). If you're looking to experiment, try out one of our SDK Starter projects as a server. If you don't have one in particular you want to use, the SDK Starter for Node.js is pretty straight forward.

The second step is to request that access token from your server application - which is what we will cover in this guide. We will use the standard iOS networking library to make an HTTPS call to our server. 

Retrieve an Access Token with URLSession

Our code for retrieiving the access token will differ slightly, based on whether we are using Swift or Objective-C. If you're new to iOS development, Swift is probably easier to pick up and get started with.

We will use the URLSession (NSURLSession with Objective-C) class as the basis for our approach. The iOS networking library uses configurable sessions that can create individual tasks that perform a network request. These tasks can either retrieve data, download a file, or upload a file - all of which are different subclasses of the URLSessionTask/NSURLSessionTask class. To retrieve an access token, we would use a data task, which would be an instance of the URLSessionDataTask/NSURLSessionDataTask class. You create a data task from a URLSession or NSURLSession object - usually you would use the shared singleton object available on the URLSession/NSURLSession class.

Typically, we would use an HTTP GET request to retrieve an access token from a given URL.

The dataTask function on URLSession that we will use takes a URL and a closure (completion block in Objective-C) as an argument. Your closure will get the HTTP response, the Data/NSData returned by the server, and an error (if there was one) as arguments. We check to see if the error exists, and if it does not, we create a string from the Data and print it out. Be sure to call resume on the task to initiate the HTTP Request - this step is easily forgotten. 

Loading Code Samples...
Language
NSString* functionURL = @"https://your-server-here/token";
NSURL *url = [NSURL URLWithString:functionURL];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error: %@",error);
    } else {
        NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"Response: %@", responseString);
    }
}];
[task resume];
let tokenURL = "https://your-server-here/token"
if let url = URL(string: tokenURL) {
    let task = URLSession.shared.dataTask(with: url) {
        data, response, error in
        if error != nil {
            print(error!)
        } else {
            if let responseString = String(data: data!, encoding: .utf8) {
                print(responseString)
            }
        }
    }
    task.resume()
}
Requesting an Access Token from iOS

When you use the Xcode playground with Swift to try out HTTP networking, the playground will send the HTTP request, and then immediately move on to the next line of code - when the playground gets to the last line of code, execution will stop, and your HTTP response won't be logged. You will need to enable a special setting for Xcode playgrounds and network calls if you are trying this outside of a mobile app.

To do this, you will need to import the PlaygroundSupport framework, and then include this line of code at the bottom:

PlaygroundPage.current.needsIndefiniteExecution = true

 

Loading Code Samples...
Language
struct TokenResponse: Decodable {
    var identity: String
    var token: String
}

func requestToken() {
    let tokenURL = "https://your-server-here/token"
    
    let decoder = JSONDecoder()
    if let url = URL(string: tokenURL) {
        let task = URLSession.shared.dataTask(with: url) {
            data, response, error in
            if let json = data {
                do {
                    let tokenResponse = try decoder.decode(TokenResponse.self, from: json)
                    print(tokenResponse.identity)
                    print(tokenResponse.token)
                } catch {
                    print(error)
                }
            } else {
                if let error = error {
                    print(error)
                }
            }
        }
        task.resume()
    }
}
Parsing a JSON Token Response

Parsing a JSON Response with Swift

When we call the /token route from one of the SDK Starter Kit servers, the response will come back as JSON with an identity and a corresponding access token. Using the new Decodable protocol in Swift 4, we can have a struct that models this response. See Apple's documentation for more on encoding and decoding JSON with Swift.

In our particular case, the struct will contain two strings - identity and token - and only needs to be decodable as we aren't encoding data as JSON to send it back to the server.

Be sure to wrap the JSON decoding in a do...try...catch block, so that you can catch any JSON parsing errors.

Whether you are using your own server to provide access tokens, or one of our SDK starter kit servers, you can see how easy it is to retrieve an access token using iOS's standard library.

The next step would be to use that access token to initialize a Twilio product such as Video, Voice, Chat, or Sync. Check out our Twilio iOS Quickstarts to get started and learn more!

Jeff Linwood
Kat King

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

1 / 1
Loading Code Samples...
NSString* functionURL = @"https://your-server-here/token";
NSURL *url = [NSURL URLWithString:functionURL];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error: %@",error);
    } else {
        NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"Response: %@", responseString);
    }
}];
[task resume];
let tokenURL = "https://your-server-here/token"
if let url = URL(string: tokenURL) {
    let task = URLSession.shared.dataTask(with: url) {
        data, response, error in
        if error != nil {
            print(error!)
        } else {
            if let responseString = String(data: data!, encoding: .utf8) {
                print(responseString)
            }
        }
    }
    task.resume()
}
struct TokenResponse: Decodable {
    var identity: String
    var token: String
}

func requestToken() {
    let tokenURL = "https://your-server-here/token"
    
    let decoder = JSONDecoder()
    if let url = URL(string: tokenURL) {
        let task = URLSession.shared.dataTask(with: url) {
            data, response, error in
            if let json = data {
                do {
                    let tokenResponse = try decoder.decode(TokenResponse.self, from: json)
                    print(tokenResponse.identity)
                    print(tokenResponse.token)
                } catch {
                    print(error)
                }
            } else {
                if let error = error {
                    print(error)
                }
            }
        }
        task.resume()
    }
}