我正在执行一项锁定/解锁计数的任务。当应用程序处于前台但它无法在后台运行时工作正常。请帮助我
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[[NSUserDefaults standardUserDefaults]setInteger:0 forKey:@"COUNT"];
[[NSUserDefaults standardUserDefaults]synchronize];
isVAlue=0;
//[self registerAppforDetectLockState];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];
MainViewController *mainCtrl=[[MainViewController alloc]initWithNibName:@"MainViewController" bundle:nil];
self.window.rootViewController=mainCtrl;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
-(void)registerAppforDetectLockState {
int notify_token,countval;
NSString *task=[[NSUserDefaults standardUserDefaults]valueForKey:@"STATE"];
notify_register_dispatch("com.apple.springboard.lockstate", ¬ify_token,dispatch_get_main_queue(), ^(int token)
{
uint64_t state = UINT64_MAX;
notify_get_state(token, &state);
NSLog(@"notify_token %d",token);
if (isVAlue)
{
// notify_cancel(token);
}
if(state == 0) {
isVAlue=YES;
taskName=@"Unlock";
[[NSUserDefaults standardUserDefaults]setValue:taskName forKey:@"STATE"];
[[NSUserDefaults standardUserDefaults]synchronize];
int value=[[[NSUserDefaults standardUserDefaults] valueForKey:@"COUNT"]intValue];
value=value+1;
[[NSUserDefaults standardUserDefaults]setInteger:value forKey:@"COUNT"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(@"value %d",value);
NSLog(@"unlock device");
NSDictionary *incrementVal=@{@"incrementVal":[NSNumber numberWithInt:value]};
[[NSNotificationCenter defaultCenter] postNotificationName:@"HiEverybody" object:self userInfo:incrementVal];
} else {
taskName=@"Lock";
[[NSUserDefaults standardUserDefaults]setValue:taskName forKey:@"STATE"];
[[NSUserDefaults standardUserDefaults]synchronize];
NSLog(@"lock device");
isVAlue=NO;
}
});
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateInactive) {
NSLog(@"Sent to background by locking screen");
[self backgroundTask];
} else if (state == UIApplicationStateBackground) {
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"kDisplayStatusLocked"]) {
NSLog(@"Sent to background by home button/switching to other app");
} else {
NSLog(@"Sent to background by locking screen");
[self backgroundTask];
}
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"kDisplayStatusLocked"];
[[NSUserDefaults standardUserDefaults] synchronize];
//[self registerAppforDetectLockState];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
-(void)backgroundTask
{
UIApplication* application = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier background_task;
//Registered a background task, telling the system we need to borrow some events to the system
background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
//[self registerAppforDetectLockState];
//Whether or not complete, the end of background_task task
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self registerAppforDetectLockState];
if (TRUE)
{
NSLog(@"running");
}
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
});
}
请帮助您了解如何在后台模式下连续运行应用程序。 谢谢 Dronavalli
答案 0 :(得分:0)
请帮助您了解如何在后台模式下连续运行应用程序。
这是不可能的。您无法确保应用始终运行。
如果用户已启动您, if 尚未被杀死, if 用户有锁码,您可以实施UIApplicationDelegate
方法applicationProtectedDataWillBecomeUnavailable:
和applicationProtectedDataWillBecomeAvailable:
,以了解何时打开和关闭数据保护,这是您所谈论的内容的代理。但它不太可能与你所描述的完全匹配。
如上所述,您的申请无法实施。应用程序不是iOS中的OS服务。您需要将注意力集中在实际需要上。
答案 1 :(得分:-1)
查看Apple提供的本文档的“实施长时间运行的后台任务”部分。 来自Apple的文档:声明应用程序支持的后台任务 必须由使用它们的应用程序事先声明对某些类型的后台执行的支持。应用程序使用其Info.plist文件声明对服务的支持。将UIBackgroundModes键添加到Info.plist文件中,并将其值设置为包含以下一个或多个字符串的数组:(请参阅上面提到的链接中的Apple文档。)