IdentityManager

public class IdentityManager : IdentityManagerProtocol

This manager provides access to various auth related APIs and manages the creation and persistence of an internal User object that can be accessed through IdentityManager.currentUser.

A number of methods of creating a user exist within this manager. They include:

  1. Passwordless login APIs (IdentityManager.sendCode(...))
  2. Password login APIs (IdentityManager.login(...))
  3. Signup APIs (IdentityManager.signup(...))
  4. APIs to access client specific information

The general approach is to first create an IdentityManager with a ClientConfiguration. After that you may check if there already is a user that was previously persisted. This can be checked via IdentityManager.currentUser‘s User.state which will tell you if the internal user is in a logged in or logged out state. In order to comply with privacy regulations, you also need to make sure that the user accepts any update to terms and conditions that may have been issued since the user’s last visit: see User’s documentation for more details on how to do that.

The objective of the identity manager is to create a user object. There should be no need to keep an identity manager lying around once you have a reference to the internal user object.

Authorization code vs one-time code

There are two code validation APIs in the manager. One of them operates on one time codes that are explicitly send to an Identifier using IdentityManager.sendCode(...) to start a passwordless login process. The other is an OAuth-related authroization code, which is not explicily requested. The current use-case for authorization code validation is after a signup process, when a user verifies their email. Or after an unverified identifier tries to login.

After logging in

After you successfully login by either the passwordless or password APIs, it is recommended that you check the profile status of your user object. This means checking if there are updated terms and conditions that need to be accepted or if there are required fields that need to be updated. These can both be done via User.Agreements.status(...) and User.Profile.requiredFields(...).

User persistence

If the persistUser parameter passed to the IdentityManager’s methods is true, the user that is internally managed by an identity manager is also persisted in your keychain for maintaing logged in and logged out state. Therefore, once a user is made valid, the manager persists the data necessary to recreate the user for a later session.

Currently the keychain user is a singleton. So the last user that is validated will be persisted. And the last user that is persisted will be the one that is loaded by a new instance of the IdentityManager.

Scopes

Some of the functions take a scope parameter. This is related to OAuth scopes. If you want to add the ability to specify custom scopes or you want access to some already available predefined scopes, then you’ll have to send a support request to schibstedaccount@schibsted.com

Support

