菜鸟教程小白 发表于 2022-12-13 03:39:53

ios - 钥匙串(keychain) iOS touchId 提示两次


                                            <p><p>如果它不存在,我想将一个项目添加到钥匙串(keychain),如果它存在,我想更新它。
我通过以下查询调用 SecItemCopyMatching 来检查项目是否存在:</p>

<pre><code>NSDictionary *query = @{
                            (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrService: @&#34;myservice&#34;,
                            (__bridge id)kSecReturnData: @NO
                            };   
</code></pre>

<p>SecItemCopyMatching 提示用户输入 touchid/密码。
之后我需要更新再次提示用户的钥匙串(keychain)。
我可以在我的程序中存储一个 BOOL 来保存状态,但这可能与钥匙串(keychain)中的值不同步,所以我宁愿查询钥匙串(keychain)本身是否存在该项目,但我不希望用户得到双重提示.有什么办法吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这里的解决方法是先调用更新。除非该项目存在,否则它不会提示您。如果更新调用返回 errSecItemNotFound,则添加数据。这应该最多只提示您一次。如果您添加一个项目,它根本不应该提示您。 </p>

<pre><code>class func updateData(value: NSData, forKey keyName: String) -&gt; Bool {
    let keychainQueryDictionary: NSMutableDictionary = self.setupKeychainQueryDictionaryForKey(keyName)
    let updateDictionary =

    let status: OSStatus = SecItemUpdate(keychainQueryDictionary, updateDictionary)

    if status == errSecSuccess {
      return true
    } else if status == errSecItemNotFound {
      return setData(value, forKey: keyName)
    } else {
      return false
    }
}

class func setData(value: NSData, forKey keyName: String) -&gt; Bool {
    var keychainQueryDictionary: NSMutableDictionary = self.setupKeychainQueryDictionaryForKey(keyName)

    keychainQueryDictionary = value

    var error:Unmanaged&lt;CFErrorRef&gt;?
    let sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleAfterFirstUnlock, SecAccessControlCreateFlags.UserPresence, &amp;error)
    keychainQueryDictionary = sacObject.takeRetainedValue()

    let status: OSStatus = SecItemAdd(keychainQueryDictionary, nil)

    if status == errSecSuccess {
      return true
    } else {
      return false
    }
}

private class func setupKeychainQueryDictionaryForKey(keyName: String) -&gt; NSMutableDictionary {
    var attributes = NSMutableDictionary()
    attributes = kSecClassGenericPassword as String
    attributes = &#34;Sample Service 1&#34;
    attributes = &#34;Operation prompt goes here&#34;
    attributes = keyName

    return attributes
}
</code></pre>

<p>此代码修改自 Jason Rendel 的 <a href="https://github.com/jrendel/SwiftKeychainWrapper" rel="noreferrer noopener nofollow">KeychainWrapper</a> .</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 钥匙串(keychain) iOS touchId 提示两次,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/27113256/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/27113256/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 钥匙串(keychain) iOS touchId 提示两次