从通知小组件中查找设备是否已锁定

Nic*_*ise 5 objective-c ios ios8-today-widget today-extension

我想知道当我加载Notification/Today小部件时设备是否被锁定,所以我可以适当地显示小部件.(这是财务方面的,我们不想在锁定的手机上显示余额)

在具有TouchID的设备上,我可以尝试访问Keychain,如果我得到的话

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"];
}
Run Code Online (Sandbox Code Playgroud)

编写/创建文件(在应用程序中,而不是扩展名:

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}];
Run Code Online (Sandbox Code Playgroud)

读:

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

  NSLog(@"isReadable? %@", isReadable ? @"YES" : @"NO");
Run Code Online (Sandbox Code Playgroud)

它始终能够读取文件,即使在屏幕锁定的TouchID设备上也是如此.如果我查看属性,它会显示NSFileProtectionKey设置为NSFileProtectionComplete ...但我仍然可以阅读它:(

更新:发现它.将伊恩的答案标记为正确

Ian*_*ald 8

NSFileProtectionComplete在您的应用运行时创建一个文件,然后尝试从您的扩展程序访问它.如果您无法访问它,屏幕将被锁定.

[[NSFileManager defaultManager] createFileAtPath:someFilePath
                                        contents:[@"Lock screen test." dataUsingEncoding:NSUTF8StringEncoding]
                                      attributes:@{NSFileProtectionKey: NSFileProtectionComplete}];
Run Code Online (Sandbox Code Playgroud)

编辑:包括完成解决方案和合并答案的最后步骤.(Nic Wise提供的剩余工作.)

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;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法,使用errSecInteractionNotAllowed也有效,但仅适用于TouchID设备.

我在这里找到答案(间接)(最有可能需要iOS开发程序)