The visual login via the IdentityUI is the recommended approach to creating a User. This IdentityManager should just be used to check if there’s already an existing user.

  • The delegate that will receive events related to the manager’s state.

    Declaration

    Swift

    public weak var delegate: IdentityManagerDelegate?
  • The user managed by this manager

    This user object is persisted in the keychain so that when you initialize an identity manager again, you may just resume the previously saved user session.

    Users are persisted after any successful login process.

    Declaration

    Swift

    public internal(set) var currentUser: User
  • The client configuration used to create the manager

    Declaration

    Swift

    public let clientConfiguration: ClientConfiguration
  • Gives you access to Schibsted account web flow routes.

    Where relevent, these can typically be used with User.Auth.webSessionURL(...) to create a web session on a Schibsted account page where a user is considered as logged in.

    Declaration

    Swift

    public let routes: WebSessionRoutes
  • Initializes the identity manager.

    If there is a valid user in the keychain then that will be loaded in, else you will have to create a user using one of the aformentioned methods.

    Declaration

    Swift

    public required init(clientConfiguration: ClientConfiguration)

    Parameters

    clientConfiguration

    defines your configuration

  • Starts a passwordless login flow with Identifier as the basis of where to send the one time code to

    One time code passwordless authentication involves 2 steps. First this method is called to send a code to an identifier. This code has to be extracted seperately by the owner of the identifier and then it can be used with validate(oneTimeCode:for:completion:) to create a valid user

    Declaration

    Swift

    public func sendCode(to identifier: Identifier, completion: @escaping NoValueCallback)

    Parameters

    identifier

    can be either email or phone number

    completion

    callback that is called after the code is sent

  • Resends the code that was tried previously with sendCode(...).

    See also

    sendCode(...)

    Declaration

    Swift

    public func resendCode(to identifier: Identifier, completion: @escaping NoValueCallback)

    Parameters

    identifier

    can be either email or phone number

    completion

    callback that is called after the code has been resent

  • Used after a call to sendCode(...) to validate the one time code that was sent to an identifier.

    Declaration

    Swift

    public func validate(oneTimeCode: String, for identifier: Identifier, scopes: [String] = [], persistUser: Bool, completion: @escaping NoValueCallback)

    Parameters

    oneTimeCode

    the code sent to identifier

    identifier

    the user’s identifier. Should match the one used in sendCode(...)

    scopes

    array of scopes you want the token to contain

    persistUser

    whether the login status should be persistent on app’s relaunches

    completion

    the callback that is called after the one time code is checked

  • Used to validate an authorization code

    sendCode(...) must have been called before. The difference between this overload and the one that takes an explicit identifier is that this will try and validate against any identifier that was previously used (during a single session) and succeed if any succeed.

    Declaration

    Swift

    public func validate(oneTimeCode: String, scopes: [String] = [], persistUser: Bool, completion: @escaping NoValueCallback)

    Parameters

    oneTimeCode

    The auth code that was sent to the user

    scopes

    array of scopes you want the token to contain

    persistUser

    whether the login status should be persistent on app’s relaunches

    completion

    the callback that is called after the auth code is checked

  • Authenticate using e-mail and password.

    Declaration

    Swift

    public func login(username: Identifier, password: String, scopes: [String] = [], persistUser: Bool, completion: @escaping NoValueCallback)

    Parameters

    username

    Identifier representing the username to login with. Only email is supported.

    password

    the password for the identifier

    scopes

    array of scopes you want the token to contain

    persistUser

    whether the login status should be persistent on app’s relaunches

    completion

    a callback that is called after the credential is checked.

  • Signup using e-mail and password.

    This method does not result in a valid currentUser object. The reason is that either the identifier already exists in the system, in which case you will get a ClientError.alreadyRegistered, or the identifier needs to be verified, in which case there will be an eventual deep link back in to your application that can be parsed with AppLaunchData and verified with validate(authCode:completion:)

    This API results in an email being sent to the user to complete the process. Once a user clicks on a verification email, a number of things can happen, they can be:

    1. Redirected to the app via the url scheme (see ClientConfiguration.appURLScheme)
    2. Redirected to a webflow to accept terms and conditions, and then redirected to the app
    3. Redirected to a webflow to update/input required fields and then redirected to the app

    Checking identifier before calling signup

    If you try and signup with an identifier that already exists, you will get an error. If you need to check the status of an identifier you should use fetchStatus(for:completion:) first.

    Terms and conditions and privacy policy

    The redirection to the webflow terms and condition screen can be bypassed if you accept terms through this API. However, if you do do this then you are responsible for actually showing the terms to the user. This tells us that the user has explicitly accepted the Schibsted account terms and conditions and been notified of the privacy policy, and also has done the same for the client’s (your) terms and conditions and privacy policy.

    Required fields

    Depending on how you’ve set up your client in self service, the user may also need to fill in some required fields. If you want to bypass the webflow for these as well, then you must provide a valid UserProfile object that fulfills all of your client’s required fields.

    Declaration

    Swift

    public func signup(
        username: Identifier,
        password: String,
        profile: UserProfile? = nil,
        acceptTerms: Bool? = nil,
        redirectPath: String? = nil,
        persistUser: Bool,
        completion: @escaping NoValueCallback
    )

    Parameters

    username

    Identifier representing the username to signup

    password

    password for identifier

    profile

    profile information to be set on created user

    acceptTerms

    this must be set to true to create a user

    redirectPath

    The signup process will eventually deep link back to your app with ClientConfiguration.redirectBaseURL and this argument

    persistUser

    whether the login status should be persistent on app’s relaunches

    completion

    a callback that is called in the end (with an error object in case of failures).

  • Log in by an auth code.

    The authorization code is passed into the app from Schibsted account after the user verified their email.

    See also

    AppLaunchData

    Declaration

    Swift

    public func validate(authCode: String, persistUser: Bool, completion: @escaping NoValueCallback)

    Parameters

    authCode

    an authorization code (currently it’s just available through deeplinks)

    completion

    the callback that is called after validation

    scopes

    array of scopes you want the token to contain

    persistUser

    whether the login status should be persistent on app’s relaunches

  • Fetch the IdentifierStatus for the supplied identifier

    Declaration

    Swift

    public func fetchStatus(for identifier: Identifier, completion: @escaping IdentifierStatusResultCallback)

    Parameters

    identifier

    The identifier you want the status for

    completion

    contains an IdentifierStatus object on success

  • Retrieve the latest terms & conditions links for Schibsted account and client (i.e. your app).

    The platform terms returned are the default ones associated with Schibsted account. The client terms are what are associated with your client ID and can be set in Schibsted account Self Service under Assign T&C page.

    Declaration

    Swift

    public func fetchTerms(completion: @escaping TermsResultCallback)

    Parameters

    completion

    a callback that receives the Terms model.

  • Fetches the list of required fields that this client expects

    The required fields can be set in Schibsted account Self Service.

    Declaration

    Swift

    public func requiredFields(completion: @escaping RequiredFieldsResultCallback)

    Parameters

    completion

    a callback that’s called on completion and might receive an error.

  • Retrieve information from self serivice about your app

    Some information from Schibsted account that is associated with your client ID and can be set in Schibsted account Self Service

    Declaration

    Swift

    public func fetchClient(completion: @escaping ClientResultCallback)

    Parameters

    completion

    a callback that receives the Client model.