I have a test Appcelerator iOS-only App (to simplify things). You can get the whole (really small app) in this repo
This app stores a value in the Keychain from Appcelerator side, without problems, usingTi.Identity
module . The problem is that I can't read that value from Swift.
Code to save something in the keychain, inside 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');
This works, as after saving I print waht's inside the keychain with that key, and prints correctly s3cr3t_p4$$w0rd
.
Now to read that from a Share Extension, I've added the extension to the project. Relevant parts oftiapp.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>
App is is <id>com.testapp</id>
The entitlement file in the app extension is:
<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>
To read it from Swift I've tried to:
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"
}
Also I've used this Keychain Wrapper from Ti.Identity. Without success. I always get -25300, /* The specified item could not be found in the keychain. */
-25300, /* The specified item could not be found in the keychain. */
What's wrong in the Swift side of things?
This might not be a complete answer as your question is quite long, but there's an example app that claims to do this .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.