Installation and usage

The Tanker Client SDK is available as a CocoaPods package. To use it, add the following lines in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/TankerHQ/PodSpecs.git'

target 'MyApp' do
  use_frameworks!
  pod 'Tanker'
end

To install the dependency, run:

$ pod install && pod update Tanker

To use Tanker in your application:

@import Tanker;

@interface MyClass : NSObject
@property TKRTanker* tanker;

@end

@implementation MyClass


- (instancetype)init
{
  if (self = [super init])
  {
    TKRTankerOptions* opts = [TKRTankerOptions options];
    opts.appID = @"YOUR_APP_ID";
    opts.writablePath = getWritablePath();
    self.tanker = [TKRTanker tankerWithOptions:opts];
  }
  return self;
}

NSString* getWritablePath()
{
  NSArray *paths = NSSearchPathForDirectoriesInDomains(
    NSLibraryDirectory,
    NSUserDomainMask,
    YES
  );
  NSString *libraryDirectory = [paths objectAtIndex:0];
  return libraryDirectory;
}


@end

Note

We use NSSearchPathForDirectoriesInDomains to make sure we have a writable folder that the Tanker Client SDK can use to store persistent data.

Supported architectures

The Tanker Client SDK uses native code, and the binaries we provide are compatible with the following architectures:

  • For iOS devices: armv7, armv7s, armv8.
  • For the iOS simulator: x86, x86_64.

The SDK is compatible with the latest Xcode release.

Error handling

Errors are reported with NSError, with the TKRErrorDomain domain, and a TKRError code.

NSString* identity = /* ... */;
[tanker startWithIdentity:identity completionHandler:
  ^(NSError* err)
  {
    if (err != nil) {
      NSLog(@"An error occurred: %@", err.localizedDescription);
      if (err.code == TKRErrorInvalidArgument) {
        /* ... */
      }
    }
  }
];

Here is the list of possible errors:

TKRError Description
TKRErrorInvalidArgument Developer error, one of the function's argument is invalid
TKRErrorNetworkError Network error, e.g. connection lost or the Tanker server is not reachable
TKRErrorPreconditionFailed Developer error, a function's precondition was violated
TKRErrorOperationCanceled An asynchronous operation was canceled when Tanker stopped
TKRErrorDecryptionFailed A decryption operation failed
TKRErrorGroupTooBig The group would exceed the maximum member limit (1000)
TKRErrorInvalidVerification An invalid identity verification was provided
TKRErrorTooManyAttempts An operation was attempted too many times, please try again later
TKRErrorExpiredVerification The identity verification is expired
TKRErrorInternalError Tanker internal error, thrown as a last resort
TKRErrorDeviceRevoked The device has been revoked

Constructor

TKRTankerOptions* opts = [TKRTankerOptions options];
opts.appID = @"YOUR_APP_ID";
opts.writablePath = @"/some/writable/path";

TKRTanker* tanker = [TKRTanker tankerWithOptions:opts];
Options
writablePath: NSString* The path where persistent data will be stored
appID: NSString* The app ID

Session management

startWithIdentity

Starts a Tanker session and returns a status. See the guide for more information on treating the status.

typedef void (^TKRStartHandler)(TKRStatus _Nullable status,
                                NSError* _Nullable err);

- (void)startWithIdentity:(nonnull NSString*)identity
        completionHandler:(nonnull TKRStartHandler)handler;
Parameters
identity: NSString* A Tanker identity
Handler return value Description
TKRStatusReady The session is ready and fully operational
TKRStatusIdentityRegistrationNeeded First use of the identity. registerIdentity must be called.
TKRStatusIdentityVerificationNeeded New device for this identity. verifyIdentityWithVerification must be called.
Errors Description
TKRErrorInvalidArgument The identity is invalid
TKRErrorPreconditionFailed The status is not TKRStatusStopped

stopWithCompletionHandler

Stops the current Tanker session.

typedef void (^TKRErrorHandler)(NSError* _Nullable err);

- (void)stopWithCompletionHandler:(nonnull TKRErrorHandler)handler;

TKRStatus

