SecItemCopyMatching继续返回errSecItemNotFound

时间:2015-11-17 19:39:44

标签: ios objective-c keychain

我尝试使用Keychain Services来保存一个值,即使用户重新安装该应用程序也会保留该值。因此,我使用SecItemCopyMatching检查项目是否存在,第一次返回errSecItemNotFound并使用SecItemAdd添加新项目,该项目返回errSecSuccess,但_attrs的值为{{} 1}}是nil。此外,当第二次调用代码时,SecItemCopyMatching仍会返回errSecItemNotFound,就好像SecItemAdd未被调用一样。那可能与什么有关?

    CFMutableDictionaryRef _attrs = nil;
    NSString* key = @"<unique key>";
    NSMutableDictionary* query = [NSMutableDictionary dictionary];
    query[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
    query[(__bridge id)kSecAttrLabel] = key;
    query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
    query[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue;

    OSStatus err = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&_attrs);

    if (err == errSecSuccess) {
        return YES;
    }
    NSString* str = @"<some data>";
    if (err == errSecItemNotFound) {
        query[(__bridge id)kSecValueData] = NSData_from_string(string_from_NSString(str));
        query[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAlways;
        err = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef*)&_attrs);
        assert(err == errSecSuccess);
    }

1 个答案:

答案 0 :(得分:1)

您正在重复使用let uniforms = { color: { type: 'v4', value: new three.Vector4(0.2, 0.8, 0.8, 1), }, opacity: { type: 'f', value: 1, }, region_left: { type: 'f', value: -1, }, region_right: { type: 'f', value: -1, }, region_top: { type: 'f', value: -1, }, region_bottom: { type: 'f', value: -1, }, } let vertex_shader = `varying vec2 screen_space_position; void main() { vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); screen_space_position = mvPosition.xy; gl_Position = projectionMatrix * mvPosition; }` let fragment_shader = `uniform vec4 color; uniform float opacity; uniform float region_left; uniform float region_right; uniform float region_top; uniform float region_bottom; varying vec2 screen_space_position; void main() { // The following just checks a 2D box I've defined in 'screen space' // (really it's camera space, but I'm using an ortho camera where units // are pixels) and sets the opacity to zero if the fragment is inside // it. float final_opacity = opacity; vec2 position = screen_space_position; if (position.x >= region_left && position.x <= region_right && position.y >= region_top && position.y <= region_bottom) { final_opacity = 0.0; } gl_FragColor = vec4(color.rgb, color.a * final_opacity); // I also tried just bypassing the above code and rendering 0 alpha // across the entire quad //gl_FragColor = vec4(1, 1, 1, 0); }` // Create geometry that represents a quad let geometry = new three.PlaneGeometry(1, 1) // PlaneGeometry assumes the lower left corner is (0, 0). This makes it // so the upper left corner is (0, 0). geometry.scale(1, -1, 1) let material = new three.ShaderMaterial({ uniforms, vertexShader: vertex_shader, fragmentShader: fragment_shader, transparent: true, }) let mesh = new three.Mesh(geometry, material) // Center the mesh mesh.position.set(0.5, 0.5, 0) let root = new three.Object3D() root.add(mesh) 来调用query,并且此功能的字典中出现的SecItemAdd值正在破坏它。您应该在致电kSecMatchLimit之前删除此密钥。

值得注意的是,SecItemAdd可能比[str dataUsingEncoding:NSUTF8StringEncoding]更好,这取决于你正在做什么。