代码之家  ›  专栏  ›  技术社区  ›  nishith Singh

在iOS应用程序和WatchOS 7应用程序之间共享帐户详细信息

  •  0
  • nishith Singh  · 技术社区  · 5 年前

    我正在寻找一种方法来共享帐户凭据,如 userID accessToken 在iOS应用程序和WatchOS应用程序之间。据我所知,我可以使用 WatchConnectivity 但这似乎并不可靠。例如,如果我的iOS应用程序被杀死,我就找不到方法来强制唤醒应用程序以获取数据。

    我试过的另一个想法是钥匙链共享,它似乎也不起作用,而且给了我很多好处

    密钥库.retrieveSecItemCopyMatching错误-25300

    错误

    下面是我正在使用的代码,我从 this 辅导的。

    class KeyStore {
    
        let account = "accessToken"
        let group = "[TeamID].[BundleID]" //Setup same as in keychain sharing options in capabilities
    
        func store(token : String) {
            let data = token.data(using: .utf8)!
            let addquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword as String,
                                           kSecAttrAccount as String: account,
                                           kSecValueData as String: data,
                                           kSecAttrSynchronizable as String : kCFBooleanTrue!,
                                           kSecAttrAccessGroup as String : group
            ]
            SecItemDelete(addquery as CFDictionary)
            let status : OSStatus = SecItemAdd(addquery as CFDictionary, nil)
            guard status == errSecSuccess else {
                os_log("store: whoops")
                return
            }
        }
    
        func clear() {
            let addquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword as String,
                                           kSecAttrAccount as String: account,
                                           kSecAttrSynchronizable as String : kCFBooleanTrue!,
                                           kSecAttrAccessGroup as String : group
            ]
            SecItemDelete(addquery as CFDictionary)
        }
    
        func retrieve() -> String? {
            let getquery: [String: Any] = [kSecClass as String: kSecClassGenericPassword,
                                           kSecAttrAccount as String: account,
                                           kSecReturnData as String: kCFBooleanTrue!,
                                           kSecMatchLimit as String : kSecMatchLimitOne,
                                           kSecAttrSynchronizable as String : kCFBooleanTrue!,
                                           kSecAttrAccessGroup as String : group
            ]
    
            var item: CFTypeRef?
            let status = SecItemCopyMatching(getquery as CFDictionary, &item)
            guard status == errSecSuccess else {
                os_log("keyStore.retrieve SecItemCopyMatching error \(status)")
                return nil
            }
    
            guard let data = item as? Data? else {
                os_log("keyStore.retrieve not data")
                return nil
            }
    
            return String(data: data!, encoding: String.Encoding.utf8)
        }
    
        func getAllKeychainItems() throws {
    
            let classes = [kSecClassGenericPassword as String,  // Generic password items
                           kSecClassInternetPassword as String, // Internet password items
                           kSecClassCertificate as String,      // Certificate items
                           kSecClassKey as String,              // Cryptographic key items
                           kSecClassIdentity as String,
                           kSecAttrAccount as String]         // Identity items
    
    
            classes.forEach { secClass in
              let items = getAllKeyChainItemsOfClass( secClass )
              NSLog(items.description)
            }
          }
    
    
          func getAllKeyChainItemsOfClass(_ secClass: String) -> [String: AnyObject] {
    
            let query: [String: Any] = [
              kSecClass as String : secClass,
              kSecReturnData as String  : true,
              kSecReturnAttributes as String : true,
              kSecReturnRef as String : true,
              kSecMatchLimit as String: kSecMatchLimitAll
            ]
    
            var result: AnyObject?
    
            let lastResultCode = withUnsafeMutablePointer(to: &result) {
              SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
            }
    
            var values = [String: AnyObject]()
            if lastResultCode == noErr {
              let array = result as? Array<Dictionary<String, Any>>
    
              for item in array! {
                if let key = item[kSecAttrAccount as String] as? String,
                  let value = item[kSecValueData as String] as? Data {
                  values[key] = String(data: value, encoding:.utf8) as AnyObject?
                }
                else if let key = item[kSecAttrLabel as String] as? String,
                  let value = item[kSecValueRef as String] {
                  values[key] = value as AnyObject
                }
              }
            }
            return values
          }
    
    }
    

    任何可以帮助我共享登录凭据的引用,即使在应用程序被终止时,也会非常有用

    0 回复  |  直到 5 年前