- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我知道我可以通过启用应用程序组和使用 NSUserDefaults(参见 Sharing data between an iOS 8 share extension and main app)在我的共享扩展和包含它的应用程序之间共享数据。
但是我存储的数据比较敏感,所以希望使用keychain。因此,用户将在包含的应用程序中输入帐户信息,然后共享扩展程序将读取该数据以执行预期的共享操作。
有人知道这是否可行吗?我的第一个破解表明扩展程序和包含的应用程序具有单独的钥匙串(keychain)(在尝试为扩展程序中的该 key 返回数据时,使用包含的应用程序中的 key 保存数据时返回 null)。
谢谢!
附言使用 Lockbox 进行钥匙串(keychain)访问,但如果它过于抽象而无法正常工作,我可以放弃它。 https://github.com/granoff/Lockbox
最佳答案
使钥匙串(keychain)在 Xcode 8 中共享。
1) 在您的 App target 的 Capabilities 中找到并打开“Keychain Sharing”,添加一个 Keychain Group key (一个反向域样式的字符串,如 com.myappdomain.myappname)
2) 对扩展目标执行完全相同的操作。确保应用程序和扩展程序的钥匙串(keychain)组 key 相同。
以您通常的方式从 Keychain 添加和检索数据,无需对代码进行特殊更改。例如,这是我将数据放入主应用程序中的钥匙串(keychain)的方式(有点过时但在 Swift 3 中仍然有效):
let login = loginString
let domain = domainString
let passwordData: Data = passwordString.data(using: String.Encoding.utf8, allowLossyConversion: false)!
let keychainQuery: [NSString: NSObject] = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: login as NSObject, // login and domain strings help identify
kSecAttrService: domain as NSObject, // the required record in the Keychain
kSecValueData: passwordData as NSObject]
SecItemDelete(keychainQuery as CFDictionary) //Deletes the item just in case it already exists
let keychainSaveStatus: OSStatus = SecItemAdd(keychainQuery as CFDictionary, nil)
然后在扩展中检索它:
let keychainQuery: [NSString: NSObject] = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccount: login as NSObject,
kSecAttrService: domain as NSObject,
kSecReturnData: kCFBooleanTrue,
kSecMatchLimit: kSecMatchLimitOne]
var rawResult: AnyObject?
let keychain_get_status: OSStatus = SecItemCopyMatching(keychainQuery as CFDictionary, &rawResult)
if (keychain_get_status == errSecSuccess) {
if let retrievedData = rawResult as? Data,
let password = String(data: retrievedData, encoding: String.Encoding.utf8) {
// "password" contains the password string now
}
}
请注意,您仍然需要将“登录名”和“域”传递给扩展程序,以便识别正确的记录。这可以通过 NSUserDefaults 来完成。参见 this answer关于如何做到这一点。
关于ios - 使用钥匙串(keychain)在 iOS 扩展及其包含的应用程序之间共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26693913/
我是一名优秀的程序员,十分优秀!