Читаем iOS. Приемы программирования полностью

OSStatus found = SecItemCopyMatching((__bridge CFDictionaryRef)query,

NULL);

Можно и не проверять наличие значения перед тем, как его обновлять. Вполне допустимо просто попытаться обновить значение. Если же его не существует, функция SecItemUpdate вернет значение errSecItemNotFound. Выбор заключается в том, проводить ли поиск в связке ключей самостоятельно или перепоручить эту задачу SecItemUpdate.

Если эта функция вернет значение errSecSuccess, вы будете знать, что интересовавшее вас значение уже обновлено. Обратите внимание: в качестве второго параметра мы передали NULL. Дело в том, что мы не собираемся получать из связки ключей старое значение. Мы просто хотим определить, существует ли значение, а сделать это можем, только проверив возвращаемое значение функции. Если возвращаемое значение равно errSecSuccess, делаем вывод, что значение уже было сохранено и может быть обновлено. Обновлять значение мы будем вот так:


NSData *newData = [@"Mark Tremonti"

dataUsingEncoding: NSUTF8StringEncoding];


NSDictionary *update = @{

(__bridge id)kSecValueData: newData,

};


OSStatus updated = SecItemUpdate((__bridge CFDictionaryRef)query,

(__bridge CFDictionaryRef)update);


if (updated == errSecSuccess){

NSLog(@"Successfully updated the existing value");

} else {

NSLog(@"Failed to update the value. Error = %ld", (long)updated);

}


Обновляющий словарь, который мы передаем функции SecItemUpdate в качестве второго параметра, может содержать больше ключей чем один ключ kSecValueData, использованный в нашем примере. На самом деле этот словарь может содержать обновления для любого имеющегося элемента. Например, если вы хотите добавить комментарий к имеющемуся значению (комментарий — это строка), то можете выполнить обновление следующим образом:


#import «AppDelegate.h»

#import 


@implementation AppDelegate


— (void) readExistingValue{


NSString *keyToSearchFor = @"Full Name";

NSString *service = [[NSBundle mainBundle] bundleIdentifier];


NSDictionary *query = @{

(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,

(__bridge id)kSecAttrService: service,

(__bridge id)kSecAttrAccount: keyToSearchFor,

(__bridge id)kSecReturnAttributes: (__bridge id)kCFBooleanTrue,

};


CFDictionaryRef cfAttributes = NULL;

OSStatus found = SecItemCopyMatching((__bridge CFDictionaryRef)query,

(CFTypeRef *)&cfAttributes);


if (found == errSecSuccess){


NSDictionary *attributes =

(__bridge_transfer NSDictionary *)cfAttributes;


NSString *comments = attributes[(__bridge id)kSecAttrComment];

NSLog(@"Comments = %@", comments);


} else {

NSLog(@"Error happened with code: %ld", (long)found);

}


}


— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{


NSString *keyToSearchFor = @"Full Name";

NSString *service = [[NSBundle mainBundle] bundleIdentifier];


NSDictionary *query = @{

(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,

(__bridge id)kSecAttrService: service,

(__bridge id)kSecAttrAccount: keyToSearchFor,

};


Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже