Чтение онлайн

на главную - закладки

Жанры

iOS. Приемы программирования

Нахавандипур Вандад

Шрифт:

Группа доступа является общим идентификатором моей команды и соответствует группе, имеющей доступ к нашей общей связке ключей. Разумеется, в вашем случае это значение будет другим. Воспользуйтесь приемами, изученными в разделе 8.0 этой главы, чтобы извлечь разрешения из ваших профилей инициализации.

Для первого из наших iOS-приложений я задам следующие настройки. Вы должны заменить их собственными.

• Идентификатор пакета com.pixolity.ios.cookbook.SecurityApp.

 Группа доступа к связке ключей F3FU372W5M.*.

 Профиль инициализации, специально созданный для идентификатора пакета данного приложения.

А вот мои настройки для второго приложения — того, которое будет считывать из связки ключей значения, сохраненные там первым приложением.

• Идентификатор пакета com.pixolity.ios.cookbook.SecurityApp.

 Группа доступа к связке ключей F3FU372W5M.*.

 Профиль инициализации, специально созданный для идентификатора пакета данного приложения, но отличающийся от аналогичного профиля, созданного для первого приложения.

Самая важная деталь, отличающая первое приложение (сохраняющее связку ключей) от второго (считывающего цепочку ключей), — это идентификаторы пакетов. Первое приложение будет использовать свой идентификатор пакета для сохранения значения в связке ключей, а второе — использовать идентификатор пакета первого приложения для считывания того самого значения из связки ключей. Код очень напоминает тот, что мы написали в разделе 8.2. Разница заключается в том, что новый код будет указывать группу доступа к связке ключей при сохранении данных в этой связке ключей:

#import «AppDelegate.h»

#import <Security/Security.h>

@implementation AppDelegate

— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

NSString *key = @"Full Name";

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

NSString *accessGroup = @"F3FU372W5M.*";

/* Сначала удаляем имеющееся значение, если оно существует. Этого можно

и не делать, но SecItemAdd завершится с ошибкой, если имеющееся

значение окажется в связке ключей */

NSDictionary *queryDictionary = @{

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

(__bridge id)kSecAttrService: service,

(__bridge id)kSecAttrAccessGroup: accessGroup,

(__bridge id)kSecAttrAccount: key,

};

SecItemDelete((__bridge CFDictionaryRef)queryDictionary);

/* Затем запишем новое значение в связку ключей */

NSString *value = @"Steve Jobs";

NSData *valueData = [value dataUsingEncoding: NSUTF8StringEncoding];

NSDictionary *secItem = @{

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

(__bridge id)kSecAttrService: service,

(__bridge id)kSecAttrAccessGroup: accessGroup,

(__bridge id)kSecAttrAccount: key,

(__bridge id)kSecValueData: valueData,

};

CFTypeRef result = NULL;

OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result);

if (status == errSecSuccess){

NSLog(@"Successfully stored the value");

} else {

NSLog(@"Failed to store the value with code: %ld", (long)status);

}

self.window = [[UIWindow alloc]

initWithFrame: [[UIScreen mainScreen] bounds]];

self.window.backgroundColor = [UIColor whiteColor];

[self.window makeKeyAndVisible];

return YES;

}

Код начинается с запрашивания связки ключей для нахождения имеющегося элемента с заданным ключом, именем службы и группой доступа к связке ключей. Если такое значение существует, мы удаляем его из связки ключей. Мы делаем это лишь для того, чтобы позже можно было успешно добавить новое значение. Функция SecItemAdd завершится с ошибкой, если вы попытаетесь перезаписать ею имеющееся значение. Поэтому мы удаляем имеющееся значение (если оно существует) и записываем новое. Вы также можете попытаться найти имеющееся значение, обновить его (при наличии такого значения), а если оно отсутствует — записать новое значение. Второй подход более сложен, а поскольку мы выполняем демонстрационное упражнение, обойдемся первым примером.

Однако прежде, чем вы сможете запустить это приложение, необходимо задать в коде разрешения, связанные с подписыванием. Чтобы задать элементы, регламентирующие подписывание кода, выполните следующие шаги.

1. Воспользуйтесь приемами, изученными во введении к этой главе, нужными для извлечения разрешений, находящихся в вашем профиле инициализации.

2. Создайте в вашем приложении новый. plist-файл и назовите его Entitlements.plist. Вставьте содержимое файла с разрешениями из профиля инициализации — в точности как они есть — в ваш файл Entitlements.plist и сохраните.

3. Перейдите в настройки сборки и найдите разрешения подписывания кода (Code Signing Entitlements). Задайте для этого раздела значение $(TARGET_NAME)/Entitlements.plist. Оно означает, что Xcode должна найти файл Entitlements.plist в целевом каталоге, имеющем такое имя.

Опишу причины, по которым нам требуется это значение. Если создать проект под названием MyProject, Xcode создаст корневой каталог (SCROOT) под названием MyProject. В нем среда создаст еще один подкаталог, который также будет называться MyProject, а уже в этом каталоге будет находиться ваш исходный код. В каталоге SCROOT (то есть в вышестоящем каталоге под названием MyProject) будет создан еще один подкаталог под названием MyProjectTests. В этом подкаталоге будут модульные тесты, интеграционные тесты и тесты пользовательского интерфейса. Под этой структурой вы найдете ваш файл Entitlements.plist (он находится по адресу MyProject/MyProject/Entitlements.plist). Программа поиска разрешений подписывания кода ищет указанный. plist-файл в каталоге SRCROOT, поэтому, если вы предоставите ей значение MyProject/MyProject/Entitlements.plist, это ее вполне устроит! $(TARGET_NAME) в Xcode — это переменная, разрешаемая в имя вашей цели, которое по умолчанию совпадает с именем вашего проекта. Следовательно, в случае с MyProject значение $(TARGET_NAME)/Entitlements.plist будет разрешаться в MyProject/Entitlements.plist.

Поделиться:
Популярные книги

Последний Паладин. Том 7

Саваровский Роман
7. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 7

Солнечный флот

Вайс Александр
4. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Солнечный флот

Антимаг его величества. Том IV

Петров Максим Николаевич
4. Модификант
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Антимаг его величества. Том IV

Я до сих пор не князь. Книга XVI

Дрейк Сириус
16. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я до сих пор не князь. Книга XVI

Дракон

Бубела Олег Николаевич
5. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.31
рейтинг книги
Дракон

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Двойник короля 18

Скабер Артемий
18. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 18

Газлайтер. Том 4

Володин Григорий
4. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 4

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

Мастер 5

Чащин Валерий
5. Мастер
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Мастер 5

Зодчий. Книга III

Погуляй Юрий Александрович
3. Зодчий Империи
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Зодчий. Книга III

Заход. Солнцев. Книга XII

Скабер Артемий
12. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Заход. Солнцев. Книга XII