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:
- Passwordless login APIs (
IdentityManager.sendCode(...)
) - Password login APIs (
IdentityManager.login(...)
) - Signup APIs (
IdentityManager.signup(...)
) - 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 toOne 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 userDeclaration
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
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 aClientError.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 withAppLaunchData
and verified withvalidate(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:
- Redirected to the app via the url scheme (see
ClientConfiguration.appURLScheme
) - Redirected to a webflow to accept terms and conditions, and then redirected to the app
- 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.
See also
fetchTerms(completion:)
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.See also
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 signuppassword
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 argumentpersistUser
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).
- Redirected to the app via the url scheme (see
-
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
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 identifierDeclaration
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 underAssign 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.