菜鸟教程小白 发表于 2022-12-11 20:05:07

ios - 通过 KeyChain 保存和检索值


                                            <p><p>我正在尝试存储一个整数并使用 KeyChain 检索它。</p>

<p>我是这样保存的:</p>

<pre><code>func SaveNumberOfImagesTaken()
    {
      let key = &#34;IMAGE_TAKEN&#34;
      var taken = 10
      let data = NSKeyedArchiver.archivedDataWithRootObject(taken)
      let query : = [
            kSecClass as String : kSecClassGenericPassword,
            kSecAttrAccount as String : key,
            kSecValueData as String : data
      ]
      let status : OSStatus = SecItemAdd(query as CFDictionaryRef, nil)

    }
</code></pre>

<p>这是我尝试检索它的方式:</p>

<pre><code>func CheckIfKeyChainValueExitss() -&gt; AnyObject? {
    var key = &#34;IMAGE_TAKEN&#34;
    let query : = [
      kSecClass as String       : kSecClassGenericPassword,
      kSecAttrAccount as String : key,
      kSecReturnData as String: kCFBooleanTrue,
      kSecMatchLimit as String: kSecMatchLimitOne ]

    var dataTypeRef :Unmanaged&lt;AnyObject&gt;?

    let status: OSStatus = SecItemCopyMatching(query, &amp;dataTypeRef)

    if let op = dataTypeRef?.toOpaque() {
      let data = Unmanaged&lt;NSData&gt;.fromOpaque(op).takeUnretainedValue()
      if let string: AnyObject? =NSKeyedUnarchiver.unarchiveObjectWithData(data) as? AnyObject? {
            if key == &#34;IMAGE_TAKEN&#34;
            {
                return string as! String!

            }
            else if string == nil
            {
                return nil
            }
      }
    }
    return nil

}
</code></pre>

<p>我收到以下错误:</p>

<blockquote>
<p>Could not cast value of type &#39;__NSCFNumber&#39; to &#39;NSString&#39;</p>
</blockquote>

<p>我尝试使用变量但没有成功。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p><strong>我已经更新了 Eric 的 Swift 5 版本:</strong></p>

<pre><code>class KeyChain {

    class func save(key: String, data: Data) -&gt; OSStatus {
      let query = [
            kSecClass as String       : kSecClassGenericPassword as String,
            kSecAttrAccount as String : key,
            kSecValueData as String   : data ] as

      SecItemDelete(query as CFDictionary)

      return SecItemAdd(query as CFDictionary, nil)
    }

    class func load(key: String) -&gt; Data? {
      let query = [
            kSecClass as String       : kSecClassGenericPassword,
            kSecAttrAccount as String : key,
            kSecReturnData as String: kCFBooleanTrue!,
            kSecMatchLimit as String: kSecMatchLimitOne ] as

      var dataTypeRef: AnyObject? = nil

      let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &amp;dataTypeRef)

      if status == noErr {
            return dataTypeRef as! Data?
      } else {
            return nil
      }
    }

    class func createUniqueID() -&gt; String {
      let uuid: CFUUID = CFUUIDCreate(nil)
      let cfStr: CFString = CFUUIDCreateString(nil, uuid)

      let swiftString: String = cfStr as String
      return swiftString
    }
}

extension Data {

    init&lt;T&gt;(from value: T) {
      var value = value
      self.init(buffer: UnsafeBufferPointer(start: &amp;value, count: 1))
    }

    func to&lt;T&gt;(type: T.Type) -&gt; T {
      return self.withUnsafeBytes { $0.load(as: T.self) }
    }
}
</code></pre>

<hr/>

<p>我已经更新了 Eric 的 Swift 3 版本:</p>

<pre><code>class KeyChain {

    class func save(key: String, data: Data) -&gt; OSStatus {
      let query = [
            kSecClass as String       : kSecClassGenericPassword as String,
            kSecAttrAccount as String : key,
            kSecValueData as String   : data ] as

      SecItemDelete(query as CFDictionary)

      return SecItemAdd(query as CFDictionary, nil)
    }

    class func load(key: String) -&gt; Data? {
      let query = [
            kSecClass as String       : kSecClassGenericPassword,
            kSecAttrAccount as String : key,
            kSecReturnData as String: kCFBooleanTrue,
            kSecMatchLimit as String: kSecMatchLimitOne ] as

      var dataTypeRef: AnyObject? = nil

      let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &amp;dataTypeRef)

      if status == noErr {
            return dataTypeRef as! Data?
      } else {
            return nil
      }
    }

    class func createUniqueID() -&gt; String {
      let uuid: CFUUID = CFUUIDCreate(nil)
      let cfStr: CFString = CFUUIDCreateString(nil, uuid)

      let swiftString: String = cfStr as String
      return swiftString
    }
}

extension Data {

    init&lt;T&gt;(from value: T) {
      var value = value
      self.init(buffer: UnsafeBufferPointer(start: &amp;value, count: 1))
    }

    func to&lt;T&gt;(type: T.Type) -&gt; T {
      return self.withUnsafeBytes { $0.pointee }
    }
}
</code></pre>

<p>示例用法:</p>

<pre><code>let int: Int = 555
let data = Data(from: int)
let status = KeyChain.save(key: &#34;MyNumber&#34;, data: data)
print(&#34;status: &#34;, status)

if let receivedData = KeyChain.load(key: &#34;MyNumber&#34;) {
    let result = receivedData.to(type: Int.self)
    print(&#34;result: &#34;, result)
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 通过 KeyChain 保存和检索值,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/50038832/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/50038832/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 通过 KeyChain 保存和检索值