iphone-背靠背为事件进行投票

iphone-背靠背为事件进行投票

很长一段时间以来,我一直在研究一种在我的iPhone应用程序中每隔X分钟轮询一次数据计数器的方法。在阅读了大量的后台执行文档和一些试用应用程序之后,我认为在不滥用后台API的情况下,这是不可能的。

上周,我发现这个应用程序就是这么做的。http:/itunes.apple.com/us/app/DataMan-实时-数据-使用/id3932873?mt=8

它在后台运行,并跟踪您所使用的蜂窝/WiFi数据的计数。我怀疑开发人员正在注册他的应用程序以跟踪位置变化,但是在应用程序运行时,位置服务图标是不可见的,我认为这是必需的。

有没有人知道如何做到这一点?



陪伴而非守候
浏览 347回答 3
3回答

慕尼黑的夜晚无繁华

我也见过这种行为。经过多次尝试,我发现了两件事情,这可能会有所帮助。但我仍不清楚这会如何影响检讨过程。如果您使用其中一个后台功能,应用程序将由iOS在后台再次启动,一旦退出(由系统)。我们稍后会滥用这个。在我的例子中,我使用了在我的plist中启用的VoIP回退。这里的所有代码都是在AppDelegate中完成的:// if the iOS device allows background execution,// this Handler will be called- (void)backgroundHandler {     NSLog(@"### -->VOIP backgrounding callback");     // try to do sth. According to Apple we have ONLY 30 seconds to perform this Task!     // Else the Application will be terminated!     UIApplication* app = [UIApplication sharedApplication];     NSArray*    oldNotifications = [app scheduledLocalNotifications];      // Clear out the old notification before scheduling a new one.     if ([oldNotifications count] > 0) [app cancelAllLocalNotifications];     // Create a new notification     UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];     if (alarm)     {         alarm.fireDate = [NSDate date];         alarm.timeZone = [NSTimeZone defaultTimeZone];         alarm.repeatInterval = 0;         alarm.soundName = @"alarmsound.caf";         alarm.alertBody = @"Don't Panic! This is just a Push-Notification Test.";         [app scheduleLocalNotification:alarm];     }}注册是在- (void)applicationDidEnterBackground:(UIApplication *)application {     // This is where you can do your X Minutes, if >= 10Minutes is okay.     BOOL backgroundAccepted = [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];     if (backgroundAccepted)     {         NSLog(@"VOIP backgrounding accepted");     }}现在神奇的事情发生了:我甚至不使用VoIP-Socket。但是这10分钟的回调提供了一个很好的副作用:在10分钟(有时更早)之后,我发现我的计时器和以前的运行记录被执行了一段时间。你可以看到这个,如果你放置一些NSlog(.)进入你的密码。这意味着,这个简短的“唤醒”会执行一段时间的代码。根据苹果的说法,我们还有30秒的执行时间。我想,类似线程的背景代码正在执行将近30秒。这是有用的代码,如果你必须“有时”检查一些东西。医生说,所有的背景任务(VoIP,音频,位置更新)将在后台自动重新启动,如果应用程序被终止。VoIP应用程序将在启动后在后台自动启动!通过滥用这种行为,您可以使您的应用程序看起来像运行“永远”。为一个背景进程(即VoIP)注册。这将导致您的应用程序在终止后重新启动。现在编写一些“任务必须完成”的代码。根据苹果的说法,你有一些时间(5秒?)左转完成任务。我发现,这一定是CPU时间。这意味着:如果你什么也不做,你的应用程序还在被执行!苹果建议,如果你的工作完成了,就打电话给一个呼气处理程序。在下面的代码中,您可以看到,我在期满处理程序上有一个注释。这将导致您的应用程序运行,只要系统允许您的应用程序运行。所有计时器和线程都在运行,直到iOS终止应用程序为止。- (void)applicationDidEnterBackground:(UIApplication *)application {     UIApplication*    app = [UIApplication sharedApplication];     bgTask = [app beginBackgroundTaskWithExpirationHandler:^{         [app endBackgroundTask:bgTask];         bgTask = UIBackgroundTaskInvalid;     }];     // Start the long-running task and return immediately.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{     // you can do sth. here, or simply do nothing!     // All your background treads and timers are still being executed     while (background)         [self doSomething];        // This is where you can do your "X minutes" in seconds (here 10)        sleep(10);     }     // And never call the expirationHandler, so your App runs     // until the system terminates our process     //[app endBackgroundTask:bgTask];     //bgTask = UIBackgroundTaskInvalid;     }); }在这里非常空闲的CPU时间,你的应用程序运行时间更长!但有一点是肯定的:你的应用程序会在一段时间后被终止。但是因为你注册了你的应用程序为VoIP或其他的一个,系统在后台重新启动应用程序,这将重新启动你的后台进程;-)用这个乒乓,我可以做很多回植。但请记住,与CPU的时间是非常空闲的。并保存所有数据,以恢复您的视图-您的应用程序将在一段时间后终止。为了使它看起来仍在运行,您必须在醒来后跳回最后的“状态”。我不知道这是不是你之前提到的应用程序的方法,但它对我有用。希望我能帮上忙最新情况:在测量了BG任务的时间之后,出现了一个惊喜。BG任务以600秒为限。这是VoIP最短时间的最小时间(setKeepAliveTimeout:600)。因此,这段代码在后台导致“无限”执行:标题:UIBackgroundTaskIdentifier bgTask;代码:// if the iOS device allows background execution,// this Handler will be called- (void)backgroundHandler {     NSLog(@"### -->VOIP backgrounding callback");     UIApplication*    app = [UIApplication sharedApplication];     bgTask = [app beginBackgroundTaskWithExpirationHandler:^{         [app endBackgroundTask:bgTask];         bgTask = UIBackgroundTaskInvalid;     }];     // Start the long-running task      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{     while (1) {         NSLog(@"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining);            [self doSomething];         sleep(1);     }   });     - (void)applicationDidEnterBackground:(UIApplication *)application {     BOOL backgroundAccepted = [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];     if (backgroundAccepted)     {         NSLog(@"VOIP backgrounding accepted");     }     UIApplication*    app = [UIApplication sharedApplication];     bgTask = [app beginBackgroundTaskWithExpirationHandler:^{         [app endBackgroundTask:bgTask];         bgTask = UIBackgroundTaskInvalid;     }];     // Start the long-running task     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{         while (1) {             NSLog(@"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining);            [self doSomething];            sleep(1);         }         }); }在应用程序超时后,将调用VoIP期满处理程序,您只需重新启动一个长时间运行的任务。此任务将在600秒后终止。但是会再次调用过期处理程序,这将启动另一个长时间运行的任务,等等。现在您只需检查应用程序是否返回到前台。然后关闭bgTask,你就完成了。也许一个人能做某事。在长时间运行的任务中,呼气处理程序就像这样。试试看。用你的控制台,看看会发生什么.玩得开心!更新2:有时候简化一些事情会有帮助。我的新方法是:- (void)applicationDidEnterBackground:(UIApplication *)application {     UIApplication*    app = [UIApplication sharedApplication];     // it's better to move "dispatch_block_t expirationHandler"     // into your headerfile and initialize the code somewhere else     // i.e.      // - (void)applicationDidFinishLaunching:(UIApplication *)application {//// expirationHandler = ^{ ... } }     // because your app may crash if you initialize expirationHandler twice.     dispatch_block_t expirationHandler;     expirationHandler = ^{         [app endBackgroundTask:bgTask];         bgTask = UIBackgroundTaskInvalid;         bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];     };     bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];     // Start the long-running task and return immediately.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{         // inform others to stop tasks, if you like         [[NSNotificationCenter defaultCenter] postNotificationName:@"MyApplicationEntersBackground" object:self];         // do your background work here          }); }这起作用了无网络电话攻击。根据文档,如果执行时间结束,过期处理程序(在本例中是我的“期满处理程序”块)将被执行。通过将块定义为块变量,可以在过期处理程序中递归地再次启动长时间运行的任务。这也导致了无止境的处决。如果应用程序再次进入前台,请注意终止任务。如果你不再需要的话就终止任务。根据我自己的经验,我测量了一些东西。使用位置回叫与有全球定位系统收音机是吸吮我的电池非常快。使用我在更新2几乎不需要任何能量。根据“用户体验”,这是一种更好的方法。也许其他的应用程序就是这样工作的,把它的行为隐藏在GPS功能后面.

