# Quick Reference

> \[!WARNING]
>
> The TwilioAuth SDK has been deprecated. This means that while we will continue to provide maintenance support for existing customers and their usage, we discourage new customers and new usage, as we may shut it down entirely in the future. We strongly recommend using the [Verify Push SDK](/docs/verify/push) instead, which currently supports the Push channel, and will be enhanced to support the TOTP channel in the future.

For iOS projects, make sure you import the framework in the files in which you will interact with the SDK.

Import TwilioAuth framework

```objective-c
#import <TwilioAuth/TwilioAuth.h>
```

```swift
import TwilioAuth
```

## Setup TwilioAuth instance

Setup TwilioAuth instance

```java
TwilioAuth twilioAuth = TwilioAuth.getInstance(this);
```

```objective-c
TwilioAuth *sharedTwilioAuth = [TwilioAuth sharedInstance];
```

```swift
let sharedTwilioAuth = TwilioAuth.sharedInstance()
```

## Register the device with the Authy service

Register device

```java
// You should obtain the registration token from your backend 
// pushToken is optional and you include it if you want us to handle push notifications  
twilioAuth.registerDevice(registrationToken, pushToken);
```

```objective-c
// You should obtain the registration token from your backend
// `pushToken` is optional, you should include it if you want us to handle push notifications
// the push token is obtained when registering your app for push notifications.
[sharedTwilioAuth registerDeviceWithRegistrationToken:registrationToken pushToken:pushToken completion:^(NSError *error) {
	// ...
}];
```

```swift
// You should obtain the registration token from your backend
// `pushToken` is optional, you should include it if you want us to handle push notifications
// the push token is obtained when registering your app for push notifications.
sharedTwilioAuth.registerDevice(withRegistrationToken: registrationToken pushToken: pushToken) { error in
    // ...
}
```

Make sure the current device is registered by calling `isDeviceRegistered`.

Check if device is registered

```java
boolean isDeviceRegistered = twilioAuth.isDeviceRegistered()
```

```objective-c
BOOL isDeviceRegistered = [sharedTwilioAuth isDeviceRegistered];
```

```swift
let isDeviceRegistered = sharedTwilioAuth.isDeviceRegistered()
```

To obtain the device id, call the `getDeviceId` method. This method will be useful for device specific operations such as deletion.

Get Device ID

```java
String deviceId = twilioAuth.getDeviceId();
```

```objective-c
NSString *deviceId = [sharedTwilioAuth getDeviceId];
```

```swift
let deviceId = sharedTwilioAuth.getDeviceId()
```

## Approval Requests