@property(readonly) TKRStatus status;

The following constants are available to check the status value:

Status Description
TKRStatusStopped The session is stopped. startWithIdentity() can be called on it.
TKRStatusReady The session is ready and fully operational
TKRStatusIdentityVerificationNeeded The session needs the identity to be verified to become TKRStatusReady
TKRStatusIdentityRegistrationNeeded This identity is not associated with any verification method. One must be registered.

Identity verification

TKRVerification

The TKRVerification class is an opaque type providing the following class methods:

+ (instancetype)verificationFromVerificationKey:(nonnull TKRVerificationKey*)key;
+ (instancetype)verificationFromEmail:(nonnull NSString*)email
                     verificationCode:(nonnull NSString*)code;
+ (instancetype)verificationFromPassphrase:(nonnull NSString*)passphrase;
+ (instancetype)verificationFromOIDCIDToken:(nonnull NSString*)oidcIDToken;

A TKRVerification object is typically used to perform an identity verification, or to register a new identity verification method.

TKRVerificationMethod

The TKRVerificationMethod class is a read-only type, returned by the verificationMethodsWithCompletionHandler function.

@property(readonly) TKRVerificationMethodType type;

// nil when type != TKRVerificationMethodTypeEmail
@property(readonly) NSString* email;

TKRVerificationMethod objects will be returned by functions that list identity verification methods available for an upcoming identity verification, such as getVerificationMethods() or attachProvisionalIdentity().

registerIdentityWithVerification

Registers the user's identity with which startWithIdentity() has been called, and starts the session.

The Tanker status must be TKRStatusIdentityRegistrationNeeded.

- (void)registerIdentityWithVerification:(nonnull TKRVerification*)verification
                       completionHandler:(nonnull TKRErrorHandler)handler;
Parameters Description
verification: TKRVerification* The verification required to register the identity
Errors Description
TKRErrorPreconditionFailed Status is not TKRStatusIdentityRegistrationNeeded
TKRErrorExpiredVerification The verification expired
TKRErrorInvalidVerification The verification is invalid
TKRErrorTooManyAttempts Too many verification attempts occurred. Please retry later.

verifyIdentityWithVerification

Verifies the user's identity with which startWithIdentity has been called, and starts the session.

The Tanker status must be TKRStatusIdentityVerificationNeeded.

- (void)verifyIdentityWithVerification:(nonnull TKRVerification*)verification
                     completionHandler:(nonnull TKRErrorHandler)handler;
Parameters Description
verification: TKRVerification* The verification required to verify the identity
Errors Description
TKRErrorPreconditionFailed Status is not TKRStatusIdentityVerificationNeeded
TKRErrorExpiredVerification The verification expired
TKRErrorInvalidVerification The verification is invalid
TKRErrorTooManyAttempts Too many verification attempts occurred. Please retry later.

setVerificationMethod

Adds or overrides a verification method.

The Tanker status must be TKRStatusReady.

- (void)setVerificationMethod:(nonnull TKRVerification*)verification
            completionHandler:(nonnull TKRErrorHandler*)handler;
Parameters Description
verification: TKRVerification* The verification to use
Errors Description
TKRErrorExpiredVerification The verification expired
TKRErrorInvalidVerification The verification is invalid.
TKRErrorPreconditionFailed Status is not TKRStatusReady
TKRErrorTooManyAttempts Too many verification attempts occurred. Please retry later.
TKRErrorDeviceRevoked The device has been revoked

verificationMethodsWithCompletionHandler

Returns the list of registered verification methods.

The Tanker status must be TKRStatusReady.

typedef void (^TKRVerificationMethodsHandler)(
    NSArray<TKRVerificationMethod*>* _Nullable methods, NSError* _Nullable err);

- (void)verificationMethodsWithCompletionHandler:(nonnull TKRVerificationMethodsHandler)handler;
Handler return value Description
methods An array of verification methods
Errors Description
TKRErrorPreconditionFailed The status is neither TKRStatusIdentityVerificationNeeded nor TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

generateVerificationKeyWithCompletionHandler

