Я пытаюсь добавить элемент в keychain iOS с помощью Swift, но не могу понять, как правильно набирать литеры. Из сессии 709 WWDC 2013, учитывая следующий код Objective-C:
NSData *secret = [@"top secret" dataWithEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
(id)kSecClass: (id)kSecClassGenericPassword,
(id)kSecAttrService: @"myservice",
(id)kSecAttrAccount: @"account name here",
(id)kSecValueData: secret,
};
OSStatus = SecItemAdd((CFDictionaryRef)query, NULL);
Попытка сделать это в Swift следующим образом:
var secret: NSData = "Top Secret".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: "MyService",
kSecAttrAccount: "Some account",
kSecValueData: secret
]
дает ошибку "Невозможно преобразовать тип выражения" Словарь "в" СловарьLiteralConvertible ".
Другим подходом, который я взял, было использование Swift и метода - setObject:forKey:
в словаре для добавления kSecClassGenericPassword с ключом kSecClass.
В Objective-C:
NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionary];
[searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
В коде Objective-C CFTypeRef различных ключей класса элемента keychain соединяется с использованием id. В Swift documentation он упомянул, что Swift импортирует id как AnyObject. Однако, когда я попытался понизить kSecClass как AnyObject для метода, я получаю сообщение об ошибке "Тип" AnyObject "не соответствует NSCopying.
Любая помощь, будь то прямой ответ или какое-либо руководство о том, как взаимодействовать с типами Core Foundation, будет оценено.
РЕДАКТИРОВАТЬ 2
Это решение больше недействительно с Xcode 6 Beta 2. Если вы используете бета-версию 1, приведенный ниже код может работать.
var secret: NSData = "Top Secret".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let query = NSDictionary(objects: [kSecClassGenericPassword, "MyService", "Some account", secret], forKeys: [kSecClass,kSecAttrService, kSecAttrAccount, kSecValueData])
OSStatus status = SecItemAdd(query as CFDictionaryRef, NULL)
Чтобы использовать ключи атрибута Keychain Item в качестве ключей словаря, вам необходимо развернуть их, используя либо takeRetainedValue, либо takeUnretainedValue (при необходимости). Затем вы можете отправить их в NSCopying. Это потому, что они являются CFTypeRefs в заголовке, которые не все могут быть скопированы.
Как и в случае с Xcode 6 Beta 2, это приводит к сбою Xcode.