To create a new approval request, you can follow the instructions [here](/docs/authy/api/push-authentications#create-an-approval-request) or use the pre-built Authy API scripts available [here](https://github.com/AuthySE/Authy-API-Samples).

Call `getApprovalRequests` to get the list of approval requests:

Get approval requests

```java
long since = ...; // lower limit
long until= ...; // upper limit
TimeInterval timeInterval = new TimeInterval.Builder()
                                         .setSince(since)
                                         .setUntil(until)
                                         .build();
List<ApprovalRequestStatus> statuses = Arrays.asList(
                                              ApprovalRequestStatus.approved, 
                                              ApprovalRequestStatus.denied, 
                                              ApprovalRequestStatus.expired, 
                                              ApprovalRequestStatus.pending);

twilioAuth.getApprovalRequests(statuses, timeInterval);
```

```objective-c
NSArray *statuses = @[AUTApproveStatus, AUTDenyStatus, AUTPendingStatus, AUTExpiredStatus];
AUTTimeInterval *timeInterval = [[AUTTimeInterval alloc] init];
long since = ... // lower limit
long until = ... // upper limit
timeInterval.sinceTimestamp = since;
timeInterval.untilTimestamp = until;

[sharedTwilioAuth getApprovalRequestsWithStatuses:statuses timeInterval:timeInterval completion:^(AUTApprovalRequests *approvalRequests, NSError *error) {
	// ...
}];
```

```swift
let statuses = [AUTApproveStatus, AUTDenyStatus, AUTPendingStatus, AUTExpiredStatus]
let timeInterval = AUTTimeInterval()
let since = ... // lower limit
let until = ... // upper limit
timeInterval.sinceTimestamp = since
timeInterval.untilTimestamp = until

sharedTwilioAuth.getApprovalRequests(withStatuses: statuses, timeInterval: timeInterval) { (requests, error) in
	// ...	
}
```

Call `approveRequest` or `denyRequest` to handle approval requests.

Approve or deny a request

```java
// Approve
authy.approveRequest(approvalRequest);

// Deny
authy.denyRequest(approvalRequest);
```

```objective-c
[sharedTwilioAuth approveRequest:approvalRequest completion:^(BOOL success, NSError *error) {
	// ...
}];

[sharedTwilioAuth denyRequest:approvalRequest completion:^(BOOL success, NSError *error) {
	// ...
}];
```

```swift
sharedTwilioAuth.approveRequest(approvalRequest, completion: { (error: AUTError?) -> Void in
    // ...
})

sharedTwilioAuth.denyRequest(approvalRequest, completion: { (error: AUTError?) -> Void in
    // ...
})
```

If you configured a callback URL in the [Dashboard](https://dashboard.authy.com/) to receive notifications when a user approves/denies a request it will be called after this step. Otherwise you should poll the OneTouch API. For more details go [here.](/docs/authy/api)

## Push notification handling

In order to interact with the request notifications you will need to update the push token every time it changes in the device.

Register push token

```java
// pushToken is optional and you include it if you want us to handle push notifications  
twilioAuth.setPushToken(pushToken);
```

```objective-c
// If you want us to handle push notifications you should let us know when 
// the push token changed in the device
[sharedTwilioAuth setPushToken:deviceTokenAsString completion:^(NSError * _Nullable error) {

    if (!error) {
        // Push token configured successfully
    }

}];
```

```swift
// If you want us to handle push notifications you should let us know when 
// the push token changed in the device
sharedTwilioAuth.setPushToken(pushToken) { error in

}
```

Once the notification arrives, you will need to pull it from the TwilioAuth API. The reason for this is that it contains sensitive information, so the device must retrieve it through the TwilioAuth SDK instead of having it directly in the notification payload.

Handle push notifications

```java
public class MessagingService extends FirebaseMessagingService {
    private static final String TAG = MessagingService.class.getSimpleName();
    public static final String ONETOUCH_APPROVAL_REQUEST_TYPE = "onetouch_approval_request";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() == 0) {
            Log.e(TAG, "Received notification with empty payload");
            return;
        }

        if (ONETOUCH_APPROVAL_REQUEST_TYPE.equals(remoteMessage.getData().get("type"))) {
            
            // Since the approval request has sensitive data, we'll fetch it in background with
            // the request uuid instead of delivering the information within the userInfo.

            // Get the approval request id
            String approvalRequestUuid = remoteMessage.getData().get("approval_request_uuid");

            TwilioAuth twilioAuth = ((App) getApplicationContext()).getTwilioAuth();

            if (!twilioAuth.isDeviceRegistered()) {
                throw new RuntimeException("Device should be registered");
            }

            ApprovalRequest approvalRequest;

            try {
                ApprovalRequests approvalRequests = twilioAuth.getApprovalRequests(null, null);

                approvalRequest = approvalRequests.getApprovalRequestById(approvalRequestUuid);

            } catch (TwilioException e) {
                throw new RuntimeException(e);
            }

            if (approvalRequest != null) {
                // Do something with the pending approvalRequest
            }
        }

    }
```

```objective-c
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo {

    NSString *notificationType = [userInfo objectForKey:@"type"];
    if (![notificationType isEqualToString:@"onetouch_approval_request"]) {
        return;
    }

    NSString *approvalRequestUUID = [userInfo objectForKey:@"approval_request_uuid"];
    TwilioAuth *twilioAuth = [TwilioAuth sharedInstance];
    
    // Since the approval request has sensitive data, we'll fetch it in background with the 
    // request uuid instead of delivering the information within the userInfo.

    [twilioAuth getRequestWithUUID:approvalRequestUUID completion:^(AUTApprovalRequest *request, NSError *error) {

        if (error != nil) {
            return;
        }

        if ([request.uuid isEqualToString:approvalRequestUUID]) {

            // Do something with the pendingRequest
            return;
        }

    }];

}
```

```swift
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
    guard
        let approvalRequestUUID = userInfo["approval_request_uuid"] as? String,
        let notificationType = userInfo["type"] as? String, notificationType == "onetouch_approval_request"
        else {
            return
    }
    
    let twilioAuth = TwilioAuth.sharedInstance() as! TwilioAuth
    
    // Since the approval request has sensitive data, we'll fetch it in background with the 
    // request uuid instead of delivering the information within the userInfo.
    
    twilioAuth.getRequestWithUUID(approvalRequestUUID)
    { request, error in
        
        if error != nil {
            // Error fetching approval request
            return
        }
        
        guard let request = request else { return }

        if request.uuid == approvalRequestUUID {
            
            // Do something with the pendingRequest
            print(request)

        }
    }
}
```

## Time-based One Time Passwords (TOTP)

As a fallback when OneTouch requests aren't functioning (more specifically, if the user is in Airplane mode, has no Wi-Fi/cell connection, misses the push notification, or prefers to type the generated code in for validation instead of pushing the Approve/Deny button) you can obtain a TOTP.

The TOTP will be valid for 30 seconds and you can obtain it as follows:

Get TOTP

```java
twilioAuth.getTOTP(this);
```

```objective-c
[sharedTwilioAuth getTOTPWithDelegate:self];
```

```swift
sharedTwilioAuth.getTOTPWith(self)
```

Additionally your class must implement the AUTTOTPDelegate protocol (on iOS) or the TOTPCallback interface (on Android) to be able to receive the TOTP:

Implement AUTTOTPDelegate/TOTPCallback

```java
public class TokensFragment extends Fragment implements TOTPCallback {
	// ...

	void onTOTPReceived(String totp) {
		// Display TOTP
	}

	void onTOTPError(Exception exception) {
		// Handle error
	}
}
```

```objective-c
@interface TOTPViewController : UIViewController <AUTTOTPDelegate>
	// ...
@end

@implementation TOTPViewController

	// ...

- (void)didReceiveTOTP:(NSString *)totp withError:(NSError *)error {
	// ...
}

@end
```

```swift
class TOTPViewController: UIViewController, AUTTOTPDelegate {

	// ...

	func didReceiveTOTP(_ totp: String?, withError error: Error?) {
		// ...
	}

}
```

### Important note

This delegate/callback listener will receive a TOTP immediately, which will be generated with the local token. Then the SDK will try to sync the token with TwilioAuth API in the background. If that token differs (i.e. digits changed, seed was rotated, or token was removed) your delegate will receive another call with the newest TOTP.

## Helper methods

To delete the device local data you can use the following method:

Clear Local Data

```java
twilioAuth.clearLocalData();
```

```objective-c
[sharedTwilioAuth clearLocalData];
```

```swift
sharedTwilioAuth.clearLocalData()
```

**Note**: This method doesn't delete the device in the Authy backend, it only clears the data stored locally on the device. For example, you may use this method as a logout option inside your app.

## Support

If you find any inconveniences while following this guide please file us an issue

[Android issues on github.com](https://github.com/twilio/mobile-sdk-sample-android/issues)

[iOS issues on github.com](https://github.com/twilio/mobile-sdk-sample-ios/issues)
