I’ve been utilizing Auth0 in my iOS project via the Lock.swift framework, leveraging its classic Type with custom UI functionalities for the login/signup flow. However, upon transitioning to Xcode 15, I’ve encountered that Lock.swift is no longer supported. As a result, I’m seeking guidance on how to directly integrate and maintain the same custom UI experience while using Auth0.
Here’s a snippet of the code I’ve been utilizing for the login/signup flow:
//
// QLoginWithAuth0Lock.swift
//
// Created by Bhargav Bajani on 31/07/20.
//
import Foundation
import Lock
import Auth0
@objc public class QLoginWithAuth0Lock: NSObject {
var parentViewController: UIViewController?
@objc public func showLockLogin(presentFromVC: UIViewController) {
self.parentViewController = presentFromVC
Lock.classic(clientId: "auth0ClientID", domain: "auth0Domain()")
.withConnections { connections in
let usernameValidator = UsernameValidator(withLength: 1...20, characterSet: UsernameValidator.auth0)
connections.database(name: "Username-Password-Authentication", requiresUsername: false, usernameValidator: usernameValidator, passwordPolicy: self.getPasswordPolicy())
}
.withOptions {
$0.closable = true
$0.oidcConformant = true
$0.customSignupFields = [
CustomTextField(name: "first_name", placeholder: "First Name", defaultValue: nil, storage: .userMetadata, icon: LazyImage(name: "ico-user_login"), keyboardType: .default, autocorrectionType: .default, autocapitalizationType: .none, secure: false, hidden: false, contentType: nil, validation: nonEmpty),
CustomTextField(name: "last_name", placeholder: "Last Name", defaultValue: nil, storage: .userMetadata, icon: LazyImage(name: "ico-user_login"), keyboardType: .default, autocorrectionType: .default, autocapitalizationType: .none, secure: false, hidden: false, contentType: nil, validation: nonEmpty)
]
$0.showTerms = true
$0.mustAcceptTerms = true
$0.privacyPolicyURL = QStaticPageURLBuilder.privacyPolicyURL()
$0.termsOfServiceURL = QStaticPageURLBuilder.termsURL()
$0.autoClose = false
}
.withStyle({
$0.headerColor = QColorManager.sharedInstance()?.navigationBarColor()
$0.primaryColor = QColorManager.sharedInstance()!.button_loginBackgroundColor()
$0.backgroundColor = QColorManager.sharedInstance()!.login_backgroundViewColor()
$0.buttonTintColor = QColorManager.sharedInstance()!.button_loginButtonTextColor()
$0.secondaryButtonColor = QColorManager.sharedInstance()!.primaryTextColor()
$0.tabTextColor = QColorManager.sharedInstance()!.button_loginCreateAccountTextColor()!.darker()
$0.selectedTabTextColor = QColorManager.sharedInstance()!.button_loginCreateAccountTextColor()
$0.tabTintColor = QColorManager.sharedInstance()!.button_loginCreateAccountTextColor()
$0.textColor = QColorManager.sharedInstance()!.primaryTextColor()
$0.statusBarHidden = false
$0.logo = LazyImage(name: "logo")
$0.title = ""
}).onError(callback: { (error) in
})
.onAuth { credentials in
guard let accessToken = credentials.accessToken else { return }
print("accessToken:\(accessToken)")
self.loginToAuctionServer(accessToken: accessToken)
}
.present(from: presentFromVC)
}
private func getPasswordPolicy() -> PasswordPolicy {
let policyString = QClientDataManager.sharedInstance()?.auth0PasswordPolicy() ?? "fair"
switch policyString {
case "excellent":
return PasswordPolicy.excellent()
case "good":
return PasswordPolicy.good()
case "fair":
return PasswordPolicy.fair()
case "low":
return PasswordPolicy.low()
case "none":
return PasswordPolicy.none()
default:
return PasswordPolicy.fair()
}
}
func loginToAuctionServer(accessToken: String) {
if self.parentViewController?.presentedViewController != nil {
MBProgressHUD.showAdded(to: self.parentViewController?.presentedViewController?.view!, animated: true)
}
QLoginManager.sharedInstance()?.delegate = self;
QLoginManager.sharedInstance()?.doNativeLogin(withAuth0Token: accessToken, completionHandler: nil)
}
}
extension QLoginWithAuth0Lock: QLoginManagerDelegate {
public func loginSuccess() {
NotificationCenter.default.post(name: NSNotification.Name(QUserSignedInNotificationName), object: nil)
self.dismissPresentedViewController()
}
public func accountCreationSuccessButUserNotLoggedIn() {
self.dismissPresentedViewController()
}
public func loginError(_ error: QLoginError!) {
self.hideLoader()
var message = QGlobal.qAMLocalizedString("Unknown Error", forComment: "")
if error != nil {
message = error.message
}
QAlertProvider.sharedInstance()?.showAlert(withTitle: QGlobal.qAMLocalizedString("Oops", forComment: ""), message: message)
}
public func notLoggedIn() {
self.hideLoader()
}
func dismissPresentedViewController() {
self.hideLoader()
self.parentViewController?.presentedViewController?.dismiss(animated: true, completion: nil)
}
func hideLoader() {
if self.parentViewController?.presentedViewController != nil {
MBProgressHUD.hide(for: self.parentViewController?.presentedViewController?.view!, animated: true)
}
}
}
I’m looking for advice and best practices to migrate from using Lock.swift to directly interfacing with Auth0 while retaining the custom UI elements and login/signup functionalities.
Any insights, code samples, or pointers on implementing Auth0 in this context or suggestions for alternative approaches would be greatly appreciated. Thank you!