Generates a verification key, registers its public part on Tanker's servers, and returns its private part, which is required to verify the user's identity.

The Tanker status must be TKRStatusIdentityRegistrationNeeded.

typedef void (^TKRVerificationKeyHandler)(TKRVerificationKey* _Nullable key,
                                          NSError* _Nullable err);

- (void)generateVerificationKeyWithCompletionHandler:(nonnull TKRVerificationKeyHandler)handler;

Once the verification key has been generated, it is not possible to set up high-level verification methods (e.g. email/passphrase).

The opposite is also true: no high-level verification method must have been set up before calling this function.

It is NOT possible to generate several verification keys.

Warning

This is a low level function for specific use-cases only, as it can have severe security implications. Use it only if high-level identity verification doesn't fit your needs, and you fully understand how it works. Don't hesitate to contact us for help.

Handler return value Description
TKRVerificationKey* The verification key's private part
Errors Description
TKRErrorPreconditionFailed The status is not TKRStatusIdentityRegistrationNeeded

Device management

deviceIDWithCompletionHandler

Retrieves the current device's ID.

The Tanker status must be TKRStatusReady.

typedef void (^TKRDeviceIDHandler)(NSString* _Nullable deviceID,
                                   NSError* _Nullable err);

- (void)deviceIDWithCompletionHandler:(nonnull TKRDeviceIDHandler)handler;
Handler return value Description
NSString* The device ID
Errors Description
TKRErrorPreconditionFailed The status is not TKRStatusReady

getDeviceList

Retrieves the user's devices list.

Warning

Not implemented yet for iOS.

revokeDevice

Revokes one of the user's devices.

The status must be TKRStatusReady.

- (void)revokeDevice:(nonnull NSString*)deviceId
   completionHandler:(nonnull TKRErrorHandler)handler;
Parameters
deviceId: NSString The device ID of the device to revoke
Errors Description
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorInvalidArgument The device ID is not one of the users'
TKRErrorDeviceRevoked The device has been revoked

Encryption

encryptString

typedef void (^TKREncryptedDataHandler)(NSData* _Nullable encryptedData,
                                        NSError* _Nullable err);

- (void)encryptString:(nonnull NSString*)clearText
    completionHandler:(nonnull TKREncryptedDataHandler)handler;

- (void)encryptString:(nonnull NSString*)clearText
              options:(nonnull TKREncryptionOptions*)encryptionOptions
    completionHandler:(nonnull TKREncryptedDataHandler)handler;

Encrypts and shares a string.

The resulting encrypted resource will be shared with users and groups specified in the TKREncryptionOptions.

Note

The clearText string is UTF-8 encoded prior to encryption.

Parameters
clearText: NSString* The clear string to be encrypted
options: TKREncryptionOptions* Encryption options (optional)
Errors Description
TKRErrorInvalidArgument One of the provided user public identities or group IDs is invalid
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

encryptData

- (void)encryptData:(nonnull NSData*)clearData
  completionHandler:(nonnull TKREncryptedDataHandler)handler;

- (void)encryptData:(nonnull NSData*)clearData
            options:(nonnull TKREncryptionOptions*)encryptionOptions
  completionHandler:(nonnull TKREncryptedDataHandler)handler;

Encrypts and shares binary data.

The resulting encrypted resource will be shared with users and groups specified in the TKREncryptionOptions.

Parameters
clearData: NSData* The clear data to be encrypted
options: TKREncryptionOptions* Encryption options (optional)
Errors Description
TKRErrorInvalidArgument Some of the provided user public identities or group IDs are invalid
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

encryptStream

typedef void (^TKRInputStreamHandler)(NSInputStream* _Nullable stream,
                                      NSError* _Nullable err);

- (void)encryptStream:(nonnull NSInputStream*)clearStream
    completionHandler:(nonnull TKRInputStreamHandler)handler;

- (void)encryptStream:(nonnull NSInputStream*)clearStream
              options:(nonnull TKREncryptionOptions*)encryptionOptions
    completionHandler:(nonnull TKRInputStreamHandler)handler;

Creates an encryption stream wrapping clearStream.

