// // DeviceOperations.swift // AWSMobileClient // import Foundation import AWSCognitoIdentityProvider /// DeviceOperations is responsible for handling mobile device related operations for logged in user. public class DeviceOperations { weak var mobileClient: AWSMobileClient? internal static let sharedInstance: DeviceOperations = DeviceOperations() /// List all devices for current user. /// /// - Parameters: /// - limit: The number of devices to list in current call. Defaults to 60(max possible value) /// - paginationToken: The pagination token returned in previous list call to get more devices. /// - completionHandler: completion handler for result or error. public func list(limit: Int = 60, paginationToken: String? = nil, completionHandler: @escaping ((ListDevicesResult?, Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(nil, error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { let message = AWSMobileClientConstants.notSignedInMessage let error = AWSMobileClientError.notSignedIn(message: message) completionHandler(nil, error) return } currentActiveUser.listDevices(Int32(limit), paginationToken: paginationToken).continueWith { (task) -> Any? in if let error = task.error { completionHandler(nil, AWSMobileClientError.makeMobileClientError(from: error)) } else if let result = task.result { var devices: [Device] = [] if result.devices != nil { for device in result.devices! { devices.append(self.getMCDeviceForCognitoDevice(device: device)) } } let listResult = ListDevicesResult(devices: devices, paginationToken: result.paginationToken) completionHandler(listResult, nil) } return nil } } } /// Update status for specified device id. /// /// - Parameters: /// - deviceId: the device id which needs to be updated. /// - remembered: true if device has to be remembered. false to set it to not remembered. /// - completionHandler: completion handler for result or error. public func updateStatus(deviceId: String, remembered: Bool, completionHandler: @escaping ((UpdateDeviceStatusResult?, Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(nil, error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { let message = AWSMobileClientConstants.notSignedInMessage let error = AWSMobileClientError.notSignedIn(message: message) completionHandler(nil, error) return } currentActiveUser.updateDeviceStatus(deviceId, remembered: remembered).continueWith { (task) -> Any? in if let error = task.error { completionHandler(nil, AWSMobileClientError.makeMobileClientError(from: error)) } else if let _ = task.result { completionHandler(UpdateDeviceStatusResult(), nil) } return nil } } } /// Update status for current device. /// /// - Parameters: /// - remembered: true if device has to be remembered. false to set it to not remembered. /// - completionHandler: completion handler for result or error. public func updateStatus(remembered: Bool, completionHandler: @escaping ((UpdateDeviceStatusResult?, Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(nil, error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { let message = AWSMobileClientConstants.notSignedInMessage let error = AWSMobileClientError.notSignedIn(message: message) completionHandler(nil, error) return } currentActiveUser.updateDeviceStatus(remembered).continueWith { (task) -> Any? in if let error = task.error { completionHandler(nil, AWSMobileClientError.makeMobileClientError(from: error)) } else if let _ = task.result { completionHandler(UpdateDeviceStatusResult(), nil) } return nil } } } /// Get details for specified device id. /// /// - Parameters: /// - deviceId: deviceId for device whose details need to be fetched. /// - completionHandler: completion handler for result or error. public func get(deviceId: String, completionHandler: @escaping ((Device?, Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(nil, error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { let message = AWSMobileClientConstants.notSignedInMessage let error = AWSMobileClientError.notSignedIn(message: message) completionHandler(nil, error) return } currentActiveUser.getDevice(deviceId).continueWith { (task) -> Any? in if let error = task.error { completionHandler(nil, AWSMobileClientError.makeMobileClientError(from: error)) } else if let result = task.result { completionHandler(self.getMCDeviceForCognitoDevice(device: result.device), nil) } return nil } } } /// Get details of current device. /// /// - Parameter completionHandler: completion handler for result or error. public func get(_ completionHandler: @escaping ((Device?, Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(nil, error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { let message = AWSMobileClientConstants.notSignedInMessage let error = AWSMobileClientError.notSignedIn(message: message) completionHandler(nil, error) return } currentActiveUser.getDevice().continueWith { (task) -> Any? in if let error = task.error { completionHandler(nil, AWSMobileClientError.makeMobileClientError(from: error)) } else if let result = task.result { completionHandler(self.getMCDeviceForCognitoDevice(device: result.device), nil) } return nil } } } /// Forget specified device. /// /// - Parameters: /// - deviceId: The deviceId of device which needs to be stopped being tracked. /// - completionHandler: completion handler for result or error. public func forget(deviceId: String, completionHandler: @escaping ((Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { let message = AWSMobileClientConstants.notSignedInMessage let error = AWSMobileClientError.notSignedIn(message: message) completionHandler(error) return } currentActiveUser.forgetDevice(deviceId).continueWith { (task) -> Any? in if let error = task.error { completionHandler(AWSMobileClientError.makeMobileClientError(from: error)) } else if let _ = task.result { completionHandler(nil) } return nil } } } /// Forget current device. The device will no longer be tracked. Note: Calling `updateStatus` to remember the device after calling forget device will result in error. To remember a forgotten device, the user needs to re-login. /// /// - Parameter completionHandler: completion handler for result or error. public func forget(_ completionHandler: @escaping ((Error?) -> Void)) { mobileClient?.getTokens{ _, error in if let error = error { completionHandler(error) return } guard let currentActiveUser = self.mobileClient?.userpoolOpsHelper?.currentActiveUser else { completionHandler(AWSMobileClient.missingCurrentActiveUser()) return } currentActiveUser.forgetDevice().continueWith { (task) -> Any? in if let error = task.error { completionHandler(AWSMobileClientError.makeMobileClientError(from: error)) } else if let _ = task.result { completionHandler(nil) } return nil } } } internal func getMCDeviceForCognitoDevice(device: AWSCognitoIdentityProviderDeviceType?) -> Device { let createDate = device?.deviceCreateDate let lastAuthDate = device?.deviceLastAuthenticatedDate let lastModifiedDate = device?.deviceLastModifiedDate let deviceKey = device?.deviceKey var attributes: [String: String] = [:] if device?.deviceAttributes != nil { for attr in device!.deviceAttributes! { if attr.name != nil && attr.value != nil { attributes[attr.name!] = attr.value! } } } return Device(attributes: attributes, createDate: createDate, deviceKey: deviceKey, lastAuthenticatedDate: lastAuthDate, lastModifiedDate: lastModifiedDate) } }