在iOS扩展程序及其包含的应用程序之间通过钥匙串共享吗? [英] Share between an iOS extension and its containing app with the keychain?

查看:127
本文介绍了在iOS扩展程序及其包含的应用程序之间通过钥匙串共享吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解我可以通过启用应用程序组并使用NSUserDefaults在共享扩展名及其包含的应用程序之间共享数据(请参阅

I understand I can share data between my share extension and its containing app by enabling app groups and using NSUserDefaults (see Sharing data between an iOS 8 share extension and main app).

但是,我存储的数据很敏感,所以我希望使用钥匙串.因此,用户将在包含的应用程序中输入帐户信息,然后共享扩展程序将读取该数据以执行预期的共享操作.

However, the data I am storing is sensitive, so I hoped to use the keychain. So the user would enter account information in the containing app, and then the share extension would read that data to perform the intended sharing action.

有人知道这是否可能吗?我的第一个建议是扩展程序和包含应用程序具有单独的钥匙串(尝试在扩展程序中为该键返回数据时,使用包含键的数据保存在包含应用程序中将返回null).

Does anyone know if this is possible? My first crack at it suggests that the extension and the containing app have separate keychains (saving the data with a key in the containing app returns null when attempting to return data for that key in the extension).

谢谢!

P.S.使用Lockbox进行钥匙串访问,但是如果它过于抽象而无法使它起作用,我可以放弃它. https://github.com/granoff/Lockbox

P.S. Using Lockbox for Keychain access, but I could ditch it if it's too much of an abstraction to make it work. https://github.com/granoff/Lockbox

推荐答案

使钥匙串在Xcode 8中共享.

To make the Keychain shared in Xcode 8.

1)在功能"的应用"目标中,找到并打开钥匙串共享",添加钥匙串组"钥匙(诸如com.myappdomain.myappname之类的反向域样式字符串)

1) In your App target in Capabilities find and turn on "Keychain Sharing", add a Keychain Group key (a reverse-domain style string like com.myappdomain.myappname)

2)对扩展目标执行完全相同的操作.确保应用程序和扩展名的钥匙串组密钥都相同.

2) Do exactly the same for the extension target. Make sure the Keychain Group key is the same for both - the app and the extension.

以通常的方式从钥匙串添加和检索数据,无需在代码中进行任何特殊更改.例如,以下是我如何在主应用程序中将数据放入钥匙串"的方法(有点老式,但在Swift 3中仍然可以使用):

Add and retrieve data from Keychain in your usual way, no special changes required in the code. For example, here's how I put data into Keychain in the main app (a little old-fashioned but still works in 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)

然后在扩展名中检索它:

And then retrieve it in the extension:

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完成.有关如何操作的信息,请参见此答案.

Note that you will still need to pass "login" and "domain" over to the extension in order to identify the correct record. This can be done via NSUserDefaults. See this answer on how to do this.

这篇关于在iOS扩展程序及其包含的应用程序之间通过钥匙串共享吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