Tôi cũng có vấn đề này, và nó đã cho tôi mãi mãi để tìm ra
Có một phiên bản của "KeychainWrapper" nổi xung quanh đó đã nó SecItemUpdate trong một NSAssert (trong số những thứ khác).
Ai đã làm điều này là một moron !, khi xây dựng cho phát hành/phân phối mỗi NSAssert được vô hiệu hóa, có nghĩa là mã thậm chí không chạy.
Ví dụ:
NSAssert(SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck), @"Couldn't update the Keychain Item.");
nhu cầu để trở thành
OSStatus status = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)tempCheck);
NSAssert(status == noErr, @"Couldn't update the Keychain Item.");
Thông báo như thế nào SecItemUpdate thực tế được chuyển ngoài NSAssert, và thay vào đó kết quả được kiểm tra
Lưu ý quan trọng: Cố để cập nhật giá trị cho kSecValueData, mà không chỉ định giá trị cho kSecAttrAccount, cũng sẽ khiến xác nhận thất bại. Vì vậy, nếu mục đích của bạn là để lưu trữ một chuỗi duy nhất của dữ liệu nhạy cảm (chẳng hạn như một danh sách các số thẻ tín dụng), hãy chắc chắn để lưu trữ một số "tên tài khoản" văn bản trong các thuộc tính kSecAttrAccount, như vậy:
static NSString* kCardListXML = @"cardListXML";
static NSString* cardListAccountName = @"cardListAccount";
-(void)setCardListXML:(NSString*)xml {
KeychainItemWrapper* wrapper =
[[KeychainItemWrapper alloc] initWithIdentifier:kCardListXML accessGroup:nil];
[wrapper setObject:cardListAccountName forKey:(id)CFBridgingRelease(kSecAttrAccount)];
[wrapper setObject:xml forKey:(id)CFBridgingRelease(kSecValueData)];
}
-(NSString*)getCardListXML {
KeychainItemWrapper* wrapper =
[[KeychainItemWrapper alloc] initWithIdentifier:kCardListXML accessGroup:nil];
[wrapper setObject:cardListAccountName forKey:(id)CFBridgingRelease(kSecAttrAccount)];
return [wrapper objectForKey:CFBridgingRelease(kSecValueData)];
}
Tôi đã tìm ra và đây chính là vấn đề. Cảm ơn. – iHorse
Điều đó dường như được sửa trong v1.2 của KeychainWrapper, có sẵn từ Mã mẫu Xcode – Olaf