Appcelerator iOS应用程序:如何从Share Extension读取Keychain值?

时间:2018-05-02 14:31:45

标签: ios swift keychain appcelerator-titanium appcelerator-mobile

我有一个测试Appcelerator iOS专用的应用程序(为了简化事情)。您可以在此repo

中获取整个(非常小的应用)

此应用程序使用Ti.Identity module在Appcelerator端的Keychain中存储一个值,没有任何问题。 问题在于我无法从Swift中读取该值。

alloy.js内的钥匙串中保存内容的代码:

var Identity = require('ti.identity');

// Create a keychain item
var keychainItem = Identity.createKeychainItem({
identifier: 'mypassword',
accessGroup: 'group.test.projects'
});


keychainItem.addEventListener('save', function(e) {
    Ti.API.info("Saved!!! ");

    keychainItem.addEventListener('read', function(e) {
            Ti.API.info("Read!!!");
            if (e.success) {
                Ti.API.info(JSON.stringify(e, null, 4));
            } else {
                Ti.API.info("Error" + e);
            }
    });

    keychainItem.read();
});

// Write to the keychain
keychainItem.save('s3cr3t_p4$$w0rd');

这样做有用,因为保存后我用钥匙在钥匙串内打印,并正确打印s3cr3t_p4$$w0rd

现在从Share扩展中读取,我已将扩展添加到项目中。 tiapp.xml的相关部分:

<ios>
...
<entitlements>
  <dict>
    <key>com.apple.security.application-groups</key>
    <array>
      <string>group.test.projects</string>
    </array>
    <key>keychain-access-groups</key>
    <array>
      <string>$(AppIdentifierPrefix)keychain.test.projects</string>
    </array>
  </dict>
</entitlements>
<extensions>
  <extension projectPath="extensions/TestKeychain.xcodeproj">
    <target name="ShareExtension">
      <provisioning-profiles>
        <devices/>
      </provisioning-profiles>
    </target>
  </extension>
</extensions>

应用是<id>com.testapp</id>

应用扩展程序中的权利文件是:

<dict>
    <key>com.apple.security.application-groups</key>
    <array>
        <string>group.test.projects</string>
    </array>
    <key>keychain-access-groups</key>
    <array>
        <string>$(AppIdentifierPrefix)keychain.test.projects</string>
    </array>
</dict>

要从Swift中读取它,我试图:

let domain = "group.test.projects"
let login = "mypassword"
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)

self.textView.text = "Reading something"

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
    }
} else {
    self.textView.text = "Error"
}

此外,我还使用了Ti.Identity中的Keychain Wrapper。没有成功。我总是得到-25300, /* The specified item could not be found in the keychain. */

Swift方面的错误是什么?

1 个答案:

答案 0 :(得分:0)

这可能不是一个完整的答案,因为你的问题很长,但有一个声称这样做的示例应用程序。 See here

Here's his example

如果不完全符合您的要求,请不要进行投票,可提供相关演示。没试过,但你通过这个链接与Slack联系 - 只是试图提供更多信息。