ios - Swift 钥匙串(keychain)和配置文件

标签 ios xcode swift keychain testflight

我们在 swift 中创建了一个使用钥匙串(keychain)的应用程序。该应用程序在设备或模拟器中运行时运行良好,但在通过 Testflight 提供时无法访问钥匙串(keychain),除非提供给以前从未通过 Xcode 6.1 安装该应用程序的新设备。

以下是钥匙串(keychain)代码的摘录:

    import UIKit
    import Security

    let serviceIdentifier = "com.ourdomain"

    let kSecClassValue = kSecClass as NSString
    let kSecAttrAccountValue = kSecAttrAccount as NSString
    let kSecValueDataValue = kSecValueData as NSString
    let kSecClassGenericPasswordValue = kSecClassGenericPassword as NSString
    let kSecAttrServiceValue = kSecAttrService as NSString
    let kSecMatchLimitValue = kSecMatchLimit as NSString
    let kSecReturnDataValue = kSecReturnData as NSString
    let kSecMatchLimitOneValue = kSecMatchLimitOne as NSString

class KeychainManager {

    class func setString(value: NSString, forKey: String) {
        self.save(serviceIdentifier, key: forKey, data: value)
    }

    class func stringForKey(key: String) -> NSString? {
        var token = self.load(serviceIdentifier, key: key)

        return token
    }

    class func removeItemForKey(key: String) {
        self.save(serviceIdentifier, key: key, data: "")
    }



    class func save(service: NSString, key: String, data: NSString) {
        var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
        // Instantiate a new default keychain query
        var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, key, dataFromString], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecValueDataValue])

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

        if data == "" { return }

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

    class func load(service: NSString, key: String) -> 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: [kSecClassGenericPasswordValue, service, key, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue])

        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 {
            return nil
        }

        return contentsOfKeychain
    }  
  }

通过 Xcode 6.1 在设备上安装应用程序后,我注意到“serviceIdentifier”-“com.ourdomain”不正确并且与供应所需的应用程序包标识符。

然后我更改了“serviceIdentifier”值以匹配包标识符 - “com.ourdomain.appname”但是当通过 Testflight 提供。我很肯定这是因为设备已经安装了带有不正确标识符的捆绑 ID 的钥匙串(keychain),但我无法理解如何解决这个问题,以便在删除应用程序时删除钥匙串(keychain)或获取要使用的配置文件现有的钥匙串(keychain)(标识符不正确)

如有任何帮助,我们将不胜感激。提前致谢

最佳答案

使用 withUnsafeMutablePointer 函数和 UnsafeMutablePointer 结构来检索数据,如下所示:

var result: AnyObject?
var status = withUnsafeMutablePointer(&result) { SecItemCopyMatching(keychainQuery, UnsafeMutablePointer($0)) }

if status == errSecSuccess {
    if let data = result as NSData? {
        if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
            // ...
        }
    }
}

它适用于发布(最快优化)构建。

关于ios - Swift 钥匙串(keychain)和配置文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26355630/

相关文章:

ios - 带有 CAShapelayer 的圆弧圆环图 - 底层的边界可见

iphone - 无法在 iPhone 上加载/安装应用程序

ios - 具有多个自定义单元格滚动和重用问题的 uitableview

ios - 在 IOS WebView 中打开时处理来自 TXT 文件的数据

ios - 意外的 EXC_BAD_INSTRUCTION

ios - 在 ARC 上创建 IBOutlets 作为 ivars。内存问题?

android - 如何在 React Navigation 中创建屏幕下推

ios - 从根节点映射嵌套对象不起作用

iPhone 开发测试版?

ios - 从 "UITableViewCell"转换为不相关类型 "UIView"总是失败 iOS9