Last modified: 01.11.2025
The purpose of this guide is to walk a software development team through the steps necessary to build the Schlage Employee Badge Mobile Credential iOS App. The Schlage Employee Badge Quick Start App, along with the Allegion Mobile Access SDK, allows organizations to understand how to build their own app that delivers NFC-based Schlage Credentials to the Apple Wallet (iOS) for use as a replacement or alongside physical card-based credentials. This guide covers the steps for building a Quick Start app. With the information covered in this guide, a software team is prepared to implement their own production ready version of the app.
If you're already familiar with the high-level details of an Employee Badge project and are looking for implementation specifics you can jump to the Building the Employee Badge Quick Start App for iOS section of this guide.
If you're looking for a detailed code review of the Quick Start App code you can jump to the Employee Badge Quick Start App Code Walkthrough located at the end of this guide.
The Employee Badge Mobile Credentials App is a fairly simple to use, and the application code is not very complex, however; the process to build the app involves a significant amount of up-front setup and configuration work. This guide seeks to walk through all requirements, dependencies and setup steps to complete the process in a straight-forward and easy-to-consume manner. Where necessary, references to other relevant guides will be linked to ensure no gaps exist to completing integration.
This guide does not assume the reader has advance knowledge of Wallet-based iOS app development. The reader may choose to skip ahead as necessary where topics are already known or dependencies are already in place. Dependencies are listed in the Dependencies section of this guide.
This guide is intended to be read and used by anyone who is responsible for technical implementation of a Schlage Employee Badge Mobile Credential project, including mobile app developers, backend developers and project managers. It will also be useful for technical resources responsible for provisioning credential management systems and technical administrators responsible for managing credentials.
Since not everyone who reads this guide will be familiar with language used in physical security and access management, this section covers definitions for terms commonly used in the space.
Term | Definition |
---|---|
Access Control System (ACS) | An Access Control System is a software platform that manages access rights of physical spaces and resources based on predefined rules, policies and user access rights. ACSs provide a unified platform for managing access to spaces and resources across an enterprise and capture real-time information related to who is attempting to use/access spaces and resources at all times. Access control systems work alongside access control devices such as locks, credential readers and modules to control physical space access and govern assignment of credentials to support access control management policies. |
Bluetooth Low Energy (BLE) | BLE is a short-range wireless networking protocol based on Bluetooth, designed especially for short-range communication and used extensively in security, IoT and other applications where device-to-device communication is a requirement. BLE is useful where device battery life is prioritized over high data transfer requirements. Most smart phones available today are BLE-compatible. BLE (beacons) has an indoor broadcast signal range of 10-30 meters. |
Credential | In access control, a credential is a piece of data, document or physical object owned by or granted to an individual by a third party that establishes the individual's identity and authority within a given physical and digital environment. Examples of credentials are plastic employee badges, pin codes, physical door keys, or a person's fingerprint or retina. |
Near-Field Communication (NFC) | NFC is a very close proximity wireless communication standard, NFC based on the Radio Frequency Identification (RFID) standard, designed especially for near-physical communication and used extensively in security, IoT and other applications where device-to-device communication is a requirement. Most smart phones available today are NFC-compatible. NFC (tags) has a broadcast range of 4 centimeters. |
Patron | In access control, a patron is a bearer and user of a credential. |
Reader (or Module) | A reader is a device that controls access to a given space or resource. Readers communicate with and 'read' credentials presented to them and work alongside an Access Control System to determine if a patron has authorization to the resource or space it controls. Readers communicate access requests to an access control system, including unauthorized access requests, tamper attempts and breaches. |
This section covers the high-level process overview of the Employee Badge implementation project and description of each phase of the project.
The company will sign the Apple Participating Partner Agreement to begin receiving access to proprietary documentation and processes as part of initial discovery.
Allegion and the company will conduct a site survey and discovery meetings to determine all requirements, relevant systems and dependencies for implementing a mobile access project. This will include evaluating existing hardware to determine all firmware requirements and configuration updates. This may also include onsite hardware testing and demonstration of readiness.
A company's developers will be granted access to the Schlage Mobile Access NFC SDK and Allegion Mobile Access APIs and the Schlage NFC Quick Start app for iOS. The quick start app will be particularly useful in understanding the structure of an app.
After requirements have been collected, Allegion and company will work together to confirm project goals and determine solutions for any identified gaps.
Allegion and company will develop a project plan (based on a standard project) and define scope and timing for the project.
Project resources will be identified and assigned tasks and deliverables. Work hours will be established.
Project kick-off will occur, including sharing contact details and establish regular project meeting cadence.
Project work begins including development work against Schlage APIs and SDKs:
The company will work with Allegion to request access to Apple Wallet-specific developer entitlements for Apple mobile development. These entitlements are granted by Apple only during implementation of an Apple Wallet-based project.
Development work will commence to connect the Allegion Cloud with the company's access control system. This work allows the company to send new patron records to Allegion and receive back a record of a new credential for that patron.
Company hardware (locks, readers) will be configured and prepared for use with Apple Wallet-based mobile credentials
Patron training materials will be developed from template content including how-to guides, FAQs and other supporting documentation
Testing - including end-to-end testing and user acceptance testing - will be completed. Testing will also require review, validation and certification of test cases by Allegion.
Existing credential support staff will be trained on the use of the new wallet-based mobile credential technology and prepared for inbound patron technical support requests.
Production support plan will be implemented based on previously defined and agreed support requirements.
A pilot will be conducted to with a subset of patrons to validate the solution is working and address any outstanding issues with the solution.
The full launch will commence.
Implementing an Employee Badge project involves work and coordination across the following organizations and resources:
Allegion - provides software and hardware to support implementation. Allegion will also assign a Project Manager and Technical Account Manager to every Mobile Credentials project.
Integrator - The integrator is typically responsible for access control hardware installations, management and firmware updates. Employee Badge projects will always include the integrator as they will have critical information and important responsibilities necessary to prepare and configure hardware to support the project.
Mobile App Developers - If an app is being built to support this project, mobile app developers will be engaged to complete development. The mobile app is used to authorize the patron, associate the patron with a credential and store newly provisioned credentials into the Apple Wallet.
Cloud Developers - An engineer will need to implement an integration between an existing Access Control System and the Allegion Cloud. This integration is required to provision new credentials.
Cloud System Engineers - An engineer or technical resource will need to configure single sign-on with the corporate identity service used to manage patron identity. This resource will also support ensuring all systems are able to communicate with each other and supporting activities such as system configurations, whitelisting of IP addresses, etc.
Project Manager - A project manager will manage this project and will manage not only the implementation but also support testing, documentation development, support process development, employee/patron training and system launch.
This section covers the required and/or supported hardware, software as well as developer tools and development experience required to implement an Employee Badge on iOS.
Because this is a technical solution and requires development to implement, the development topics in this guide cover topics at a level that expect developers to have knowledge of iOS development processes, tools and technology, including experience with the XCode IDE and use of Cocoapods Dependency Manager. It also assumes developers have had previous experience developing and distributing iOS mobile applications to the Apple App store.
Schlage Employee Badge solutions are deployed within and supported by a corporate information technology environment and infrastructure. There are some technologies that need to exist in that corporate environment to support this solution:
Physical Access Control System (PACS) - The organization must manage their locks and readers using a PACS. Allegion can support all major PACS for Employee Badge. Your Allegion Customer Success engineer can provide full details on PACS requirements, the scope of which is not covered in this guide.
Identity Management System (IdM) and Single Sign-On (SSO) - The organization must have an IdM deployed that validates employee identity and authenticates/authorizes employee access to corporate applications and systems. SSO must be supported for user authentication.
Compatible hardware
iPhone SE, iPhone 6s, iPhone 6s Plus or later running iOS 15.6 or later
Apple Watch Series 3 or later running the latest version of watchOS 8.6 or later
Device settings
T&Cs with Apple must be accepted
iCloud Terms and Conditions must be accepted
Passcode, Face ID or Fingerprint must be enabled
2FA -- Two Factor Authentication must be enabled for account login
The table below lists all Schlage locks that support the Mobile Credentials solution:
Locks that support Apple NFC | Hardware Version Info | Firmware Version for Initial Apple NFC Certification | Certification Status |
---|---|---|---|
Schlage Control B Locks | All hardware versions support Apple NFC | 04.12.00 | Complete |
Schlage Control BM Locks | All hardware versions support Apple NFC | 05.11.39 | Complete |
Schlage Control Locks | Not pursuing Apple NFC Certification | n/a | n/a |
Schlage NDE Locks | All hardware versions support Apple NFC | 02.12.72 | Complete |
Schlage LE Locks | All hardware versions support Apple NFC | 01.07.67 | Complete |
Schlage NDEB Locks | All hardware versions support Apple NFC | 03.07.01 | Complete |
Schlage LEB Locks | All hardware versions support Apple NFC | 03.07.01 | Complete |
Schlage NDEB Si Locks | All hardware versions support Apple NFC | 03.09.07 | Complete |
Schlage LEB Si Locks | All hardware versions support Apple NFC | 03.09.07 | Complete |
Schlage AD300 | Must have MT2/MTK2 Reader | AD.A.125 | Complete |
Schlage AD400 | Must have MT2/MTK2 Reader AD | AD.A.125 | Complete |
The table below lists all Schlage readers & modules that support the Mobile Credentials solution:
Readers that support Apple NFC | Hardware Version Info | Firmware Version for Initial Apple NFC Certification | Certification Status |
---|---|---|---|
Schlage RC Reader Controller (RC11, RC15, RCK15) |
All hardware versions support Apple NFC | 01.08.02 | In process |
Schlage MTB Readers (MTB11, MTB15, MTBK15) |
All hardware versions support Apple NFC | 60.47.14, 60.47.27 |
In process |
Schlage MT15, MTK15, MT11, MTMS15, MTMSK15 Readers | All hardware versions support Apple NFC | 22.02 | Complete |
Schlage OEM200 Modules | All hardware versions support Apple NFC | 2.01 | Complete |
Schlage MT20 Enrollment Readers | All hardware versions support Apple NFC | 9.02 | Complete |
Schlage Mobile Credentials give patrons the ability to use an NFC-based credential - known as a pass - stored in their phone's/watch's Apple Wallet - to gain access to secured spaces managed by an Access Control System (ACS).
Schlage Employee Badge Mobile Credentials for Apple Wallet are implemented using two technologies from Schlage:
The Schlage Employee Badge Product API - hosted in the Schlage Cloud, this API exposes the following capabilities:
Creation of a patron record and user access rights in the Allegion Cloud (also known as ingress)
Gives the PACS partner the ability to suspend, resume and delete user credentials (and propagates these changes with Apple)
Gives the PACS partner the ability to update information on the pass including name, photo, email address and other patron information.
Other components needed for implementation include:
A Physical Access Control System (PACS - may be provided by Allegion)
An Identity Management Platform/Service
A Single Sign-On solution (Apple requirement)
An endpoint established to capture inbound data responses from the Schlage Cloud
Compatible iPhone with Apple Wallet using personal Apple IDs (not Managed Apple IDs)
Compatible hardware (locks and readers)
The remainder of this document will focus on implementation development activities and is intended for a technical audience (Developers, System Administrators).
The steps in this topic will focus on preparing your environment and then building the Employee Badge Quick Start app for iOS. This guide assumes the developers working to build the app meet the following minimum dependencies for completing such a task:
Developers have access to the latest version of the Apple XCode IDE.
Developers have a paid Apple Developer Account and access to the Apple Developer Portal
Developers have experience building Apple mobile apps.
Developers have experience using the Cocoapods dependency manager to manage code.
If you have not already done so, you'll need to create an account in the Allegion Developer Portal in order to gain access to the API and SDK documentation for the Allegion Employee Badge product. You'll also need this account to obtain a Mobile SDK Subscription Key, which is required to initialize and use the SDK within your app.
As you build an Employee Badge solution, your team will be working with APIs and SDKs across two different projects. Each project outlines specific areas of development effort and uses a different subscription key to interact with Allegion. For this guide/project, we'll be focused on mobile app development and so we'll be using the Mobile SDK Subscription Key to interact with Allegion SDKs.
When building the integration between an Access Control System and Allegion Cloud (the subject of a different guide), an API Subscription Key is used. These are each different keys with different permissions, and are not interchangeable. Mixing/matching keys will result in errors and frustration, so we'll make this callout in several places throughout this and other guides.
Follow these steps to create your account and request your Mobile SDK Subscription Key:
Click the Sign In link in the top right corner of the landing page.
If you have an account, enter your account details and click Login to log in.
If you don't have an account, click the Create Profile button to create an account. Enter required details to create an account and complete the email verification step to continue. You'll also need to complete profile details to proceed.
Once you have your profile you'll be directed to your Account Profile page. This is the area where you'll see Product subscriptions to which you've been granted access. If you've never requested access to use Allegion Products then you'll see an empty list here that displays, "No results found":
To obtain a key, send an email to Allegion Customer Success requesting a "Mobile SDK Product Subscription Key (developer.support@allegion.com) for the Employee Badge iOS Mobile App. Expect to get a response in no less than 24-48 hours.
Once a response from Allegion is received confirming your subscription key is created, navigate back to your Allegion Developer Account Profile (from the Allegion Developer Portal home click your name, then Profile) and you'll see your newly granted subscription listed.
Next, we'll request access to the Schlage Employee Badge Quick Start App for iOS codebase. The app uses the Allegion Mobile Access NFC SDK alongside the Allegion Employee Badge APIs to demonstrate how to get an app built and running. It also relies on dependencies found in the Allegion CocoaPods repository. You'll need to request access to all 3 Github repositories. This Quick start app will serve as a reference app to follow along to while you build your own. To make the request just reach out to your Allegion Customer Success engineer and request this access (https://developersupport.allegion.com/hc/en-us/requests/new?ticket_form_id=32387239325844&tf_22658560153748=new_integration) and provide the Github username/email address associated with the Github account to which you need access granted.
If you have not already done so, you'll need to complete and sign Apple's Non-Disclosure Agreement and the Apple Participating Partner Terms and Conditions before you'll be granted access to Apple documentation and Wallet development assets. You can reach out to your Allegion Customer Success resource to begin this process, or contact your Apple representative if you are already working with Apple.
The next step is to obtain the necessary Apple Entitlements to build iOS/WatchOS apps that can interact with the Apple Wallet for provisioning mobile passes. This capability allows the app you are building to interact with Apple's wallet in order to push a pass into a patron's Apple Wallet so the pass can later be presented to a Schlage reader or lock for credentialed access. Apple's SLA for this is 5 days, if you haven't heard let us know and Allegion can follow up on your request.
These entitlements are not publicly available capabilities (such as iCloud, Push Notifications, etc) but rather need to be assigned by Apple to the developer's Apple Developer account. The entitlements to be requested are:
Contactless Pass Provisioning (SharableCredential) - com.apple.developer.contactless-payment-pass-provisioningDevelopment
Contactless Pass Provisioning access for MAIDs - com.apple.developer.contactless-payment-pass-provisioning.maids
To make the request to begin building with these features, please create an email using the following template and replacing anything in brackets with proper values/responses:
To: | applepayentitlements@apple.com |
Email Subject: | Mobile Access NFC Entitlement Request: [Your Company Name] |
Email Body: | Entitlement Team,
com.apple.developer.contactless-payment-pass-provisioningDevelopment
com.apple.developer.contactless-payment-pass-provisioning.maids
Here are the details for our request:
Please respond back for answers to any additional questions. |
While you wait for entitlements to be granted we'll go ahead and create/update your Employee Badge iOS app.
In order to test working with mobile credentials, you'll need access to a sandbox Apple account. A standard (production) Apple account cannot be used as it will not give your iOS device access to the Sandbox Apple Wallet. Sandbox Apple Accounts are created using Apple App Store Connect.
Once you've created your Sandbox account you can us it login to an iOS device. Go to Settings ➡ Account Name and click Sign Out to sign out an active account. Signing out will disable Find My on the device. Once signed out, sign back in using the new Sandbox account login details.
To confirm your account is a sandbox account, open the Apple Wallet and ensure that it says "Sandbox" in the upper area of the app.
Once the iOS device is in Sandbox mode it is ready for testing.
If you have not already, download and install the Cocoapods dependency manager. If you have not already used CocoaPods with an XCode project you'll want to follow the guidance at the CocoaPods home to get CocoaPods dependency manager installed on your development machine. Directions for this can be found at the link provided but are not covered in this guide.
Once you have access to the Allegion Github repository, you'll need to download the Quick Start App Project. Follow these instructions to download the app and set up your dependencies.
Open XCode.
Select Clone an existing project to clone the Employee Badge Quick Start App from Github
For repository URL enter the Quick Start App Repository URL and click Clone. You'll be prompted to sign in to Github using your Github account name and Personal Access Token (PAN). You can generate a Github PAN for use here at Github under Settings ➡ Developer Settings ➡ Personal access tokens ➡ Tokens (classic)
If - after logging in - XCode prompts that you don't have access to the repository, be sure you've completed the Request API Access step above. If that step is completed please contact your Allegion Customer Success engineer to troubleshoot access.
Choose the main
repository, click Clone and select the target home directory to clone the Quick Start App project locally.
Once the project is cloned, open the Command Line/Terminal application and browse to the folder containing the newly cloned project. (As of Q2 2023 this folder is called PersonaManagerEnrollment. This may be in a subdirectory of the directory containing the cloned project. You are in the correct folder when you see a file called Podfile in the same directory.
Update the project using the pod repo update
command.
Initialize the project using the pod install
command.
With a successful build, you are now ready to continue.
If you are modifying an existing app to add Mobile Credential capability, you can follow these steps to add the necessary dependencies.
Login to your Github account.
Once logged into Github, click this link to reach the Allegion Github Repository hosting the iOS SDK.
Note: If you reach a Github 404 error page instead of the repository this means your Github account doesn't have access to the repository. Please contact your Allegion Customer Success engineer with your Github username so you can be granted access.
Once you've confirmed you have access to the SDK, add it your app build using the standard method for installing Podfiles:
Open your project Podfile and add the following lines (if they aren't already there):
source 'https://github.com/Allegion-Plc/AllegionCocoaPods'
source 'https://cdn.cocoapods.org/'
use_frameworks!
Add the pod name and desired version number (all versions for the iOS SDK can be found here):
pod 'Allegion.Access.MobileAccessSDK.iOS', :git => 'https://github.com/Allegion-Plc/AllegionAccessMobileAccessNFCSDK', :tag => '0.1.1'
Note that the current version of the Podfile as of time of writing this guide is 3.0.0
Save the Podfile.
Once Apple has responded to your email request for necessary entitlements as outlined in the step above, you'll need to configure your project to use the new capabilities. Follow these steps to configure your project:
com.allegion.PersonaManagerEnrollment
Under the Capabilities section, check the following boxes:
<appName>.entitlements
in the project main folder if it does not already exist) and ensure it includes the following content:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.contactless-payment-pass-provisioning</key>
<true/>
</dict>
</plist>
Next we'll configure the app environment.
At this point the app will run, but is not configured to run properly. This section will set environment details and provide more detail how the app works. Before we cover steps to configure the environment, it's important to understand what the app is designed to do.
The purpose of this app is to create a digital credential for an authorized user/patron and deposit that credential into the Apple Wallet. The user's identify must be verified as valid in order for the app to progress to generating a credential on their behalf. The process of verifying identity relies on a corporate Identity Management System (IdM). The app will challenge the user to supply a username and password and have the IdM confirm the user as valid. Once the user has been authorized, the app will generate a digital credential and allow the user to deposit/store it in the Apple Wallet. The complete app flow is detailed below.
This sequence diagram illustrates the flow of activities the Quick Start app follows in order to deposit a digital credential into the Apple Wallet, and is an appropriate best practice design for developers to follow as they build/modify their own application to include this capability. This flow covers activities across the mobile app, the Allegion Mobile Access SDK, a generic IdP and the Apple (iOS) wallet.
A detailed code review of these steps is outlined at the end of this guide in the Employee Badge Quick Start App Code Walkthrough.
Note that after a quick device-model check, the first task the app performs is a user authorization. The Quick Start app directs the users to an IdP in a standard OAuth flow to complete the authorization. (The Allegion Quick Start app happens to use Auth0 as the IdP.)
After authorization, the app will do a series of checks to determine if a credential can be generated for the user. The remaining steps are simplified below:
The flow diagram below outlines the decision tree an application should follow to determine if an available NFC should be provisioned to the wallet.
Decision 1 - Is Current Device iPhone? - The device type needs to be determined as not all iOS devices (namely iPads) have NFC capabilities.
Decision 2 - Is the Pass Library available? - The app cannot continue if it does not have necessary resources to generate the pass.
Decision 3 - (If a credential already exists) - Is there a pass already provisioned? - This check is needed to provide a great user experience. If credential provisioning is attempted when a pass already exists, the wallet presents a generic error without a means to determine the "error" was actually a result of the pass (credential) already being provisioned.
Decision 4 - (If a credential already exists) - Is the existing pass deactivated? - The app will not provision a credential if the existing credential has been deactivated.
Decision 5 - (If a credential already exists) - Is the pass Suspended? - The pass can be suspended by the user through the iOS wallet app, through iCloud or by the Access Control system. If a pass is suspended, a link to the pass in the wallet can be provided to the user for further action on their part.
Decision 6 - (If a credential already exists) - Is there a remote pass provisioned? - A remote pass (credential) can be provisioned to devices associated with the iOS device and the user, such as a watch. Being a remote device, the pass (credential) can be managed / removed from the watch independent of the iOS device. If the credential is on the iOS device but not on the remote device, provisioning can still be completed in order to add the pass to the remote device.
Decision 7 - (If a credential already exists) - Can the configuration as built be provisioned? - The app will confirm that the configuration is still valid for provisioning pass.
Provision Pass - If the app reaches this point, either from Decision 3 or Decision 7, it provisions the credential.
Now that we've covered the application flow, we'll move to configuring the environment.
Open the project in XCode.
Open the Environment.plist file which is located in the Supporting Files folder.
We'll be populating this file with relevant configuration details for our environment based on the configuration you've done in previous steps up to this point. This project by default is set to look at Pilot environment variables. The Info.plist file in the top level project folder specifies which environment variables will be used when building the project.
Expand the Pilot variables section.
For SubscriptionKey, enter the value of your Employee Badge Mobile SDK Subscription Key. You can obtain your Mobile SDK Subscription key from the Allegion Developer Portal. Sign into the portal and then click on your name ➡ Profile. Click the Show link next to the Primary Key row to reveal the subscription key.
(Note: If you don't have a Subscription Key listed, another developer on your team may have already been granted one. Allegion only grants one Mobile SDK Subscription Key and one API Subscription Key per organization, so check with your team if you think one may have already been created.)
Copy and paste that key into the Environments file, SubscriptionKey variable, replacing the empty value with the value of your key. (Be sure to paste in the Pilot variables section.)
As you build an Employee Badge solution, your team will be working with APIs and SDKs across two different projects. Each project outlines specific areas of development effort and uses a different subscription key to interact with Allegion. For this guide/project, we'll be focused on mobile app development and so we'll be using the Mobile SDK Subscription Key to interact with Allegion SDKs.
When building the integration between an Access Control System and Allegion Cloud (the subject of a different guide), an API Subscription Key is used. These are each different keys with different permissions, and are not interchangeable. Mixing/matching keys will result in errors and frustration, so we'll make this callout in several places throughout this and other guides.
For IntegrationId, you'll populate this value with the
Integration ID sent to your team by Allegion Customer Success This ID is created for your team by Allegion upon request for provisioning a Schlage Mobile Credentials PACS Configuration, which is covered in the Credential Lifecycle Management ACS Integration Guide. If you have yet requested a Configuration please review that guide for details or reach out to Allegion Customer Success for assistance.
For Domain, you'll populate this with the domain URL of your Identity Management System. This can be obtained from your IdM's application-specific configuration settings.
For ClientId, you'll populate this with a Client ID value obtained from your Identity Management System. This can be obtained from one of your IdM applications application-specific configuration settings.
For Audience, you'll populate this with the following value: https://api.allegion.com/employeebadge
This notes that Allegion's API is the audience, or target, for users making requests using tokens from this identity system.
This error is informing you of the fact that the app is not authorized to make authorization requests to the IdM. We must now configure the IdM to accept and process requests from our new app.
The Quick Start App was designed to use a standard OAuth flow to process authorization requests. You'll need to configure your Identity Management System to recognize requests coming from the Quick Start app in order for the OAuth process to properly flow. To do this, you'll need to specify your Quick Start App as a valid client for performing authorization requests, which involves designating the app's callback and logout URLs.
The Quick Start app uses Auth0 for this purpose, so this guide will demonstrate where to make this change in Auth0, however any IdM will allow this setting to be applied.
Log into Auth0.
Browse to Applications and select the application associated with your app. If you have not created one then create a new application by clicking the Create Application button and following the prompts.
Once in the Application details, scroll down to the Application URIs section. You'll be populating the Allowed Callback URL and Allowed Logout URL:
[App Bundle ID]://[IDM Domain]/ios/[App Bundle ID]/callback
Replace both references of [App Bundle ID]
with your App's Bundle Identifier and replacing [IDM Domain]
with your Auth0 domain (found at the top of the Auth0 application details page). For instance, given Auth0 domain of myapp.us.auth0.com
and App Bundle Identifier of com.mycompany.thisCompanyBadgeApp
, you would populate the Allowed Callback URL as:
com.mycompany.thisCompanyBadgeApp://myapp.us.auth0.com/ios/com.mycompany.thisCompanyBadgeApp/callback
[App Bundle ID]://[Auth0 Domain]/ios/[App Bundle ID]/callback
(Note: The Quick Start app happens to use /callback
as the endpoint for both callback and logout URLs.)
Replace both references of [App Bundle ID]
with your App's Bundle Identifier and replacing [IDM Domain]
with your Auth0 domain (found at the top of the Auth0 application details page). For instance, given Auth0 domain of myapp.us.auth0.com
and App Bundle Identifier of com.mycompany.thisCompanyBadgeApp
, you would populate the Allowed Callback URL as:
com.mycompany.thisCompanyBadgeApp://myapp.us.auth0.com/ios/com.mycompany.thisCompanyBadgeApp/callback
Your Identity Management System will need to provide an API to Allegion so tokens generated in your mobile app can be validated for use with the Allegion Cloud service. Specifically, you'll need to create an API that represents Allegion as the target - or, Audience - for tokens representing this user. Auth0 uses the term Identifier to represent the Audience claim for an API. Your app will then specify a URL representing Allegion's Cloud Service as the Audience. This is a simple task in Auth0 but must be done before the Quick Start app will recognize token that Allegion's cloud will consider valid for processing user requests.
From the Auth0 dashboard, browse to Applications --> APIs
Click the Create API button.
For the Name field, enter a name for your new API such as Allegion Employee Badge App API
For the Identifier field, enter https://api.allegion.com/employeebadge/partner
Notice this value matches the identifier value you specified in your app's audience environment variable value in the app environment configuration step above.
Click the Create button to create the API. Once done, your API should be successfully created and ready to process requests from your app.
Allegion relies on a custom claim sent within your access token (JWT) to capture the email address of the user attempting to add a mobile credential. The email address is an important piece of information because it's used as the key/unique identifier that ties identity of the user in the IdM and the Access Control System to a User Access Right record in Allegion's cloud. While other claims in access tokens generated by your IdM may already contain the user email address (such as email
or sub
claims), there is no standard or requirement that an IdM must use a specific claim to assert email address. Allegion uses a custom claim to enforce a standard approach for asserting user email since it's important and required
name
that asserts that the name of the user authenticating is "Isaac Bond". Claim represent information as name/value pairs where the name is a string and the value can be any valid JSON value. Custom claims are claims that are added to the JWT and arenot part of any standard.
Here's the structure of the custom claim that should be included in access JWTs when using this option:
"https://api.allegion.com/email": [email]
Where [email]
is replaced by the email address of the user identified by the accessJWT.
The process for adding a custom claim to your access JWT will be different depending on the IdM you use.
If you happen to use Auth0 as your IdM provider, the recommended method for adding a custom claim is to add an Action to the Login Flow of your application with custom code to add the claim. Details on adding an action to the Login flow for an Auth0 application for Auth0 are detailed here and a demonstrable video is available here; you may use the following sample code as the basis for your login flow action:
/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
// This rule adds the authenticated user's email address to the access and id tokens.
if (event.authorization) {
const namespace = "https://api.allegion.com";
api.accessToken.setCustomClaim(namespace+"/email", event.user.email);
api.idToken.setCustomClaim(namespace+"/email", event.user.email);
console.log("Adding custom claim -" + namespace+"/email:" + event.user.email);
}
};
The code above defines an action that adds the custom claim to both the access token and ID token. It also outputs a message to the log regarding the additional claim value. If you're using Auth0 you can look at Auth0 logs to confirm your claim is being successfully processed:
Once you've completed all steps above, you are ready to build and run the app.
Open XCode.
Ensure the Sandbox Apple Account (created in the step above) is logged in on the test iOS device.
Plug the test iOS device into the build machine.
Build and run the app, targeting the iOS device. To test adding a credential to Apple Wallet, you'll need to target a physical iOS device - simulated devices do not have access to a Sandbox Wallet, and development testing with mobile credentials requires the Sandbox Wallet. The app should load to the login screen and display the Schlage logo.
Enter a valid username and password from your IdM to log in. If you have not yet created an account then click the Sign up link to create one.
Login and follow the prompts to provision a mobile credential into the Apple Wallet. This flow will continue, generating a mobile credential and prompting the user to authorize adding the credential to the wallet.
If after logging into the app you are presented with the error, "Authentication Error Additional error detail is not available...", this is potentially due to a misconfiguration of the Employee Badge cloud environment, misconfiguration of your XCode environment variables or misconfiguration of your Auth0 environment. To check the cause of the issue, open XCode and review the latest log output for the following error:
{"errors":null,"errorCode":"IdTokenInvalid",
"type":"https://api.allegion.com/errors/producers/MahApi/errorcodes/IdTokenInvalid",
"details":"Invalid Open Id Token.","producerId":"MahApi","title":"The ID Token failed validation.",
"instance":null,"status":400}
This error points to a problem using the token obtained from the IdM to authorize the user as a valid PACS patron. To solve this problem you'll need to work with Allegion Customer Success to ensure your Employee Badge Cloud environment is properly configured based on the properties supplied to Allegion in the Request API Access step of this guide.
If all steps were successfully complete you should be able to run your app. From here your credential will need to be provisioned in the Physical Access Control System (PACS) in order to be used, which may be similar to the process for provisioning physical credentials. PACS Configuration is unique to your environment and beyond the scope of this document.
Allegion requires functional testing and certification to be completed for all implementations of mobile credentials before any production launch. The following table lists links to test and certification requirements for Google Wallet Mobile Credentials that will be required to be completed by partners before production certification and/or a site launch.
Vertical | Test Guidelines |
---|---|
Functional Testing Guidelines for All Verticals | |
Corporate Badge | Corporate Badge Testing Checklist |
Campus ID | TBD |
Multifamily | TBD |
After a successful build of the app you can focus on changing the logo as well as card art by following our Guide on Employee Badge Card Art (TBD).
This section details the Quick Start app as a walkthrough so developers can understand which sections of code are performing each of the tasks outlined in the sequence diagram above. The steps below directly reference the numbered steps in the General Application Flow sequence diagram.
The Allegion Quick Start App enrollment application uses Auth0 as the Identity Provider (IdP) to authenticate the user. Auth0 provides a native SDK for integrating with their functionality. Note that any Identity Management System can be used here. The code for kicking off authentication appears in the AuthenticatedViewController.
File: AuthenticatedViewController.swift - Project File
Auth0
.webAuth(clientId: configuration.clientId, domain: configuration.domain)
.scope("openid email profile")
.audience(configuration.audience)
.start { result in
switch result {
case .failure(let error):
self.logWriter.log("Login failure - error:\(error)")
DispatchQueue.main.async { [self] in
let alertView = buildAlertViewWithOKButton(localizedTitle: .authenticateErrorTitle,
localizedMessage: .authenticateError)
present(alertView, animated: true)
}
case .success(let credentials):
self.logWriter.log("login success!!")
DispatchQueue.main.async { [self] in
showAuthenticatedViewController(credentials: credentials)
}
}
}
On line 17, the credentials element contains an accessToken and an idToken. These two elements, along with the integrationId (which is maintained as a configuration property of the application) are provided to the SDK for authentication.
The SDK is initialized with a Employee Badge Mobile SDK Subscription Key (instructions on obtaining this key detailed above) and an optional TLS certificate pinning pinSet within a MobileAccessConfiguration instance. Please consult the MobileAccess SDK documentation for additional information on the initialize method. The call to the MobileAccessSDK's initialize method is in AuthenticatedViewController:
File: AuthenticatedViewController.swift - Project File
let mobileAccessConfiguration = MobileAccessConfiguration(subscriptionKey: parsedSubscriptionKey, pinSet: nil)
try mobileAccessSDK!.initialize(configuration: mobileAccessConfiguration)
Before initiating any processes using the MobileAccessSDK, it is necessary to first initialize, and then authenticate. It is necessary to authenticate at least once per SDK instance. It is possible to check the SDKs authentication status and authenticate if the SDK is not authenticated as follows:
File: AuthenticatedViewController.swift - Project File
if !mobileAccessSDK.isAuthenticated {
// SDK is not authenticated - starting authenticate process
let authenticateRequest = AuthenticateRequest(idToken: credentials.idToken,
accessToken: credentials.accessToken,
integrationID: integrationId)
do {
try mobileAccessSDK.authenticate(request: authenticateRequest, completion: self)
} catch {
// ERROR HANDLING
}
}
Note the authenticate method takes request and completion parameters. The completion parameter should implement the AuthenticateDelegate protocol in the MobileAccessSDK:
File: AuthenticateDelegate.swift - Allegion Mobile Access SDK Pod file
import Foundation
@objc public protocol AuthenticateDelegate {
/// Callback for a successful result of issuing an authenticate request
///
/// - Parameter stateUpdated: `AuthenticationState` represents the current state of authentication at the moment the update was sent
@objc func authenticate(stateUpdated: AuthenticationState)
/// Callback for an unsuccessful attempt of issuing an authenticate request
///
/// - Parameter failed: `Error` object containing a description of the error encountered when issuing the request
@objc func authenticate(failed: Error)
}
An implementation of the above delegate may look something like this:
File: AuthenticatedViewController.swift - Project File
extension AuthenticatedViewController: AuthenticateDelegate {
func authenticate(stateUpdated: AuthenticationState) {
// device authentication state updated
if stateUpdated == .completed {
DispatchQueue.main.async { [self] in
// REQUEST ACCESS RIGHTS
}
}
}
func authenticate(failed: Error) {
// device authentication failed
// ERROR HANDLING
}
}
Note that other operations which use the SDK, such as request access rights, can only be requested until after authentication has reached the .completed
state. This and other possible authentication states can be seen below:
File: AuthenticationState.swift - Allegion Mobile Access SDK Pod file
import Foundation
@objc public enum AuthenticationState: Int {
/// Represents a state where the SDK is creating a Device ID, Account, and ConnectedAccount
case enrolling
/// Represents a state where the SDK is creating a ConnectedAccount
case creatingConnectedAccount
/// Represents a state where the SDK is selecting the matching ConnectedAccount given the AuthenticationRequest params
case selectingConnectedAccount
/// Represents a state where the SDK has completed authentication and another operation may be requested by the client
case completed
}
After initializing and authenticating, the access rights for the current user can be retrieved via the MobileAccessSDK's retrieveAccessRights method:
File: AuthenticatedViewController.swift - Project File
private var mobileAccessSDKInstance: MobileAccessSDK?
var mobileAccessSDK: MobileAccessSDK {
if mobileAccessSDKInstance == nil {
mobileAccessSDKInstance = MobileAccessFactory().sdk()
}
return mobileAccessSDKInstance!
}
private func retrieveAccessRights() {
presentationCoordinator?.updateActivityIndicatorMessage(LocalizationService.getMessage(.retrievingAccessRights), displayActivityIndicatorIfNotPresented: true)
do {
try mobileAccessSDK.retrieveAccessRights(completion: self, ignoreCache: true)
} catch {
logWriter.log("SDK retrieveAccessRights threw an error - error says:[\(error)]")
presentationCoordinator?.presentRetrieveAccessRightsError(error: error)
}
}
The first parameter passed to retrieveAccessRights is a RetrieveAccessRightsDelegate:
File: RetrieveAccessRightsDelegate.swift - Allegion Mobile Access SDK Pod file
/// Delegate for the "retrieve access rights" operation
@objc public protocol RetrieveAccessRightsDelegate: AnyObject {
/// success response handler for the retrieve access rights operation
///
/// - Parameter succeeded: `RetrieveAccessRightsResponse` response model with access rights for currently selected connected account
@objc func retrieveAccessRights(succeeded: RetrieveAccessRightsResponse)
/// error response handler for the retrieve access rights operation
///
/// - Parameter failed: `[Error]` collection of errors encountered while issuing and transition from the request
@objc func retrieveAccessRights(failed: [Error])
}
The RetrieveAccessRightsResponse has an accessRights member of type ConnectedAccountAccessRights:
File: RetrieveAccessRightsResponse.swift - Allegion Mobile Access SDK Pod file
public class RetrieveAccessRightsResponse: NSObject {
@objc public let accessRights: ConnectedAccountAccessRights
}
The ConnectedAccountAccessRights type maintains collections of both NFC and BLE access rights:
File: ConnectedAccountAccessRights.swift - Allegion Mobile Access SDK Pod file
public class ConnectedAccountAccessRights: NSObject {
/// `[AccessRight]` a collection of rights with nfc credentials.
@objc public let nfcCredentialRights: [AccessRight]
/// `[AccessRight]` a collection of rights with ble credentials.
@objc public let bleCredentialRights: [AccessRight]
}
An access right is determined to have an NFC payload available when the nfcCredentialRights property in the ConnectedAccountAccessRights instance is not empty. The ConnectedAccountAccessRights instance is contained in the RetrieveAccessRightsResponse instance returned through the RetrieveAccessRightsDelegate. The code for checking the payload type of the access rights appears in AuthenticatedViewController:
File: AuthenticatedViewController.swift - Project File
func retrieveAccessRights(succeeded: RetrieveAccessRightsResponse) {
let nfcCredentials = succeeded.accessRights.nfcCredentialRights
if !nfcCredentials.isEmpty {
// NFC RIGHTS FOUND!
DispatchQueue.main.async {
self.preparePushProvisioning(nfcAccessRight: nfcCredentials[0])
}
} else {
// HANDLE CASE OF NO NFC RIGHTS AVAILABLE
}
}
Once an NFC access right is identified, a call to the MobileAccessSDK's preparePushProvisioning method can be completed. This returns the required credential metadata to be passed to the iOS wallet to eventually provision the pass (credential). This call occurs in the NFCCredentialProvisioningService:
File: NFCCredentialProvisioningService.swift - Project File
do {
try mobileAccessSDK.preparePushProvisioning(nfcAccessRight: nfcAccessRight, completion: self)
} catch {
// HANDLE ERRORS
}
The call to preparePushProvisioning requires a PreparePushProvisioningDelegate passed via the completion parameter:
File: PreparePushProvisioningDelegate.swift - Allegion Mobile Access SDK Pod file
@objc public protocol PreparePushProvisioningDelegate: AnyObject {
/// Callback for a successful result of issuing a prepare push provisioning request
///
/// - Parameter succeeded: `PreparePushProvisioningResponse` response for a prepare push provisioning request
@objc func preparePushProvisioning(succeeded: PreparePushProvisioningResponse)
/// Callback for an unsuccessful attempt of issuing a prepare push provisioning request
///
/// - Parameter failed: `Error` object containing a description of the error encountered when issuing the request
@objc func preparePushProvisioning(failed: [Error])
}
The PreparePushProvisioningResponse contains the pass (credential) metadata needed by the iOS wallet to initiate pass (credential) provisioning:
File: PreparePushProvisioningResponse.swift - Allegion Mobile Access SDK Pod file
public class PreparePushProvisioningResponse: NSObject {
@objc public let provisioningCredentialIdentifier: String
@objc public let cardConfigurationIdentifier: String
@objc public let sharingInstanceIdentifier: String
@objc public let referenceIdentifier: String
@objc public let passThumbnailImage: CGImage
@objc public let ownerDisplayName: String
@objc public let localizedDescription: String
}
The next step in the provisioning process now that it has been determined an NFC credential is available for the user is to determine if the pass library is available on the iOS device. This is determined via a class level boolean exposed on the Apple class PKPassLibrary. This code is within the NCFPassUtility class:
File: NFCPassUtility.swift - Project File
guard PKPassLibrary.isPassLibraryAvailable() else {
// HANDLE PASS LIBRARY NOT AVAILABLE
return
}
File: NFCPassUtility.swift - Project File
let passLibrary = PKPassLibrary()
self.passes = passLibrary.passes()
The code to retrieve passes exists in the NFCPassUtility class within the Allegion Quick Start App.
Similarly, passes available to the application residing on remote devices - such as an Apple Watch, can be retrieved from a PKPassLibrary instance.
File: NFCPassUtility.swift - Project File
let passLibrary = PKPassLibrary()
self.remoteSecureElementsPasses = passLibrary.remoteSecureElementPasses
The code to retrieve remote passes exists in the NFCPassUtility class within the Allegion Quick Start App.
Determine if a local pass exists for the current user is accomplished by searching the (local) pass array matching the primaryAccountIdentifier on the pass to the PreparePushProvisioningResponse.referenceIdentifier
retrieved in the PreparePushProvisioning response from the MobileAccessSDK's preparePushProvisioning call.
File: NFCPassUtility.swift - Project File
func localPassExists() -> Bool {
return passes.contains { pkPass in
guard let paymentPass = pkPass as? PKPaymentPass else {
return false
}
return paymentPass.isRemotePass == false &&
paymentPass.primaryAccountIdentifier == primaryAccountIdentifier
}
}
The code to determine the existence of a local payment pass resides in the NFCPassUtility class within the Allegion Quick Start App.
If a local pass is found, the passActivationState indicates if the pass is deactivated.
File: NFCPassUtility.swift - Project File
func isLocalPassInDeactivatedState() -> Bool {
return passes.contains { pkPass in
guard let paymentPass = pkPass as? PKPaymentPass else {
return false
}
return paymentPass.isRemotePass == false &&
paymentPass.primaryAccountIdentifier == primaryAccountIdentifier &&
paymentPass.passActivationState == .deactivated
}
}
The code to determine if a local payment pass is disabled appears in the NFCPassUtility class within the Allegion Quick Start App.
If a local pass exists it may be in a suspended state which would preclude provisioning the pass (credential) again.
File: NFCPassUtility.swift - Project File
func isLocalPassInSuspendedState() -> Bool {
return passes.contains { pkPass in
guard let paymentPass = pkPass as? PKPaymentPass else {
return false
}
return paymentPass.isRemotePass == false &&
paymentPass.primaryAccountIdentifier == primaryAccountIdentifier &&
paymentPass.passActivationState == .suspended
}
}
The code to determine if a local payment pass is suspended appears in the NFCPassUtility class within the Allegion Quick Start app.
If a local pass and remote pass both exist, attempting to provision the pass (credential) again will result in the iOS wallet returning a generic error. Checking for the existence of a remote pass prior to provisioning will allow the application to proactively notify the user the pass (credential) is already provisioned. The code to determine if a remote pass exists appears in the NFCPassUtility class:
File: NFCPassUtility.swift - Project File
func remotePassExists() -> Bool {
return remoteSecureElementsPasses.contains { remoteSecureElementsPass in
return remoteSecureElementsPass.isRemotePass == true &&
remoteSecureElementsPass.primaryAccountIdentifier == primaryAccountIdentifier
}
}
If provisioning is good to move forward, the next step in the process is to create a PKShareablePassMetadata instance. This is completed in the NFCCredentialProvisioningService:
File: NFCCredentialProvisioningService.swift - Project File
guard let shareablePassMetaData = PKShareablePassMetadata(provisioningCredentialIdentifier: nfcCredentialProvisioningElements.provisioningCredentialIdentifier,
cardConfigurationIdentifier: nfcCredentialProvisioningElements.cardConfigurationIdentifier,
sharingInstanceIdentifier: nfcCredentialProvisioningElements.sharingInstanceIdentifier,
passThumbnailImage: nfcCredentialProvisioningElements.passThumbnailImage,
ownerDisplayName: nfcCredentialProvisioningElements.ownerDisplayName,
localizedDescription: nfcCredentialProvisioningElements.localizedDescription) else {
// HANDLE ERRORS
}
The NFCCredentialProvisioningElements instance referenced in the above code is of type NFCCredentialProvisioningElements. The definition appears as:
File: NFCCredentialProvisioningElements.swift - Project File
struct NFCCredentialProvisioningElements {
let provisioningCredentialIdentifier: String
let cardConfigurationIdentifier: String
let sharingInstanceIdentifier: String
let passThumbnailImage: CGImage
let ownerDisplayName: String
let localizedDescription: String
}
The Allegion Quick Start App defines an extension on the MobileAccessSDK's PreparePushProvisioningResponse to create an NFCCredentialProvisioningElements:
File: PreparePushProvisioningResponse+Transforms.swift - Project File
extension PreparePushProvisioningResponse {
func toNFCCredentialProvisioningElements() -> NFCCredentialProvisioningElements {
return NFCCredentialProvisioningElements(provisioningCredentialIdentifier: self.provisioningCredentialIdentifier,
cardConfigurationIdentifier: self.cardConfigurationIdentifier,
sharingInstanceIdentifier: self.sharingInstanceIdentifier,
passThumbnailImage: self.passThumbnailImage,
ownerDisplayName: self.ownerDisplayName,
localizedDescription: self.localizedDescription)
}
}
The PKShareablePassMetadata is then used to create the PKAddShareablePassConfiguration. This code appears in the NFCCredentialProvisioningService:
File: NFCCredentialProvisioningService.swift - Project File
PKAddShareablePassConfiguration.forPassMetaData([passMetaData],
provisioningPolicyIdentifier: NFCCredentialProvisioningElementsConstants.provisioningPolicyIdentifier,
action: PKAddShareablePassConfigurationPrimaryAction.add,
completion: {(shareablePassConfiguration, error) in
// PROCESS RESPONSE -> IMPORTANT TO CHECK THE error INSTANCE!!
}
The code sample above calls out checking the error argument passed to the completion handler. This error is an instance of NSError. When the value of the domain property is PKAddSecureElementPassErrorMapperDomain, the error code maps to the (enum) type PKAddSecureElementPassError.
At this point, it is necessary to confirm with the PKAddSecureElementPassViewController that the configuration can be provisioned. The Apple class PKAddSecureElementPassViewController provides a class level method, canAddSecureElementPass(), that validates the PKAddShareablePassConfiguration can be used for provisioning:
File: NFCCredentialProvisioningService.swift - Project File
let canProvision = PKAddSecureElementPassViewController.canAddSecureElementPass(configuration: unwrappedShareablePassConfiguration)
This code appears in the NFCCredentialProvisioningService.
The final step in preparing for provisioning is the create a PKAddSecureElementPassViewController that can be presented to the user to initiate adding the pass (credential) to then wallet. Creating is straight forward and appears in NFCCredentialProvisioningService.
File: NFCCredentialProvisioningService.swift - Project File
guard let addSecureElementPassViewController = PKAddSecureElementPassViewController(configuration: shareablePassConfiguration,
delegate: self.addSecureElementPassViewControllerDelegate) else {
// HANDLE ERROR
}
With a PKAddSecureElementPassViewController instance available, an add to wallet button (an instance of PKAddPassButton) can be displayed. When tapped, the button can present the PKAddSecureElementPassViewController instance which takes over the UI experience for adding the pass (credential) to the wallet.
File: AuthenticatedViewController.swift - Project File
@objc func onAddToWalletButton(_ sender: Any) {
if let addToWalletVC = addToWalletVC {
present(addToWalletVC, animated: true)
}
}
The code to present the PKAddSecureElementPassViewController (represented by the class level addToWalletVC property) appears in AuthenticatedViewController
The Allegion Quick Start App application provides the NFCCredentialProvisioningService class as well as supporting utility classes to make integrating with the iOS wallet app as well as the Mobile Access SDK simpler. It was designed with a goal of compartmentalizing as much of the wallet integration as possible allowing our partners to jump start their integrations. Using the NFCCredentialProvisioningService will requiring importing Allegion concepts around error handling - PersonaManagerEnrollmentError, utility classes such as NFCPassUtility and our logging implementation, Ecrivain.
The class encapsulates Steps 7-20 in the preceding diagram. The createAddSecureElementPassViewController method kicks the process off:
File: NFCCredentialProvisioningService.swift - Project File
func createAddSecureElementPassViewController(
nfcAccessRight: AccessRight,
addSecureElementPassViewControllerDelegate: PKAddSecureElementPassViewControllerDelegate? ,
delegate: CreateAddSecureElementPassViewControllerDelegate?) throws
The method requires a previously retrieved Access Right which has an NFC payload. Also required is the Apple defined PKAddSecureElementPassViewControllerDelegate which will be assigned when the PKAddSecureElementPassViewController is successfully created.
Once created, the PKAddSecureElementPassViewController instance is returned via the CreateAddSecureElementPassViewControllerDelegate which appears as:
File: CreateAddSecureElementPassViewControllerDelegate.swift - Project File
protocol CreateAddSecureElementPassViewControllerDelegate: AnyObject {
func createAddSecureElementPassViewController(succeeded: PKAddSecureElementPassViewController, badgeImprintData: BadgeImprintData)
func createAddSecureElementPassViewController(failed: Error)
}
The Error returned will be of type PersonaManagerEnrollmentError:
File: PersonaManagerEnrollmentError.swift - Project File
class PersonaManagerEnrollmentError: LocalizedError, Equatable, Hashable, CustomDebugStringConvertible {
static let PersonaManagerEnrollmentDomain = "com.allegion.PersonaManagerEnrollment"
let domain: String
let errorCode: Int
public internal (set) var source: PersonaManagerEnrollmentError?
public internal (set) var errorDescription: String?
public internal (set) var failureReason: String?
public internal (set) var recoverySuggestion: String?
public internal (set) var helpAnchor: String?
}