The resource produced by the stream will be shared with either or both individual users and groups specified using the TKREncryptionOptions.

Warning

After calling this function, clearStream must not be used!

Parameters
clearStream: NSInputStream* The stream containing data to encrypt
options: TKREncryptionOptions* Encryption options (optional)
Errors Description
TKRErrorInvalidArgument One of the provided user public identities or group IDs is invalid
TKRErrorInvalidArgument clearStream status is not NSStreamStatusNotOpen
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

TKREncryptionOptions

The TKREncryptionOptions allows you to specify who will be able to decrypt the resource through the shareWithUsers and shareWithGroups properties.

If neither are specified, only the resource creator will be able to decrypt it.

In general, if you need to share a resource with multiple users, it is advised to create groups and use shareWithGroups.

Fields Default value Description
shareWithUsers: NSArray<NSString*>* @[] User public identities to share with (the current user is automatically included)
shareWithGroups: NSArray<NSString*>* @[] Group IDs to share with

decryptStringFromData

Decrypts an encrypted resource and UTF-8 decodes the result into a string.

The Tanker status must be TKRStatusReady.

typedef void (^TKRDecryptedStringHandler)(NSString* _Nullable decryptedString,
                                          NSError* _Nullable err);

- (void)decryptStringFromData:(nonnull NSData*)encryptedData
            completionHandler:(nonnull TKRDecryptedStringHandler)handler;
Parameters Description
encryptedData: NSData* The data to decrypt
Errors Description
TKRErrorDecryptionFailed The data could not be decrypted
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

decryptData

Decrypts an encrypted resource into binary data.

The Tanker status must be TKRStatusReady.

typedef void (^TKRDecryptedDataHandler)(NSData* _Nullable decryptedData,
                                        NSError* _Nullable err);

- (void)decryptData:(nonnull NSData*)encryptedData
  completionHandler:(nonnull TKRDecryptedDataHandler)handler;

Decrypts a resource and returns the original raw bytes.

Parameters Description
encryptedData: NSData* The data to decrypt
Errors Description
TKRErrorDecryptionFailed The data could not be decrypted
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

decryptStream

- (void)decryptStream:(nonnull NSInputStream*)encryptedStream
    completionHandler:(nonnull TKRInputStreamHandler)handler;

Creates a decryption stream wrapping encryptedStream.

Note

encryptedStream's content must have been encrypted by an encryption stream

Warning

After calling this function, encryptedStream must not be used!

Parameters
encryptedStream: NSInputStream* The stream containing data to decrypt
Errors Description
TKRErrorInvalidArgument encryptedStream status is not NSStreamStatusNotOpen
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDecryptionFailed The encrypted data is corrupted
TKRErrorDeviceRevoked The device has been revoked

Groups management

createGroupWithPublicIdentities

Creates a group with users' public identities, and returns its ID.

The Tanker status must be TKRStatusReady.

typedef void (^TKRGroupIDHandler)(NSString* _Nullable groupID,
                                  NSError* _Nullable err);

- (void)createGroupWithPublicIdentities:(nonnull NSArray<NSString*>*)publicIdentities
                      completionHandler:(nonnull TKRGroupIDHandler)handler;

Note

The maximum number of users per group is 1000.

Parameters Description
publicIdentities: NSArray<NSString*>* The users' public identities to add to the new group
Errors Description
TKRErrorInvalidArgument One of the public identities is invalid
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

updateMembersOfGroup

Add members to an existing group.

- (void)updateMembersOfGroup:(nonnull NSString*)groupId
                  usersToAdd:(nonnull NSArray<NSString*>*)users
           completionHandler:(nonnull TKRErrorHandler)handler;

The new group members will automatically get access to all resources previously shared with the group.

Parameters Description
groupId: NSString* The ID of the group to update
usersToAdd: NSArray<NSString*>* The user identities to add to the group
Errors Description
TKRErrorInvalidArgument One of the arguments is ill-formed
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

Sharing

Sharing a resource can be done during encryption, using the encryption options.

resourceIDOfEncryptedData

Retrieves an encrypted resource's ID.