一只萌萌小番薯

什么起作用,什么不起作用现在还不完全清楚这些答案中的哪一个有效&我浪费了大量的时间来尝试它们。以下是我对每一种策略的经验:网络电话攻击-工作,但是将要如果你不是VOIP应用程序,就会被拒绝递归beginBackgroundTask...-不起作用。10分钟后它就会退出。即使您尝试了注释中的修补程序(至少是截至2012年11月30日的注释)。无声的音频作品,但是人们因为这个而被拒绝。本地/推送通知-在您的应用程序被唤醒之前需要用户交互使用背景位置-作品..详情如下:基本上,您使用“位置”后台模式,以保持您的应用程序在后台运行。它确实有效,即使用户不允许位置更新。即使用户按下HOME按钮并启动另一个应用程序,您的应用程序也将继续运行。如果你的应用程序与位置无关的话,这也是一个电池消耗器&如果你的应用程序与位置无关的话,这可能是审批过程中的一个环节,但据我所知,这是唯一一个很有可能获得批准的解决方案。下面是它的工作原理:在你的褶皱里:应用程序不在后台运行:否所需背景模式:地点然后参考CoreLocation框架(在构建阶段),并在应用程序中的某个地方添加这段代码(在它进入后台之前):#import&nbsp;<CoreLocation/CoreLocation.h>CLLocationManager*&nbsp;locationManager&nbsp;=&nbsp;[[CLLocationManager&nbsp;alloc]&nbsp;init]; [locationManager&nbsp;startUpdatingLocation];注:startMonitoringSignificantLocationChanges将要不工作。值得一提的是,如果你的应用程序崩溃,iOS就不会让它复活。VOIP黑客是唯一能把它带回来的黑客。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

iOS