### Initialize ClaySDK and Get Public Key Source: https://github.com/claysolutions/claysdk/blob/master/README.md Initialize the ClaySDK with your installation UID, API key, and a delegate conforming to ClayDelegate. The getPublicKey() method retrieves the public key required for mobile key activation via the API. ```swift import ClaySDK //... //'self' must conform to ClayDelegate, the apiKey will be provided to you let clay = ClaySDK(installationUID: "SOME_UNIQUE_ID", apiKey: "THE_API_PUBLIC_KEY", delegate: self) //... // Public key that you need to send via API to activate mobile key let publicKey = clay.getPublicKey() //... ``` -------------------------------- ### Install ClaySDK via CocoaPods Source: https://context7.com/claysolutions/claysdk/llms.txt Add the dependency to your Podfile and run the installation command. ```ruby # Podfile platform :ios, '11.0' target 'YourApp' do use_frameworks! pod 'ClaySDK', '~> 1.11' end ``` ```bash # Install dependencies pod install ``` -------------------------------- ### ClaySDK Initialization Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Initializes the ClaySDK with installation UID, API key, and a delegate for feedback. ```APIDOC ## ClaySDK Initialization ### Description Initializes the ClaySDK with the provided installation UID, API key, and delegate. ### Method `init(installationUID:apiKey:delegate:)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response None #### Success Response (200) None #### Response Example None ``` -------------------------------- ### Install ClaySDK via Carthage Source: https://github.com/claysolutions/claysdk/blob/master/docs/index.html Add this line to your Cartfile to manage the dependency with Carthage. ```text github "ClaySolutions/ClaySDK" "1.8.0" ``` -------------------------------- ### Initialize ClaySDK Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Initializes the ClaySDK instance with the required installation UID, API key, and delegate. ```Swift @objc public convenience init(installationUID: String, apiKey: String, delegate: ClayDelegate) ``` -------------------------------- ### Install ClaySDK with CocoaPods Source: https://github.com/claysolutions/claysdk/blob/master/README.md Add this line to your Podfile to install the ClaySDK using CocoaPods. Ensure you are using a compatible version. ```ruby pod 'ClaySDK', '~> 1.10' ``` -------------------------------- ### Install ClaySDK via CocoaPods Source: https://github.com/claysolutions/claysdk/blob/master/docs/index.html Add this line to your Podfile to include the SDK in your project. ```ruby pod 'ClaySDK', '~> 1.8' ``` -------------------------------- ### ClayResult Class Overview Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClayResult.html Provides an overview of the ClayResult class, its purpose, and an example of how to use it within the SaltoJustINMobileSDK. ```APIDOC ## ClayResult Class `ClayResult` is the result returned by the `openDoor(with:delegate:)` method. ### Example Usage ```swift import SaltoJustINMobileSDK // ... func didOpen(with result: ClayResult?) { guard let result = result else { return } if (result.getOpResult() == AUTH_SUCCESS_ACCESS_GRANTED) { // access granted } // or by using SSOperationGrup let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // success break case .groupFailure, .groupRejected, .groupUnknownResult: break default: break } } ``` ``` -------------------------------- ### Handle Open Door Result Source: https://github.com/claysolutions/claysdk/blob/master/README.md Implement the didOpen method in your OpenDoorDelegate to handle the ClayResult. This example shows how to check if the key was successfully sent to the lock using SSOperationGrup. ```swift import SaltoJustINMobileSDK //... func didOpen(with result: ClayResult?) { guard let result = result else { return } // by using SSOperationGrup let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // key sucessfully sent to lock (we don't know if user have access, access is indicated by light of the lock) break case .groupFailure, .groupRejected, .groupUnknownResult: // there was a problem with sending key to the lock break default: break } } ``` -------------------------------- ### GET /claysdk/ClayResult/getOpResult Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClayResult.html Retrieves the authentication operation result code from a ClayResult object. ```APIDOC ## GET /claysdk/ClayResult/getOpResult ### Description Authentication operation result ### Method GET ### Endpoint `/claysdk/ClayResult/getOpResult` ### Return Value - **Int** - Result code. One of `SSOpResult` codes. ``` -------------------------------- ### Initialize and Use ClaySDK Source: https://github.com/claysolutions/claysdk/blob/master/docs/index.html Initialize the SDK with your credentials and use it to retrieve a public key or open a door. The delegate must conform to the appropriate protocols. ```swift import ClaySDK //... //'self' must conform to ClayDelegate, the apiKey will be provided to you let clay = ClaySDK(installationUID: "SOME_UNIQUE_ID", apiKey: "THE_API_PUBLIC_KEY", delegate: self) //... // Public key that you need to send via API to activate mobile key let publicKey = clay.getPublicKey() //... //'yourOpenDoorDelegate' must conform to OpenDoorDelegate clay.openDoor(with: "your-encrypted-key", delegate: yourOpenDoorDelegate) ``` -------------------------------- ### Initialize ClaySDK Source: https://context7.com/claysolutions/claysdk/llms.txt Configure the ClaySDK instance within a UIViewController and implement the ClayDelegate to handle errors. ```swift import ClaySDK import UIKit class DoorController: UIViewController, ClayDelegate { private var clay: ClaySDK! override func viewDidLoad() { super.viewDidLoad() // Initialize ClaySDK with unique installation ID and API key // The installationUID should be unique per device/installation // The apiKey is provided by Clay/Salto KS clay = ClaySDK( installationUID: "com.yourapp.installation.\(UIDevice.current.identifierForVendor?.uuidString ?? UUID().uuidString)", apiKey: "YOUR_API_PUBLIC_KEY_FROM_CLAY", delegate: self ) } // MARK: - ClayDelegate func didReceive(error: Error) { // Handle SDK initialization errors if let clayError = error as? ClayError { switch clayError { case .invalidApiKey: print("Invalid API key provided") case .storeError: print("Failed to store keys in Keychain") case .storeLoadError: print("Failed to load keys from Keychain - try reloadKeys()") default: print("Clay error: \(clayError.localizedDescription)") } } } } ``` -------------------------------- ### Initialize ClaySDK and Manage Access Control Source: https://context7.com/claysolutions/claysdk/llms.txt Manages ClaySDK initialization, public key retrieval, and the door opening process. Implements ClayDelegate and OpenDoorDelegate for handling SDK events and operations. Ensure the SDK is initialized before attempting to open a door. ```swift import UIKit import ClaySDK import SaltoJustINMobileSDK class AccessControlManager: NSObject, ClayDelegate, OpenDoorDelegate { static let shared = AccessControlManager() private var clay: ClaySDK! private var isInitialized = false private var pendingDoorOperation: ((Bool, String) -> Void)? // MARK: - Initialization func initialize(withApiKey apiKey: String) { let installationUID = getOrCreateInstallationUID() clay = ClaySDK(installationUID: installationUID, apiKey: apiKey, delegate: self) } private func getOrCreateInstallationUID() -> String { let key = "ClaySDK_InstallationUID" if let existing = UserDefaults.standard.string(forKey: key) { return existing } let newUID = UUID().uuidString UserDefaults.standard.set(newUID, forKey: key) return newUID } // MARK: - Public API var devicePublicKey: String { return clay.getPublicKey() } func openDoor(withKey encryptedKey: String, completion: @escaping (Bool, String) -> Void) { guard isInitialized else { completion(false, "SDK not initialized") return } pendingDoorOperation = completion clay.openDoor(with: encryptedKey, delegate: self) } // MARK: - ClayDelegate func didReceive(error: Error) { if let clayError = error as? ClayError { switch clayError { case .storeLoadError, .storeError: // Attempt recovery DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { if self?.clay.reloadKeys() == true { self?.isInitialized = true } } default: isInitialized = false } pendingDoorOperation?(false, clayError.localizedDescription) } else { isInitialized = true // No error means successful init } } // MARK: - OpenDoorDelegate func didFindLock() { print("Lock discovered via Bluetooth") } func didOpen(with result: ClayResult?) { guard let result = result else { pendingDoorOperation?(false, "No result") return } let group = SSOpResult.getGroup(result.getOpResult()) let success = (group == .groupAccepted) let message = success ? "Door opened successfully" : "Access denied" pendingDoorOperation?(success, message) pendingDoorOperation = nil } func didReceiveTimeout() { pendingDoorOperation?(false, "Connection timed out") pendingDoorOperation = nil } func alreadyRunning() { pendingDoorOperation?(false, "Operation already in progress") pendingDoorOperation = nil } func didReceiveBLE(error: Error) { pendingDoorOperation?(false, "Bluetooth error: \(error.localizedDescription)") pendingDoorOperation = nil } } ``` -------------------------------- ### Handle Open Success Event Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html Callback triggered when the door opening process completes. ```Swift func didOpen(with result: ClayResult?) ``` -------------------------------- ### Open doors with openDoor(with:delegate:) Source: https://context7.com/claysolutions/claysdk/llms.txt Initiates a BLE-based door opening operation using an encrypted mobile key. Implement the OpenDoorDelegate protocol to handle discovery, success, and error states. ```swift import ClaySDK import SaltoJustINMobileSDK class DoorOpener: NSObject, OpenDoorDelegate { let clay: ClaySDK var completionHandler: ((Bool, String) -> Void)? init(clay: ClaySDK) { self.clay = clay } func openDoor(withEncryptedKey encryptedKey: String, completion: @escaping (Bool, String) -> Void) { self.completionHandler = completion // Initiate door opening with the encrypted mobile key clay.openDoor(with: encryptedKey, delegate: self) } // MARK: - OpenDoorDelegate func didFindLock() { // Lock was discovered via BLE print("Lock found, attempting to authenticate...") } func didOpen(with result: ClayResult?) { guard let result = result else { completionHandler?(false, "No result returned") return } // Check operation result using SSOpResultGroup let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // Key was successfully sent to lock // Note: Actual access granted/denied is indicated by the lock's LED completionHandler?(true, "Access request sent successfully") case .groupRejected: completionHandler?(false, "Access rejected by lock") case .groupFailure: completionHandler?(false, "Communication failure with lock") case .groupUnknownResult: completionHandler?(false, "Unknown result from lock") @unknown default: completionHandler?(false, "Unexpected result") } } func didReceiveTimeout() { // BLE communication timed out - lock may be out of range completionHandler?(false, "Connection timed out - ensure you are near the lock") } func alreadyRunning() { // Another door opening operation is in progress completionHandler?(false, "Another door operation is already in progress") } func didReceive(error: Error) { // General error during operation completionHandler?(false, "Error: \(error.localizedDescription)") } func didReceiveBLE(error: Error) { // Bluetooth-specific error completionHandler?(false, "Bluetooth error: \(error.localizedDescription)") } } ``` -------------------------------- ### didReceive(error:) Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/ClayDelegate.html Handles error feedback received from the ClaySDK initialization process. ```APIDOC ## didReceive(error:) ### Description Handles error feedback during the ClaySDK initialization process. ### Method Delegate Callback ### Parameters #### Parameters - **error** (Error) - Required - The error object returned by the SDK initialization process. ### Request Example func didReceive(error: Error) { print("Initialization failed with error: \(error.localizedDescription)") } ``` -------------------------------- ### openDoor(with:delegate:) Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Opens a lock using an encrypted Mobile Key and a provided delegate for feedback. ```APIDOC ## openDoor(with:delegate:) ### Description Opens a specified lock using a Mobile Key. The key must be the encrypted Mobile Key obtained from the Clay Locking Platform. A delegate is required to handle the feedback during the door opening process. ### Method `openDoor(with key: String, delegate: OpenDoorDelegate)` ### Endpoint None (Instance method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) None (Feedback is provided via the `OpenDoorDelegate`) #### Response Example None ``` -------------------------------- ### Declare ClayDelegate protocol Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols.html Implement this protocol to receive feedback and handle errors during ClaySDK initialization. ```Swift @objc public protocol ClayDelegate : AnyObject ``` -------------------------------- ### Handle Already Running Event Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html Callback triggered when an MKey process is already in progress. ```Swift func alreadyRunning() ``` -------------------------------- ### Handle ClayResult and SSOpResult in Swift Source: https://context7.com/claysolutions/claysdk/llms.txt Demonstrates how to switch on detailed operation result codes and categorize outcomes into groups using ClayResult and SSOpResult. ```swift import ClaySDK import SaltoJustINMobileSDK class ResultHandler { func handleDetailedResult(_ result: ClayResult) { let opResult = result.getOpResult() // Check specific operation result codes switch UInt8(opResult) { case AUTH_SUCCESS_ACCESS_GRANTED: print("Access granted - door opened") case AUTH_SUCCESS_ACCESS_REJECTED: print("Access rejected - insufficient permissions") case AUTH_SUCCESS_DOOR_IN_OFFICE: print("Door opened with office mode enabled") case AUTH_SUCCESS_END_OFFICE: print("Door closed with office mode disabled") case AUTH_SUCCESS_OPENING_ROLLER: print("Roller door opening") case AUTH_SUCCESS_CLOSING_ROLLER: print("Roller door closing") case AUTH_SUCCESS_STOP_ROLLER: print("Roller door stopped") case AUTH_SUCCESS_WAIT_SECOND_CARD: print("Waiting for second key - dual authentication required") case AUTH_SUCCESS_PIN_REQUIRED: print("PIN required before key presentation") case AUTH_SUCCESS_CANCELLED_KEY: print("Key has been cancelled and should be deleted") case AUTH_SUCCESS_FINGER_REQUIRED: print("Fingerprint required before key presentation") case AUTH_SUCCESS_KEY_PROCESSED: print("Key data processed successfully") case AUTH_SUCCESS_UNKNOWN_RESULT: print("Authentication successful but result unknown") default: print("Unrecognized result code: \(opResult)") } } func handleGroupedResult(_ result: ClayResult) { let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // kGroupAccepted - operation was accepted showSuccessUI() case .groupRejected: // kGroupRejected - operation was rejected showAccessDeniedUI() case .groupFailure: // kGroupFailure - operation failed showErrorUI() case .groupUnknownResult: // kGroupUnknownResult - unknown outcome showUnknownResultUI() @unknown default: break } } private func showSuccessUI() { /* ... */ } private func showAccessDeniedUI() { /* ... */ } private func showErrorUI() { /* ... */ } private func showUnknownResultUI() { /* ... */ } } ``` -------------------------------- ### getPublicKey() Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Fetches the App Public Key, which is Base64 encoded. ```APIDOC ## getPublicKey() ### Description Fetches the App Public Key. This key is Base64 encoded. ### Method `getPublicKey()` ### Endpoint None (Instance method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **String** - The Base64 encoded Public Key #### Response Example ``` "your_base64_encoded_public_key" ``` ``` -------------------------------- ### OpenDoorDelegate Protocol Methods Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html Methods to be implemented by the delegate to handle feedback from the openDoor(with:delegate:) operation. ```APIDOC ## didFindLock() ### Description Called when a lock is successfully found. ## didOpen(with:) ### Description Called when the door has been opened. ### Parameters - **result** (ClayResult?) - The result object containing details about the operation. ## didReceiveTimeout() ### Description Called when the operation times out. ## alreadyRunning() ### Description Called when the MKey process is already running. ## didReceiveBLE(error:) ### Description Called when a Bluetooth Low Energy (BLE) error occurs. ### Parameters - **error** (Error) - The error object describing the BLE failure. ``` -------------------------------- ### Define OpenDoorDelegate Protocol Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html The protocol definition for handling door opening feedback. ```Swift @objc public protocol OpenDoorDelegate : ClayDelegate ``` -------------------------------- ### Handle Timeout Event Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html Callback triggered when the door opening process times out. ```Swift func didReceiveTimeout() ``` -------------------------------- ### Open Door Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Initiates a door opening operation using an encrypted mobile key and a delegate for feedback. ```Swift @objc public func openDoor(with key: String, delegate: OpenDoorDelegate) ``` -------------------------------- ### Handle OpenDoorDelegate Results Source: https://github.com/claysolutions/claysdk/blob/master/docs/index.html Implement the delegate method to process the ClayResult after an attempt to open a door. ```swift import SaltoJustINMobileSDK //... func didOpen(with result: ClayResult?) { guard let result = result else { return } if (result.getOpResult() == AUTH_SUCCESS_ACCESS_GRANTED) { // access granted } // or by using SSOperationGrup let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // success break case .groupFailure, .groupRejected, .groupUnknownResult: break default: break } } ``` -------------------------------- ### Activate Mobile Key Source: https://context7.com/claysolutions/claysdk/llms.txt Retrieve the device public key and send it to your backend to activate a mobile key. ```swift import ClaySDK class MobileKeyActivation { let clay: ClaySDK init(clay: ClaySDK) { self.clay = clay } func activateMobileKey(forUserId userId: String, lockId: String) { // Get the device's public key let publicKey = clay.getPublicKey() // Send public key to your backend server // Your server should call Clay Connect API to create a mobile key let requestBody: [String: Any] = [ "userId": userId, "lockId": lockId, "devicePublicKey": publicKey ] // Example API call to your backend var request = URLRequest(url: URL(string: "https://your-api.com/mobile-keys/activate")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try? JSONSerialization.data(withJSONObject: requestBody) URLSession.shared.dataTask(with: request) { data, response, error in if let data = data, let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], let encryptedKey = json["encryptedMobileKey"] as? String { // Store the encrypted key for later use with openDoor() UserDefaults.standard.set(encryptedKey, forKey: "mobileKey_\(lockId)") print("Mobile key activated successfully") } }.resume() } } ``` -------------------------------- ### reloadKeys() Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Attempts to reload keys from the keychain, useful after phone unlock if keychain access was previously denied. ```APIDOC ## reloadKeys() ### Description In case of `ClayError.storeLoadError` or `ClayError.storeError`, this method attempts to reload keys from the keychain. This is particularly useful when the phone was locked and keychain access was denied. Calling this method after the phone has been unlocked may successfully reload the keys. ### Method `reloadKeys()` ### Endpoint None (Instance method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **Bool** - `true` if keys were reloaded successfully, `false` otherwise. #### Response Example ``` true ``` ``` -------------------------------- ### ClaySDK Class Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html The main class responsible for handling security and Mobile Key operations. ```APIDOC ## ClaySDK Class ### Description The main class that handles security and Mobile Key openings. ### Declaration ```swift @objc public class ClaySDK : NSObject ``` ``` -------------------------------- ### ClayDelegate Protocol Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols.html The ClayDelegate protocol is used to handle feedback and error reporting during the initialization of the ClaySDK. ```APIDOC ## ClayDelegate ### Description ClayDelegate is the delegate to handle feedback from the ClaySDK initialisation. Implement this delegate to handle error handling. ### Declaration ```swift @objc public protocol ClayDelegate : AnyObject ``` ``` -------------------------------- ### List of Authentication Operation Results Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html Defines the possible outcomes of authentication operations, including success, rejection, and specific actions like door opening or office mode. ```c // Successful authentication but no information about the operation result. extern unsigned char const AUTH_SUCCESS_UNKNOWN_RESULT // Successful authentication and access granted (lock opened). extern unsigned char const AUTH_SUCCESS_ACCESS_GRANTED // Successful authentication and access rejected. extern unsigned char const AUTH_SUCCESS_ACCESS_REJECTED // Successful authentication and door opened with office mode set. extern unsigned char const AUTH_SUCCESS_DOOR_IN_OFFICE // Successful authentication and door closed with office mode removed. extern unsigned char const AUTH_SUCCESS_END_OFFICE // Successful authentication and opening roller. extern unsigned char const AUTH_SUCCESS_OPENING_ROLLER // Successful authentication and closing roller. extern unsigned char const AUTH_SUCCESS_CLOSING_ROLLER // Successful authentication and stop roller. extern unsigned char const AUTH_SUCCESS_STOP_ROLLER // Successful authentication and waiting for a second valid key for opening. extern unsigned char const AUTH_SUCCESS_WAIT_SECOND_CARD // Successful authentication, access rejected, PIN required. Introduce PIN before key. extern unsigned char const AUTH_SUCCESS_PIN_REQUIRED // Successful authentication, access rejected and key should be deleted. extern unsigned char const AUTH_SUCCESS_CANCELLED_KEY // Successful authentication, access rejected, fingerprint required. Input fingerprint before key. extern unsigned char const AUTH_SUCCESS_FINGER_REQUIRED // Successful authentication, key data was processed successfully. Doesn't imply any further outcome. extern unsigned char const AUTH_SUCCESS_KEY_PROCESSED ``` -------------------------------- ### Trigger Door Opening from UI Source: https://context7.com/claysolutions/claysdk/llms.txt Handles the user interaction for opening a door via a button tap. It retrieves the mobile key from UserDefaults and initiates the door opening process using the AccessControlManager. Ensures the button is re-enabled after the operation completes. ```swift // Usage in a view controller class DoorViewController: UIViewController { @IBAction func openDoorTapped(_ sender: UIButton) { guard let encryptedKey = UserDefaults.standard.string(forKey: "currentMobileKey") else { showAlert("No mobile key available") return } sender.isEnabled = false AccessControlManager.shared.openDoor(withKey: encryptedKey) { [weak self] success, message in DispatchQueue.main.async { sender.isEnabled = true self?.showAlert(message) } } } private func showAlert(_ message: String) { let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default)) present(alert, animated: true) } } ``` -------------------------------- ### Fetch App Public Key Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Retrieves the Base64 encoded public key used by the application. ```Swift @objc public func getPublicKey() -> String ``` -------------------------------- ### Handle ClaySDK Errors in Swift Source: https://context7.com/claysolutions/claysdk/llms.txt Implement the ClayDelegate protocol to receive and handle ClayError types. Use a switch statement to manage specific error cases, providing user-friendly feedback or logging for debugging. ```swift import ClaySDK class ErrorHandler: ClayDelegate { func didReceive(error: Error) { guard let clayError = error as? ClayError else { print("Unknown error: \(error.localizedDescription)") return } switch clayError { case .invalidApiKey: // The provided API public key is invalid showAlert(title: "Configuration Error", message: "Invalid API key. Please contact support.") case .invalidBase64: // Invalid BASE-64 encoded string showAlert(title: "Data Error", message: "Invalid key format received from server.") case .invalidMKey: // Decrypted Mobile Key is not valid showAlert(title: "Key Error", message: "Mobile key is invalid. Please request a new key.") case .invalidMKeyFormat: // Mobile Key has invalid format showAlert(title: "Key Error", message: "Mobile key format is invalid.") case .invalidMKeySignature: // Encrypted MKey signature verification failed showAlert(title: "Security Error", message: "Key signature verification failed.") case .invalidMKeyEncryption: // Encrypted key cannot be decrypted showAlert(title: "Decryption Error", message: "Failed to decrypt mobile key.") case .storeError: // Failed to store key in Keychain showAlert(title: "Storage Error", message: "Failed to save keys securely.") case .storeLoadError: // Failed to load key from Keychain (device may be locked) showAlert(title: "Access Error", message: "Cannot access secure storage. Unlock device and retry.") case .internalError: // Internal SDK error showAlert(title: "Internal Error", message: "An unexpected error occurred.") } // Log error description for debugging print("ClayError: \(clayError.errorDescription ?? "Unknown")") } private func showAlert(title: String, message: String) { // Present alert to user } } ``` -------------------------------- ### OpenDoorDelegate Protocol Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols.html The OpenDoorDelegate protocol is used to handle feedback and error reporting from the openDoor(with:delegate:) method. ```APIDOC ## OpenDoorDelegate ### Description OpenDoorDelegate is the delegate to handle feedback from the openDoor(with:delegate:) method. Implement this delegate to handle error handling and feedback. ### Declaration ```swift @objc public protocol OpenDoorDelegate : ClayDelegate ``` ``` -------------------------------- ### Handle Lock Found Event Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html Callback triggered when a lock is successfully found. ```Swift func didFindLock() ``` -------------------------------- ### Open Door with Encrypted Key Source: https://github.com/claysolutions/claysdk/blob/master/README.md Use the openDoor method to send an encrypted key to unlock a door. The provided delegate must conform to OpenDoorDelegate to handle the result. ```swift //'yourOpenDoorDelegate' must conform to OpenDoorDelegate clay.openDoor(with: "your-encrypted-key", delegate: yourOpenDoorDelegate) ``` -------------------------------- ### ClayResult MkeyFailed Case Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums/ClayResult.html Indicates that the mobile key delivery to the lock failed. ```Swift case mkeyFailed ``` -------------------------------- ### Reload cryptographic keys with reloadKeys() Source: https://context7.com/claysolutions/claysdk/llms.txt Use this method to recover from Keychain access errors, typically triggered when the device is locked. It is recommended to observe UIApplication.didBecomeActiveNotification to trigger the reload. ```swift import ClaySDK class KeychainRecoveryHandler: ClayDelegate { let clay: ClaySDK private var hasKeychainError = false init(clay: ClaySDK) { self.clay = clay } func didReceive(error: Error) { if let clayError = error as? ClayError { switch clayError { case .storeLoadError, .storeError: // Mark that we have a keychain access issue hasKeychainError = true print("Keychain access error - device may be locked") // Schedule a retry when app becomes active NotificationCenter.default.addObserver( self, selector: #selector(attemptKeyReload), name: UIApplication.didBecomeActiveNotification, object: nil ) default: break } } } @objc func attemptKeyReload() { guard hasKeychainError else { return } // Attempt to reload keys from Keychain let success = clay.reloadKeys() if success { hasKeychainError = false print("Keys reloaded successfully from Keychain") NotificationCenter.default.removeObserver( self, name: UIApplication.didBecomeActiveNotification, object: nil ) } else { print("Failed to reload keys - will retry on next app activation") } } } ``` -------------------------------- ### ClaySDK Class Declaration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html Declaration of the ClaySDK class, the primary interface for security and Mobile Key operations. ```swift @objc public class ClaySDK : NSObject ``` -------------------------------- ### Reload Keys Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClaySDK.html Attempts to reload keys from the keychain, useful when initial access failed due to device lock state. ```Swift @objc public func reloadKeys() -> Bool ``` -------------------------------- ### ClayResult MkeyDelivered Case Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums/ClayResult.html Indicates that the mobile key was successfully delivered to the lock. ```Swift case mkeyDelivered ``` -------------------------------- ### getOpResult() Method Declaration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClayResult.html Declaration of the getOpResult method in Swift, which returns the authentication operation result code. ```swift public override func getOpResult() -> Int ``` -------------------------------- ### ClayResult Unknown Case Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums/ClayResult.html Represents an unknown result state. ```Swift case unknown ``` -------------------------------- ### ClayResult Class Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html Represents the result of an authentication operation, such as opening a door. It provides methods to interpret the operation's outcome. ```APIDOC ## ClayResult Class ### Description `ClayResult` is the result returned by the `openDoor(with:delegate:)` method. It encapsulates the outcome of an authentication operation. ### Usage Example ```swift import SaltoJustINMobileSDK func didOpen(with result: ClayResult?) { guard let result = result else { return } if (result.getOpResult() == AUTH_SUCCESS_ACCESS_GRANTED) { // access granted } // or by using SSOperationGrup let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // success break case .groupFailure, .groupRejected, .groupUnknownResult: break default: break } } ``` ### Authentication Operation Results (SSOpResult) List of possible results from an authentication operation: - `AUTH_SUCCESS_UNKNOWN_RESULT`: Successful authentication but no information about the operation result. - `AUTH_SUCCESS_ACCESS_GRANTED`: Successful authentication and access granted (lock opened). - `AUTH_SUCCESS_ACCESS_REJECTED`: Successful authentication and access rejected. - `AUTH_SUCCESS_DOOR_IN_OFFICE`: Successful authentication and door opened with office mode set. - `AUTH_SUCCESS_END_OFFICE`: Successful authentication and door closed with office mode removed. - `AUTH_SUCCESS_OPENING_ROLLER`: Successful authentication and opening roller. - `AUTH_SUCCESS_CLOSING_ROLLER`: Successful authentication and closing roller. - `AUTH_SUCCESS_STOP_ROLLER`: Successful authentication and stop roller. - `AUTH_SUCCESS_WAIT_SECOND_CARD`: Successful authentication and waiting for a second valid key for opening. - `AUTH_SUCCESS_PIN_REQUIRED`: Successful authentication, access rejected, PIN required. Introduce PIN before key. - `AUTH_SUCCESS_CANCELLED_KEY`: Successful authentication, access rejected and key should be deleted. - `AUTH_SUCCESS_FINGER_REQUIRED`: Successful authentication, access rejected, fingerprint required. Input fingerprint before key. - `AUTH_SUCCESS_KEY_PROCESSED`: Successful authentication, key data was processed successfully. Doesn't imply any further outcome. ### Operation Result Groups (SSOpResultGroup) Possible groups for operation results: - `kGroupUnknownResult` - `kGroupFailure` - `kGroupAccepted` - `kGroupRejected` ### Declaration ```swift @objc public class ClayResult : SSResult ``` ``` -------------------------------- ### ClayResult Enumeration Declaration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums/ClayResult.html The base definition for the ClayResult enumeration. ```Swift @objc public enum ClayResult : Int ``` -------------------------------- ### Handle ClayResult Authentication Outcomes Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html Use this code to process the result of an openDoor operation. It checks for authentication success and grants access, or categorizes the outcome using SSOperationGroup. ```swift import SaltoJustINMobileSDK //... func didOpen(with result: ClayResult?) { guard let result = result else { return } if (result.getOpResult() == AUTH_SUCCESS_ACCESS_GRANTED) { // access granted } // or by using SSOperationGrup let group = SSOpResult.getGroup(result.getOpResult()) switch group { case .groupAccepted: // success break case .groupFailure, .groupRejected, .groupUnknownResult: break default: break } } ``` -------------------------------- ### SSOpResult Codes Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClayResult.html Defines the possible results for authentication operations, indicating success or failure with specific outcomes. ```APIDOC ## SSOpResult Codes List of authentication operation results. `SSOpResult` can be one of: - `AUTH_SUCCESS_UNKNOWN_RESULT`: Successful authentication but no information about the operation result. - `AUTH_SUCCESS_ACCESS_GRANTED`: Successful authentication and access granted (lock opened). - `AUTH_SUCCESS_ACCESS_REJECTED`: Successful authentication and access rejected. - `AUTH_SUCCESS_DOOR_IN_OFFICE`: Successful authentication and door opened with office mode set. - `AUTH_SUCCESS_END_OFFICE`: Successful authentication and door closed with office mode removed. - `AUTH_SUCCESS_OPENING_ROLLER`: Successful authentication and opening roller. - `AUTH_SUCCESS_CLOSING_ROLLER`: Successful authentication and closing roller. - `AUTH_SUCCESS_STOP_ROLLER`: Successful authentication and stop roller. - `AUTH_SUCCESS_WAIT_SECOND_CARD`: Successful authentication and waiting for a second valid key for opening. - `AUTH_SUCCESS_PIN_REQUIRED`: Successful authentication, access rejected, PIN required. Introduce PIN before key. - `AUTH_SUCCESS_CANCELLED_KEY`: Successful authentication, access rejected and key should be deleted. - `AUTH_SUCCESS_FINGER_REQUIRED`: Successful authentication, access rejected, fingerprint required. Input fingerprint before key. - `AUTH_SUCCESS_KEY_PROCESSED`: Successful authentication, key data was processed successfully. Doesn't imply any further outcome. ``` -------------------------------- ### Handle BLE Error Event Source: https://github.com/claysolutions/claysdk/blob/master/docs/Protocols/OpenDoorDelegate.html Callback triggered when a Bluetooth Low Energy error occurs. ```Swift func didReceiveBLE(error: Error) ``` -------------------------------- ### ClayResult Enumeration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums/ClayResult.html The ClayResult enumeration defines the possible outcomes when attempting to open a door using the openDoor method. It indicates whether the operation was successful, denied, or if an unknown state occurred. ```APIDOC ## ClayResult Enumeration ### Description The `ClayResult` enumeration represents the result returned by the `openDoor(with:delegate:)` method. It provides specific codes for different outcomes of the door opening operation. ### Enumeration Cases * **unknown** * Description: Unknown result. * Declaration: ```swift case unknown ``` * **mkeyDelivered** * Description: Access to the door is granted. The Mobile Key was delivered to the lock successfully. * Declaration: ```swift case mkeyDelivered ``` * **mkeyFailed** * Description: Access to the door is denied. The Mobile Key delivery to the lock failed. * Declaration: ```swift case mkeyFailed ``` ``` -------------------------------- ### ClayError Enumeration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums/ClayError.html The ClayError enumeration represents various error conditions that can occur within the ClaySDK. It conforms to the LocalizedError protocol, providing a localized description for each error. ```APIDOC ## ClayError Enumeration ### Description The `ClayError` enumeration is the primary error type returned by the `ClaySDK`. It categorizes different failure scenarios encountered during SDK operations. ### Declaration ```swift public enum ClayError : Error ``` ### Conformance `extension ClayError: LocalizedError` ### Error Cases * **invalidApiKey** * **Description**: Returned when the provided `API public key` is invalid. * **Declaration**: `case invalidApiKey` * **invalidBase64** * **Description**: Returned when an invalid BASE-64 encoded string was attempted to be decoded. * **Declaration**: `case invalidBase64` * **invalidMKey** * **Description**: Returned when the decrypted `Mobile Key` is not valid. * **Declaration**: `case invalidMKey` * **invalidMKeyFormat** * **Description**: Returned when an MKEY has an invalid format. * **Declaration**: `case invalidMKeyFormat` * **invalidMKeySignature** * **Description**: Returned when the verification of an encrypted MKey fails. * **Declaration**: `case invalidMKeySignature` * **invalidMKeyEncryption** * **Description**: Returned when an `encrypted key` cannot be decrypted OR when the decryption of the `encrypted key` fails. * **Declaration**: `case invalidMKeyEncryption` * **storeError** * **Description**: Returned when an `encrypted key` fails to be stored in the Keychain. * **Declaration**: `case storeError` * **storeLoadError** * **Description**: Returned when a stored `encrypted key` fails to be loaded from the Keychain. * **Declaration**: `case storeLoadError` * **internalError** * **Description**: Represents an internal error within the SDK. * **Declaration**: `case internalError` ### Properties * **errorDescription** (String?) - Detailed description for the received error. * **Declaration**: `public var errorDescription: String? { get }` ``` -------------------------------- ### SSOpResultGroup Enum Definition Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html Defines the possible groups for operation results, used for categorizing outcomes like failure, acceptance, or rejection. ```objectivec typedef NS_ENUM(NSInteger, SSOpResultGroup) { kGroupUnknownResult, kGroupFailure, kGroupAccepted, kGroupRejected }; ``` -------------------------------- ### SSOpResultGroup Enum Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes/ClayResult.html Groups SSOpResult codes into broader categories for easier handling. ```APIDOC ## SSOpResultGroup Enum `SSOpResultGroup` can be one of: - `kGroupUnknownResult` - `kGroupFailure` - `kGroupAccepted` - `kGroupRejected` ``` -------------------------------- ### ClayError Enumeration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums.html The ClayError enumeration defines the different types of errors that can be returned by the ClaySDK, along with their specific reasons. ```APIDOC ## ClayError Enumeration ### Description `ClayError` is the error type returned by ClaySDK. It encompasses a few different types of errors, each with their own associated reasons. ### Enumeration Cases - **invalidApiKey**: Returned when the provided `API public key` is invalid. - **invalidEncryption**: Returned when an `encrypted key` cannot be decrypted OR when the decryption of the `encrypted key` fails. - **invalidKey**: Returned when the decrypted `Mobile Key` is not valid. - **storeError**: Returned when an `encrypted key` fails to be stored in the Keychain. ### Declaration ```swift public enum ClayError : Error extension ClayError: LocalizedError ``` ### See Also - [Classes/ClaySDK.html](Classes/ClaySDK.html) - [Enums.html](Enums.html) ``` -------------------------------- ### ClayResult Class Declaration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Classes.html Declaration of the ClayResult class, which inherits from SSResult and is used to represent the outcome of security operations. ```swift @objc public class ClayResult : SSResult ``` -------------------------------- ### ClayError Enum Declaration Source: https://github.com/claysolutions/claysdk/blob/master/docs/Enums.html The ClayError enumeration is the primary error type returned by the ClaySDK. It is declared as a Swift Error type and conforms to LocalizedError for user-friendly error messages. ```swift public enum ClayError : Error ``` ```swift extension ClayError: LocalizedError ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.