<commit_before>---
title: User Sessions
description: This tutorial will show you how to handle user sessions and retrieve the user's profile.
budicon: 280
---

<%= include('../../../_includes/_package', {
  org: 'auth0-samples',
  repo: 'auth0-ios-objc-sample',
  path: '03-User-Sessions',
  requirements: [
    'CocoaPods 1.2.1',
    'Version 8.3.2 (8E2002)',
    'iPhone 7 - iOS 10.3 (14E269)'
  ]
}) %>

## Before You Start

Before you continue with this tutorial, make sure that you are using the Swift wrapper and the Auth0 library to handle login. For more information, read the [Login](/quickstart/native/ios-objc/00-login) guide.

## Add the SimpleKeychain Dependency

Integrate the [SimpleKeychain](https://github.com/auth0/SimpleKeychain) library for managing user credentials.

### Carthage

If you are using Carthage, add the following to your `Cartfile`:

```ruby
github "auth0/SimpleKeychain"
```

Then, run `carthage bootstrap`.

::: note
For more information on how to use Carthage, read [their official documentation](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos).
:::

### Cocoapods

If you are using [Cocoapods](https://cocoapods.org/), add the following to your `Podfile`:

```ruby
pod 'SimpleKeychain', '~> 0.7'
```

Then, run `pod install`.

::: note
For more information on how to use Cocoapods, read the [Cocoapods documentation](http://guides.cocoapods.org/using/getting-started.html).
:::

## Save User Credentials When They Log in

When your users log in successfully, save their credentials. You can then log them in automatically when they open your application again.

${snippet(meta.snippets.setup)}

Then, present the hosted login screen:

```objc
// HomeViewController.m

HybridAuth *auth = [[HybridAuth alloc] init];
[auth showLoginWithScope:@"openid profile" connection:nil callback:^(NSError * _Nullable error, A0Credentials * _Nullable credentials) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (error) {
            NSLog(@"Error: %@", error);
        } else if (credentials) {
          // Do something with credentials e.g.: save them.
          // Auth0 will dismiss itself automatically by default.
        }
    });
}];
```

You need a valid access token. You can find the token in the `credentials` object. To save the access token, use an `A0SimpleKeychain` instance. `SimpleKeychain` can be a key-value storage.

```objc
// HomeViewController.m

A0SimpleKeychain *keychain = [[A0SimpleKeychain alloc] initWithService:@"Auth0"];
[keychain setString:accessToken forKey:@"access_token"];
```

## Check for an Access Token When the User Opens Your Application

When the user opens your application, check for an access token. If it exists, you can log the user in automatically and redirect them to the app's main flow without any additional login steps.

First, retrieve the access token value from the `accessToken` key in the keychain:

```objc
// HomeViewController.m

A0SimpleKeychain *keychain = [[A0SimpleKeychain alloc] initWithService:@"Auth0"];
NSString* accessToken = [keychain stringForKey:@"access_token"];
if (accessToken) {
    // accessToken exists
    // You still need to validate it!
}
```

## Validate the Access Token

Check if the user's access token is still valid. Use `Auth0` to fetch the user's profile:

```objc
// HomeViewController.m

[auth userInfoWithAccessToken:accessToken callback:^(NSError * _Nullable error, UserInfo * _Nullable profile) {
        if (error) {
            // accessToken has expired or no longer valid
        } else {
            // The accessToken is still valid and you have the user's profile
            // This would be a good time to store the profile
        }
}];
```

## Deal with a Non-Valid Access Token

Decide how to deal with a non-valid access token. You can choose between two options:
* Ask users to re-enter their credentials.
* Use `.renew(withRefreshToken: refreshToken)` with a [refresh_token](/refresh-token) to obtain a new valid access token.

If you want to ask your users to re-enter their credentials, clear all the values stored in the keychain:

```objc
// HomeViewController.m
A0SimpleKeychain *keychain = [[A0SimpleKeychain alloc] initWithService:@"Auth0"];
[keychain clearAll];
```

The rest of this tutorial shows you how to use a refresh token to obtain a new access token. 

The refresh token is a token string stored in the `Credentials` object after a successful login. The refresh token doesn't expire. 

::: note
Even though the refresh token cannot expire, it can be revoked. For more information, read the [refresh token documentation](/refresh-token) before you proceed with this tutorial.
:::

### Store the refresh token

::: note 
If you do not send `offline_access` as a scope during authentication, the refresh token can be `nil`.
:::

To get a new access token, you need to first save the refresh token after the user logs in. Go to the section where you're saving the access token and update it as follows: 

```objc
// HomeViewController.m

HybridAuth *auth = [[HybridAuth alloc] init];
[auth showLoginWithScope:@"openid profile offline_access" connection:nil callback:^(NSError * _Nullable error, A0Credentials * _Nullable credentials) {
       if (error) {
           // Handle the error
       } else {
           [auth userInfoWithAccessToken:accessToken callback:^(NSError * _Nullable error, UserInfo * _Nullable profile) {
               if (error) {
                     NSLog(@"Error: %@", error.localizedDescription);
               } else {<commit_msg>Update 03-user-sessions.md<commit_after>---
title: User Sessions
description: This tutorial will show you how to handle user sessions and retrieve the user's profile.
budicon: 280
---

<%= include('../../../_includes/_package', {
  org: 'auth0-samples',
  repo: 'auth0-ios-objc-sample',
  path: '03-User-Sessions',
  requirements: [
    'CocoaPods 1.2.1',
    'Version 8.3.2 (8E2002)',
    'iPhone 7 - iOS 10.3 (14E269)'
  ]
}) %>

## Before You Start

Before you continue with this tutorial, make sure that you are using the Swift wrapper and the Auth0 library to handle login. For more information, read the [Login](/quickstart/native/ios-objc/00-login) guide.

## Add the SimpleKeychain Dependency

Integrate the [SimpleKeychain](https://github.com/auth0/SimpleKeychain) library for managing user credentials.

### Carthage

If you are using Carthage, add the following to your `Cartfile`:

```ruby
github "auth0/SimpleKeychain"
```

Then, run `carthage bootstrap`.

::: note
For more information on how to use Carthage, read [their official documentation](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos).
:::

### Cocoapods

If you are using [Cocoapods](https://cocoapods.org/), add the following to your `Podfile`:

```ruby
pod 'SimpleKeychain', '~> 0.7'
```

Then, run `pod install`.

::: note
For more information on how to use Cocoapods, read the [Cocoapods documentation](http://guides.cocoapods.org/using/getting-started.html).
:::

## Save User Credentials When They Log in

When your users log in successfully, save their credentials. You can then log them in automatically when they open your application again.

${snippet(meta.snippets.setup)}

Then, present the hosted login screen:

```objc
// HomeViewController.m

HybridAuth *auth = [[HybridAuth alloc] init];
[auth showLoginWithScope:@"openid profile" connection:nil callback:^(NSError * _Nullable error, A0Credentials * _Nullable credentials) {
    dispatch_async(dispatch_get_main_queue(), ^{
        if (error) {
            NSLog(@"Error: %@", error);
        } else if (credentials) {
          // Do something with credentials e.g.: save them.
          // Auth0 will dismiss itself automatically by default.
        }
    });
}];
```

You need a valid access token. You can find the token in the `credentials` object. To save the access token, use an `A0SimpleKeychain` instance. `SimpleKeychain` can be a key-value storage.

```objc
// HomeViewController.m

A0SimpleKeychain *keychain = [[A0SimpleKeychain alloc] initWithService:@"Auth0"];
[keychain setString:accessToken forKey:@"access_token"];
```

## Check for an Access Token When the User Opens Your Application

When the user opens your application, check for an access token. If it exists, you can log the user in automatically and redirect them to the app's main flow without any additional login steps.

First, retrieve the access token value from the `accessToken` key in the keychain:

```objc
// HomeViewController.m

A0SimpleKeychain *keychain = [[A0SimpleKeychain alloc] initWithService:@"Auth0"];
NSString* accessToken = [keychain stringForKey:@"access_token"];
if (accessToken) {
    // accessToken exists
    // You still need to validate it!
}
```

## Validate the Access Token

Check if the user's access token is still valid. Use `Auth0` to fetch the user's profile:

```objc
// HomeViewController.m

[auth userInfoWithAccessToken:accessToken callback:^(NSError * _Nullable error, UserInfo * _Nullable profile) {
        if (error) {
            // accessToken has expired or no longer valid
        } else {
            // The accessToken is still valid and you have the user's profile
            // This would be a good time to store the profile
        }
}];
```

## Deal with a Non-Valid Access Token

Decide how to deal with a non-valid access token. You can choose between two options:
* Ask users to re-enter their credentials.
* Use `.renew(withRefreshToken: refreshToken)` with a [refresh_token](/refresh-token) to obtain a new valid access token.

If you want to ask your users to re-enter their credentials, clear all the values stored in the keychain:

```objc
// HomeViewController.m
A0SimpleKeychain *keychain = [[A0SimpleKeychain alloc] initWithService:@"Auth0"];
[keychain clearAll];
```

The rest of this tutorial shows you how to use a refresh token to obtain a new access token. 

The refresh token is a token string stored in the `Credentials` object after a successful login. The refresh token doesn't expire. 

::: note
Even though the refresh token cannot expire, it can be revoked. For more information, read the [refresh token documentation](/refresh-token) before you proceed with this tutorial.
:::

### Store the refresh token

::: note 
If you do not send `offline_access` as a scope during authentication, the refresh token will be `nil`.
:::

To get a new access token, you need to first save the refresh token after the user logs in. Go to the section where you're saving the access token and update it as follows: 

```objc
// HomeViewController.m

HybridAuth *auth = [[HybridAuth alloc] init];
[auth showLoginWithScope:@"openid profile offline_access" connection:nil callback:^(NSError * _Nullable error, A0Credentials * _Nullable credentials) {
       if (error) {
           // Handle the error
       } else {
           [auth userInfoWithAccessToken:accessToken callback:^(NSError * _Nullable error, UserInfo * _Nullable profile) {
               if (error) {
                     NSLog(@"Error: %@", error.localizedDescription);
               } else {
{'fraction_non_alphanumeric': 0.10269541778975741, 'fraction_numerical': 0.00880503144654088, 'mean_word_length': 3.8207016024252924, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5321583', 'n_tokens_mistral': 3303, 'n_tokens_neox': 3100, 'n_words': 1265}