我尝试使用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);
}
答案 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]
更好,这取决于你正在做什么。