- (nullable NSString*)resourceIDOfEncryptedData:(nonnull NSData*)encryptedData
                                          error:(NSError* _Nullable* _Nonnull)error;

The resource ID can then be used to call share.

Note

This function does not have any requirement on Tanker's status.

Parameters Description
encryptedData: NSData* The resource from which to retrieve the ID
error: NSError** Will be set if an error occurs
Returns Description
NSString* The ID of the resource, or nil if an error occurs
Errors Description
TKRErrorInvalidArgument The argument is an invalid resource

shareResourceIDs

Shares resources with users and groups.

The status must be TKRStatusReady.

- (void)shareResourceIDs:(nonnull NSArray<NSString*>*)resourceIDs
                 options:(nonnull TKRShareOptions*)shareOptions
       completionHandler:(nonnull TKRErrorHandler)handler;

This function either fully succeeds or fails. In this case, it does not share with any recipient.

Parameters Description
resourceIDs: NSArray<NSString*>* Resource IDs to share
options: TKRShareOptions* Sharing options
Errors Description
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorInvalidArgument Some recipients (groups or users) have not been found
TKRErrorInvalidArgument Some resource IDs have not been found
TKRErrorDeviceRevoked The device has been revoked

TKRShareOptions

The TKRShareOptions allows you to specify who will be able to decrypt the resource through the shareWithUsers and shareWithGroups properties.

In general, if you need to share a resource with multiple users, it is advised to create groups and use shareWithGroups.

Fields Default value Description
shareWithUsers: NSArray<NSString*>* @[] Public tanker identities of users to share with (the current user's identity will be automatically appended)
shareWithGroups: NSArray<NSString*>* @[] Group IDs to share with

Pre-registration sharing

attachProvisionalIdentity

Attaches a provisional identity to the user.

The Tanker status must be TKRStatusReady.

typedef void (^TKRAttachResultHandler)(TKRAttachResult* _Nullable result,
                                       NSError* _Nullable err);

- (void)attachProvisionalIdentity:(nonnull NSString*)provisionalIdentity
                completionHandler:(nonnull TKRAttachResultHandler)handler;

Depending on the result, verifying the provisional identity with verifyProvisionalIdentity might be necessary.

Parameters Description
provisionalIdentity: NSString* A provisional identity
Errors Description
TKRErrorInvalidArgument The provisional identity is invalid
TKRErrorPreconditionFailed The status is not TKRStatusReady
TKRErrorDeviceRevoked The device has been revoked

AttachResult

The attachProvisionalIdentity function returns a type with the following properties:

Property Description
status: TKRStatus The provisional identity's status. Either TKRStatusReady or TKRStatusIdentityVerificationNeeded
method: TKRVerificationMethod* A verification method containing the email matching the created provisional identity

verifyProvisionalIdentityWithVerification

Verifies an attached provisional identity.

To be called when the status returned by attachProvisionalIdentity is TKRStatusIdentityVerificationNeeded.

- (void)verifyProvisionalIdentityWithVerification:(nonnull TKRVerification*)verification
                                completionHandler:(nonnull TKRErrorHandler)handler;

Once the provisional identity is verified, every resource shared with it can now be decrypted by the user, who also joins every group in which the provisional identity was a member.

Parameters Description
verification: TKRVerification* A verification containing the provisional identity's email, and the verification code
Errors Description
TKRErrorPreconditionFailed The status of the current session is not TKRStatusReady
TKRErrorPreconditionFailed The status of the attach result is not TKRStatusIdentityVerificationNeeded
TKRErrorExpiredVerification The verification expired
TKRErrorInvalidVerification The verification is invalid
TKRErrorTooManyAttempts Too many verification attempts occurred. Please retry later.
TKRErrorDeviceRevoked The device has been revoked

Events

Tanker defines a set of functions and callback handlers to handle events. Call connect${eventName}Handler() with your callback to subscribe to the event. Event registration is asynchronous.

deviceRevoked

Emitted when the current device has been revoked. The revocation can be initiated on any device the user has registered, including the current device.

[tanker connectDeviceRevokedHandler:^{ NSLog(@"Current device has been revoked."); }];