Узнать, заблокировано ли устройство, из виджета уведомлений

Я хотел бы знать, заблокировано ли устройство, когда я загружаю виджет «Уведомление/Сегодня», чтобы я мог правильно отображать виджет. (это финансовые вопросы, и мы не хотим показывать баланс на заблокированном телефоне)

На устройствах с TouchID я могу просто попытаться получить доступ к Связке ключей, и если я получу

errSecInteractionNotAllowed

назад, он заперт. Все хорошо. Это не работает на устройствах без touchID (но с PIN-кодом). Я нашел несколько вещей, которые рекомендуют использовать

[[UIApplication sharedApplication] protectedDataAvailable]

Однако у меня нет [UIApplication sharedApplication] в виджете.

Есть идеи где и как это сделать? Мне просто нужно да/нет: устройство заблокировано.

Спасибо

[ОБНОВЛЕНИЕ: вот код, который у меня есть]

Получение имени файла:

+ (NSString *)lockedDeviceFilename {
    NSURL *directoryUrl = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:USER_DEFAULTS_GROUP_NAME];
   return [directoryUrl.path stringByAppendingPathComponent:@"security.dummy"];
}

Запись/создание файла (в приложении, а не расширение:

NSError *error = nil;

NSString *documentPath = [FOOStorageGatekeeper lockedDeviceFilename];

[[NSFileManager defaultManager] removeItemAtPath:documentPath error:&error];

BOOL created = [[NSFileManager defaultManager] createFileAtPath:documentPath
                                                       contents:[@"super secret file contents. we only care about the permissions" dataUsingEncoding:NSUTF8StringEncoding]
                                                     attributes:@{NSFileProtectionKey : NSFileProtectionComplete}];

Чтение:

 BOOL isReadable = [[NSFileManager defaultManager] fileExistsAtPath:[FOOStorageGatekeeper lockedDeviceFilename]];

  NSLog(@"isReadable? %@", isReadable ? @"YES" : @"NO");

Он всегда может прочитать файл, даже на устройстве TouchID с заблокированным экраном. Если я посмотрю на атрибуты, это покажет, что для NSFileProtectionKey установлено значение NSFileProtectionComplete... но я ВСЕ ЕЩЕ МОГУ ПРОЧИТАТЬ ЭТО :(

Обновление: нашел. Пометка ответа Яна как правильного


person Nic Wise    schedule 13.01.2015    source источник
comment
Проверка существования файла — это не то же самое, что проверка его читаемости.   -  person Tom Harrington    schedule 14.01.2015


Ответы (3)


Создайте файл с NSFileProtectionComplete во время работы вашего приложения, а затем попытайтесь получить к нему доступ из своего расширения. Если вы не можете получить к нему доступ, экран заблокирован.

[[NSFileManager defaultManager] createFileAtPath:someFilePath
                                        contents:[@"Lock screen test." dataUsingEncoding:NSUTF8StringEncoding]
                                      attributes:@{NSFileProtectionKey: NSFileProtectionComplete}];

EDIT: добавлены последние шаги для завершения решения и объединения ответов. (Остальные работы предоставлены Ником Уайзом.)

NSData *data = [NSData dataWithContentsOfURL:[FOOStorageGatekeeper lockedDeviceUrl] options: NSDataReadingMappedIfSafe error:&error];

if (error != nil && error.code == 257) {
    NSLog(@"**** the keychain appears to be locked, using the file method");
    return YES;
}

Другой метод с использованием errSecInteractionNotAllowed тоже работает, но только для устройств TouchID.

Я нашел ответ (косвенно) здесь (скорее всего, потребуется rego с программой разработки iOS)

person Ian MacDonald    schedule 14.01.2015
comment
Спасибо Ян - я пробовал это, но я создавал его из расширения. Попробую еще раз из приложения. Спасибо - person Nic Wise; 14.01.2015
comment
Пометка ответа Яна как правильного, так как он в основном был там - см. мой собственный ответ, чтобы прочитать его обратно (вам нужны оба, аверс) - person Nic Wise; 14.01.2015
comment
Я обновил ответ, чтобы включить вашу работу, чтобы все было в одном месте. - person Ian MacDonald; 14.01.2015
comment
Это все здорово, но работает только тогда, когда у пользователя есть пароль - person mcfedr; 14.03.2017

Наконец, после 3-4 дней поисков, нашел ответ. Это было больше в том, как я читал результат назад. Ян прав: мне нужно создать файл, используя createFileAtPath, но затем прочитать его, используя

NSData *data = [NSData dataWithContentsOfURL:[FOOStorageGatekeeper lockedDeviceUrl] options: NSDataReadingMappedIfSafe error:&error];

if (error != nil && error.code == 257) {
    NSLog(@"**** the keychain appears to be locked, using the file method");
    return YES;
}

Другой метод с использованием errSecInteractionNotAllowed тоже работает, но только для устройств TouchID.

Я нашел ответ (косвенно) здесь (скорее всего, потребуется rego с программой разработки iOS)

person Nic Wise    schedule 14.01.2015

Я попробовал это, и мой файл всегда был доступен для чтения (на экране блокировки или нет).

Я нашел этот документ: https://www.apple.com/business/docs/iOS_Security_Guide.pdf

Оказалось, что файлы блокируются через 10 секунд после блокировки устройства.

Зная это, вы можете создавать файлы из расширений, и, похоже, это работает.

person user3492842    schedule 24.04.2015