# How to request an Access Token from iOS

Looking to add Voice, Video, Conversations, or Sync to your iOS mobile application? You'll need to provide an [access token](/docs/iam/access-tokens) 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](/docs/iam/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](https://github.com/TwilioDevEd/?utf8=%E2%9C%93\&q=sdk-starter-\&type=\&language=) as a server. If you don't have one in particular you want to use, the [SDK Starter for Node.js](https://github.com/TwilioDevEd/sdk-starter-node) is pretty straightforward.

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 retrieving 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.

Requesting an Access Token from iOS

```objective-c
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];
```

```swift
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()
}
```

> \[!WARNING]
>
> 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`

```swift title="Parsing a JSON Token Response"
// !mark(1:4,13:20)
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 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](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types).

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.

The next step would be to use that access token to initialize a Twilio product such as Video, [Voice](/docs/voice), [Conversations](/docs/chat), or [Sync](/docs/sync). Check out our Twilio [iOS Quickstarts](/docs) to get started and learn more!
