Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
343 views
in Technique[技术] by (71.8m points)

swift - Sharing account details across iOS app and WatchOS 7 app

I am looking for a way to share account credentials like userID and accessToken between my iOS app and my WatchOS app. As i understand i can use the WatchConnectivity framework but that does not seem reliable. For example if my iOS app is killed i could not find a way to force wake the app to fetch the data.

The other think that i tried was keychain sharing which also does not seem to work and gives

keyStore.retrieve SecItemCopyMatching error -25300

error

Below is the code that i am using, which i got from this tutorial.

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
      }

}

Any references that could help me share login credentials even when the app is killed would really help

question from:https://stackoverflow.com/questions/65901297/sharing-account-details-across-ios-app-and-watchos-7-app

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...