In this post we will explore how to implement a Slack-like login strategy (email with a magic link) on iOS using our simple Lock library. At the end of this post you will also find a seed Xcode project written in Swift to get started as soon as possible. Read on!


Passwordless login systems are convenient for end users: just remember your username, phone number or email and off you go. Passwordless systems usually require the user to manually input a code to validate their identity. This is no longer the case thanks to the advent of Universal Links. Once an email with a link is received by the user, he or she can simply tap on the link and have the application take over. And the cool things is: it is that easy.

Slack-like magic link login

Universal Links

Apple has long provided a way to connect applications through URLs: URL schemes. URL schemes have their own set of issues such as no fallback mechanism and URL scheme hijacking. This has pushed Apple to develop a new and safer way to tell iOS when a link should be passed to an app installed on the device. This is known as Universal Links.

Universal Links allow you to register a series of domains that are allowed to interact with an installed application. If the application is not installed, the universal link is opened with Safari, allowing you to inform the user of the existence of an application or whatever is necessary. To prevent other applications from taking control of this association, a special file, called the association file, must be uploaded to the domains that are registered as associated to an application. In this way, the person or organization that controls the domain is the only one who can control the association between an application and a URL.

Before diving straight into our example, if you are already familiar with our Lock library let me tell you won't need many changes to your code: it is just a matter of setting a few flags and settings. If you are not familiar with our library, our docs provide an excellent introduction. If it seems too daunting, don't worry, download the example from this post and use that as a starting point.

We will use our iOS passwordless email example as a base for the following steps. Get the full code, go to the Passwordless-Email/Lock/Swift folder and open the Xcode workspace.

Step 1: Set your Auth0 client ID and domain

Open the info.plist file in Xcode and set your Auth0 client ID and domain in the list of properties. If don't have an Auth0 account, signup and create your first app.

Auth0 info.plist client ID and domain

Step 2: Enable passwordless logins using emails for your Auth0 app

Go to the passwordless connections section in your Auth0 dashboard. Enable Email logins. The default settings are fine.

Once you have enabled e-mail logins, don't forget to enable the connection in your application's connections section (Apps/APIs -> Your app name -> Connections -> Email) if you haven't done so in the previous step.

Step 3: Enable Universal Links support for your Auth0 app in Xcode

As universal links establish a verified relationship between domains and applications, both your Auth0 app settings and your iOS application need to be in sync. The only thing you need to setup in your Auth0 account is your iOS app's team ID and bundle ID. Unfortunately, we still don't have a proper dashboard UI to input this information, so for now it is necessary to add this information by making calls to our public API.

To find your Apple team ID, go to your Apple developer account summary page.

The application bundle ID is the one you set in your app's Xcode project settings:

Xcode bundle ID

Once you have this information, get your Auth0 application client ID by going to the Auth0 dashboard and selecting your application.

Auth0 client ID

You can now perform an API call to add the team and bundle ids to your Auth0 app. Go to this page and click on Scopes -> update:clients. Then input your Auth0 client ID in the ID form field. For the body use the following JSON snippet (replace the ellipses with your team ID and your bundle ID):

    "mobile": {
        "ios": {
            "team_id": "...",
            "app_bundle_identifier": "..."

Now click on try. This will perform the actual call to our public API. If you get a HTTP 200 response everything went well.

To test this, check whether the universal links apple app site association file is available for your application. Go to your browser and open: (replace YOURACCOUNT with your Auth0 account name).

You should see something like this (formatted for readability):

    "applinks": {
        "apps": [],
        "details": [{
            "appID": "",
            "paths": ["/ios/com.auth0.Passwordless-Email/*"]

Step 4: Setup Universal Links domains for your iOS app

iOS needs to know what domains are handled by the application. To do this:

  1. Go to your project's Xcode settings and enter the capabilities tab.
  2. Find Associated Domains in the list and enable it
  3. Click on the plus sign and add your Auth0's app domain. In my case that would be: (change speyrott for your username, the word applinks must be kept as-is).

Universal Links Domains in Xcode

Step 5: Pass all relevant callbacks to the Auth0 Lock library

If you followed our Lock library guide for iOS this will probably be already in place. If not, go to your AppDelegate class and pass the following callbacks to Auth0's Lock:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        return true

    func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        return A0Lock.sharedLock().handleURL(url, sourceApplication: sourceApplication)

    func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
        return A0Lock.sharedLock().continueUserActivity(userActivity, restorationHandler:restorationHandler)

Step 6: Tell the Lock library you want to use the 'magic link' login strategy

Our Lock library handles the login flow. To tell it to use a magic link instead of a code, do the following before presenting the relevant view controller from the Lock library:

let lock = A0Lock.sharedLock()
let controller = lock.newEmailViewController()

controller.useMagicLink = true // <--- ENABLE MAGIC LINKS!

controller.onAuthenticationBlock = { (profile, token) in
    // Do something with profile and token if necessary
    self.dismissViewControllerAnimated(true, completion: { self.performSegueWithIdentifier("UserLoggedIn", sender: self) })
lock.presentEmailController(controller, fromController: self)

This code is meant to be placed in a view controller that presents the login screen. When the login screen is to be presented, the code above is run. The call to newEmailViewController creates an email login view controller. Setting the useMagicLink variable to true tell the email view controller to favor the use of a magic link rather than a code. As you can see, the whole process and UI is encapsulated in the Lock library.

That's it! Now run the application on an actual device and see if it works. You will need to supply a working email to test it.

  • Universal Links DO NOT work on iOS simulators. You need an actual iOS-enabled device to test this. Standard manual code input logins are supported.
  • Do not use the Gmail app to open the email with the link. At the moment, Gmail opens the links internally or with the help of Google Chrome, entirely bypassing the detection of the Universal Link by iOS.

Get the full code to our seed project. Other mobile examples and an Objective-C version of this seed project can be found in the same repository.


Universal Links get rid of the old URL schemes inefficiencies. Furthermore, passwordless logins through email are a convenient strategy. By removing the step of manually inputting the code the result is a pretty straightforward login process. And thanks to the Lock library, adding this to your application can be done in a matter of minutes. Hack away!

"Universal Links get rid of the old URL schemes inefficiencies."