Ios 通过通知小部件了解设备是否已锁定

Ios 通过通知小部件了解设备是否已锁定,ios,objective-c,ios8-today-widget,today-extension,Ios,Objective C,Ios8 Today Widget,Today Extension,我想知道当我加载我的Notification/Today小部件时,设备是否被锁定,这样我可以适当地显示小部件。(这是财务问题,我们不想在锁着的手机上显示余额) 在使用TouchID的设备上,我可以尝试访问钥匙链,如果 errSecInteractionNotAllowed 后面,锁上了。一切都好这在没有touchID的设备上不起作用(但带有PIN)。我发现了一些建议使用 [[UIApplication sharedApplication]protectedDataAvailable] 但是,我在

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

在使用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…但我仍然可以读取:(


更新:找到它。将Ian的答案标记为正确

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

[[NSFileManager defaultManager] createFileAtPath:someFilePath
                                        contents:[@"Lock screen test." dataUsingEncoding:NSUTF8StringEncoding]
                                      attributes:@{NSFileProtectionKey: NSFileProtectionComplete}];
编辑:包括完成解决方案和整合答案的最后步骤。(剩余工作由Nic Wise提供。)

另一种方法是使用
errSecInteractionNotAllowed
,但仅适用于TouchID设备


我(间接地)找到了答案(最有可能需要的是iOS开发程序的rego)

最后,经过3-4天的查找,我找到了答案。更多的是我如何读取结果。Ian是对的:我需要使用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设备


我(间接地)找到了答案(最有可能需要的是带iOS开发程序的rego)

我试过了,我的文件总是可读的(无论是否在锁屏中)

我发现这个文件:

设备锁定10秒后,文件似乎被锁定

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

知道了这一点,你可以从扩展名创建文件,这似乎很有效。

谢谢Ian-我尝试过,但我是从扩展名创建的。我将从应用程序中重试。谢谢标记Ian的答案为正确,因为他大部分时间都在那里-请参阅我自己的回复,了解如何重新阅读(obv,你需要两者)我更新了答案,将您的工作包含在一个地方。这很好,但仅在用户拥有PassCode时有效。检查文件是否存在与验证文件是否可读不同。