iOS SDK for VYou
This is the iOS SDK for VYou, a service to provide user identity to your applications. This library includes a client SDK along some artifacts and a sample to streamline your workflow.
The SDK is written in Kotlin using Kotlin Multiplatform for the client side and in Swift for the integration with third-party libraries.
- KMM-Client: Client to manage operations with VYou authentication server.
In addition, we have created a sample application using SwiftUI to test how each artefact can be implemented.
The library is available through SPM (Swift Package Manager), just go to your Xcode project, click File > Add Packages and paste the git url in the search field. You can also use it as a library inside your Package.swift file.
.package(url: "https://github.com/VYou-App/vyou-ios",.upToNextMajor(from: "{latest-release-version}")),
The first step is to initialise the VYou
class, which is the main entry point for all operations in the library. VYou
is a class that contains all the operations you can perform using the SDK; you will use this method once, generating a single instance and using the rest of the methods in your application.
To create the client, we need to invoke the constructor class related to the VYou
class and pass it the required parameters:
let builder = VYou.Builder(clientId: "{VYOU_CLIENT_ID}", serverUrl: "{VYOU_SERVER_URL}")
These variables are provided by VYou staff, the approach used in the samples is to include this data through Process Info
as environment variables:
let clientId = ProcessInfo.processInfo.environment["CLIENT_ID"]
let serverUrl = ProcessInfo.processInfo.environment["SERVER_URL"]
In addition, the constructor can be configured with some optional functions. To track network operations the logging level can be changed, default is none
.
//level - VYouLogLevel class
builder.enableNetworkLogs(level: .all)
VYouLogLevel is an enum class
class and you can select between all
, info
, headers
, body
or none
which will affect our implementation Ktor used by the client.
Finally, we have two callbacks, first we have addOnRefreshTokenFailure
when the refresh token is invalidated by the server and addOnSignOut
after the signOut completes successfully. Both callbacks are intended to help manage the state of the application when these events occur.
builder.addOnRefreshTokenFailure { error in
//To do after event
}
builder.addOnSignOut {
//To do after event
}
Whether you use the optional functions or not, to finally initialise the client you need to invoke the build
function of the builder.
builder.build()
A recommended practice is to initialize VYou
in the AppDelegate
class:
import VYou
class AppDelegate : UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let clientId = ProcessInfo.processInfo.environment["CLIENT_ID"]
let serverUrl = ProcessInfo.processInfo.environment["SERVER_URL"]
VYou.Builder(clientId: clientId, serverUrl: serverUrl)
//additional functions if needed
.build()
}
}
Alternatively, if you are using Swift UI, you can build the client into the main entry point of the application.
import VYou
@main
struct MainApp: App {
init() {
let clientId = ProcessInfo.processInfo.environment["CLIENT_ID"]
let serverUrl = ProcessInfo.processInfo.environment["SERVER_URL"]
VYou.Builder(clientId: clientId, serverUrl: serverUrl)
//additional functions if needed
.build()
}
}
After building the client, we can use it throughout the application by calling VYou.shared
. If the client is not initialised before calling the instance method, it will throw a related error. The client provides functionality to authenticate a user and manage user information.
All methods related to network operations are native
functions using Kotlin coroutines
. The SDK provides two types of functions to support iOS compatibility.
First, each function can be resolved through a completion handler method. For example:
func signIn(params: VYouSignInParams, completionHandler: (VYouCredentials) -> Void)
This approach may help in some projects but in most projects an asynchronous solution such as Async/Await, Combine or RxSwift should be used. To support these cases, as we have mentioned each function is native
and can be encapsulated to support each case and this is done using KMP-NativeCoroutines.
import KMPNativeCoroutines
import VYou
//Async/Await
import KMPNativeCoroutinesAsync
func signIn() -> VYouCredentials {
return asyncFunction(for: VYou.shared.signIn(params: VYouSignInparams))
}
//Combine
import KMPNativeCoroutinesCombine
func signIn() -> AnyPublisher<VYouCredentials, Error> {
return createFuture(for: VYou.shared.signIn(params: VYouSignInparams))
}
//RxSwift
import KMPNativeCoroutinesRxSwift
func signIn() -> Single<VYouCredentials> {
return createSingle(for: VYou.shared.signIn(params: VYouSignInparams))
}
//VYouSignInProvider.UserPassword(username, password)
VYou.shared.signIn(params: VYouSignInProvider.UserPassword) -> VYouCredentials
//VYouSignInProvider.Apple(apple)
VYou.shared.signInFacebook(params: VYouSignInProvider.Apple) -> VYouCredentials
//VYouSignInProvider.Google(googleIdToken)
VYou.shared.signInGoogle(params: VYouSignInProvider.Google) -> VYouCredentials
//VYouSignInProvider.Facebook(facebookAccessToken)
VYou.shared.signInFacebook(params: VYouSignInProvider.Facebook) -> VYouCredentials
Each method returns a VYouCredentials
class that contains the information to authorise any call covered by the VYou auth server. Internally, this information is stored in an encrypted keyring and can be retrieved through these credentials methods along with helper methods to check the user's session.
//Ex: VYou.shared.accessToken()
func isLoggedIn() -> Boolean
func tokenType() -> String
func accessToken() -> String
func credentials() -> VYouCredentials
func isValidToken() -> Boolean
If you already have a Google or Facebook implementation in your application, you can use these methods to log in to VYou, plus we will explain the social artefacts mentioned in the overview that covers the implementation of the social libraries.
To register a new user on the platform, the following three steps are necessary. Firstly the new user is registered by providing an email along with the acceptance of the required terms of use and the privacy policy provided by the application, optionally a boolean information can be added for marketing purposes.
//VYouSignUpParams(email, termsOfUseAccepted, privacyPolicyAccepted, infoAccepted)
VYou.shared.signUp(params: VYouSignUpParams)
After sign up, the user will receive a confirmation code in the email provided in the previous step. The user must copy this code and introduce it to verify the register.
//VYouSignUpVerifyParams(code)
VYou.shared.signUpVerify(params: VYouSignUpVerifyParams)
Finally, if the provided code is valid, the user must register a password related to the provided email using this method:
//VYouSignUpPasswordParams(password)
VYou.shared.signUpPassword(params: VYouSignUpPasswordParams)
All these steps are necessary to ensure all security steps related to the OAuth protocol. After successfully registering the password, the user can use the sign in method to log in to the platform.
Users have access to the information they provide to the application using VYou. To retrieve the current information they have the following method.
VYou.shared.getProfile() -> VYouProfile
VYouProfile
is a class containing the registered email, custom fields and the compliance status related to the tenant. If the status is false, the application should request the required fields from the user.
To update your information you have another method to modify the custom fields related to the tenant.
//VYouEditProfileParams(fields)
VYou.shared.editProfile(params: VYouEditProfileParams) -> VYouProfile
It is not necessary to provide all fields, only the ones you want to modify.
To log out of the platform and clear the saved credentials, there is a sign out method
VYou.shared.signOut()
Users also can reset password using the next method, after a successful call they will receive an email with a confirmation token and they must proceed like in the sign up process after register the email.
//VYouResetPasswordParams(email)
VYou.shared.resetPassword(params: VYouResetPasswordParams)
If any call returns a 401 - Forbidden
http code it means that the access token used has expired and must be refreshed, to do this you must use the refresh token method.
VYou.shared.refreshToken() -> VYouCredentials
This must be implemented in a network interceptor to provide a smooth user experience, if the refresh token fails, the user must log in again to retrieve a new access token.