Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a NSMutableDictionary in Swift?

Tags:

swift

I'm trying to create an NSMutableDictionary to use the key chain in iOS, but I'm getting the following error.

Could not find an overload for 'init' that accepts the supplied arguments

This is the code I'm using:

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

Any idea what could be causing this?

the complete code:

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, &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
    }
}
like image 425
Farhad-Taran Avatar asked Jun 27 '14 14:06

Farhad-Taran


1 Answers

For your code you can use a NSDictionary that way:

    var keychainObjects = NSArray(objects:"\(kSecClassGenericPassword)", service, userAccount, dataFromString)
    var keychainValues = NSArray(objects:"\(kSecClass)","\(kSecAttrService)", "\(kSecAttrAccount)","\(kSecValueData)")
    let keychainQuery = NSDictionary(objects: keychainObjects, forKeys: keychainValues)
like image 138
Phillipe Gustavo Avatar answered Sep 24 '22 23:09

Phillipe Gustavo