Как создать NSMutableDictionary в Swift?

#swift

#swift

Вопрос:

Я пытаюсь создать NSMutableDictionary для использования цепочки ключей в iOS, но я получаю следующую ошибку.

Не удалось найти перегрузку для ‘init’, которая принимает предоставленные аргументы

Это код, который я использую:

 var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, kCFBooleanTrue, kSecMatchLimitOne], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData, kSecMatchLimit])
 

Есть идеи, что может быть причиной этого?

полный код:

 import UIKit
import Security

let serviceIdentifier = "MySerivice"
let userAccount = "authenticatedUser"
let accessGroup = "MySerivice"

class KeychainService: NSObject {

    class func saveToken(token: NSString) {
        self.save(serviceIdentifier, data: token)
    }

    class func loadToken() -> NSString? {
        var token = self.load(serviceIdentifier)

        return token
    }

    class func save(service: NSString, data: NSString) {
        var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
        // Instantiate a new default keychain query
        var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, dataFromString], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData])

        // Delete any existing items
        SecItemDelete(keychainQuery as CFDictionaryRef)

        // Add the new keychain item
        var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
    }

    class func load(service: NSString) -> NSString? {
        // Instantiate a new default keychain query
        // Tell the query to return a result
        // Limit our results to one item
        var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, userAccount, kCFBooleanTrue, kSecMatchLimitOne], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData, kSecMatchLimit])

        var dataTypeRef :Unmanaged<AnyObject>?

        // Search for the keychain items
        let status: OSStatus = SecItemCopyMatching(keychainQuery, amp;dataTypeRef)

        let opaque = dataTypeRef?.toOpaque()

        var contentsOfKeychain: NSString?

        if let op = opaque? {
            let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue()

            // Convert the data retrieved from the keychain into a string
            contentsOfKeychain = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)
        } else {
            println("Nothing was retrieved from the keychain. Status code (status)")
        }

        return contentsOfKeychain
    }
}
 

Комментарии:

1. Проблема связана с переменными, которые вы передаете в словарь. Можете ли вы показать их объявления?

2. Поскольку это NSDictionary метод инициализации, вы можете попробовать NSDictionary(objects:...,keys:...).mutableCopy() ?

3. Я вижу, тогда проблема должна заключаться в параметрах. Создаваемый вами массив имеет тип Any[] , но он принимается AnyObject[] в качестве аргумента. Я бы попробовал обернуть их в NSValue s. Я протестирую его на игровой площадке и подготовлю ответ позже

4. Я вставил ваш код в OS X playground, и он работает…

5. привет, я использую бета-версию 2, и она не работает.

Ответ №1:

Для вашего кода вы можете использовать NSDictionary таким образом:

     var keychainObjects = NSArray(objects:"(kSecClassGenericPassword)", service, userAccount, dataFromString)
    var keychainValues = NSArray(objects:"(kSecClass)","(kSecAttrService)", "(kSecAttrAccount)","(kSecValueData)")
    let keychainQuery = NSDictionary(objects: keychainObjects, forKeys: keychainValues)