【问题标题】:How to keep NSTimer alive in Background on iOS 7?如何在 iOS 7 上让 NSTimer 在后台保持活跃?
【发布时间】:2013-10-02 00:11:41
【问题描述】:

我创建了在后台运行 NSTimer 的应用程序。我使用位置管理器在后台运行 NSTimer,

我使用下面的链接在后台运行 NSTimer,

How do I get a background location update every n minutes in my iOS application?

这种方法在 iOS 6 上运行良好,但在 iOS 7 上不起作用。我的应用程序在 iOS 7 上的后台应用程序在一段时间后崩溃。

如果有任何不同的方法在后台运行 NSTimer,请告诉我。

提前致谢。

【问题讨论】:

  • NSTimer in background的可能重复
  • 改变你的设计 - 为什么你需要在后台设置一个计时器?
  • @Wain:我在特定时间获得了一些 GPS 数据,所以我使用了 NSTimer。就像我不想在下午 3.30 保持 GPS 数据并在 6.30 停止收集 GPS 数据的情况一样。系统杀死应用程序。在背景中。所以我只是每 5 分钟 ping 一次位置管理器,以保持 Timer 处于活动状态。
  • 添加一些代码来展示你如何管理你的定时器和后台过期。 Apple 更改了后台任务时间。
  • 为什么不检查您收到 GPS 更新的时间并决定是否需要保持注册状态以获取更新或断开连接?

标签: iphone objective-c cocoa-touch ios7


【解决方案1】:

在 iOS7 中,有一种新的周期性数据获取模式。将fetch 后台模式添加到您的应用程序,并在您的应用程序委托中,将间隔传递给- [UIApplication setMinimumBackgroundFetchInterval:。一旦应用进入后台,您的应用的代理将开始接收对 application:performFetchWithCompletionHandler: 的调用。

更多信息在这里: https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:performFetchWithCompletionHandler:

【讨论】:

  • 除此之外,在商店绑定的应用程序中禁止以启用位置的应用程序为幌子运行任意代码,对吧?
  • 从他的描述来看,他的应用似乎确实需要定位。 GPS 数据与位置相关。
  • @LeoNatan 后台获取模式是否可以合法地用于下载(获取)内容之外的其他目的? (例如触发位置更新)Apple 会接受吗?
  • 您可以在分配给您的应用程序的时间内做任何您想做的事情。请记住,您在后台占用的时间越长或占用的 CPU 越多,操作系统唤醒您的应用程序的频率就越低。您需要衡量您的资源占用并查看您的应用占用了多少资源。
  • @Visionscaper 是的,“获取”是相对的。您可以执行工作,完成后调用完成块。操作系统无法理解你在这两者之间做了什么。
【解决方案2】:
-(void)start {

[[NSUserDefaults standardUserDefaults ]setObject:[NSDate date] forKey:@"startTimer"];

 Nstimer*   timer2=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerFired) userInfo:nil repeats:YES];
}
-(void)timerFired
{
      @try {
    NSDate *timerStartDate = [[NSUserDefaults standardUserDefaults]objectForKey:@"startTimer"];


NSTimeInterval interval=[timerStartDate timeIntervalSinceNow];

int hour1=-interval/3600;

int rem =((int)interval)%3600 ;

int min1 = -rem/60 ;

int sec1 = -rem %60 ;

// NSLog(@"hour %i  rem %i",hour,rem);    
// NSLog(@"hour%i",hour1);
// NSLog(@"min%i",min1);
// NSLog(@"sec%i",sec1);


NSString *strmin=[NSString stringWithFormat:@"%i",min1];
NSString *strhour=[NSString stringWithFormat:@"%i",hour1];

if ([strmin integerValue]<10)
{
    [lblSeconds setText:[NSString stringWithFormat:@"0%@",strmin]];
}
else 
{
    lblSeconds.text=strmin;

}
if ([strhour integerValue]<10) {
    [lblHour setText:[NSString stringWithFormat:@"0%@",strhour]];
}
else
{
    lblHour.text=strhour;

}

}
@catch (NSException *exception) {
    NSLog(@"exception in timer %@ ",[exception description]);

}
  return;   
}

【讨论】:

  • -1:只是一堆代码,没有任何解释。而且也解决不了题主的问题。
【解决方案3】:
NSTimer *currentCycleTimer;

UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
[currentCycleTimer invalidate];
currentCycleTimer=nil;
secondsLeft = 120;
currentCycleTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target:self        selector:@selector(Countdown) userInfo:nil repeats: YES];

-(void) Countdown
{
  [currentCycleTimer invalidate];
  currentCycleTimer=nil;
}

【讨论】:

    【解决方案4】:
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
    loop = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(Update) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:loop forMode:NSRunLoopCommonModes];
    

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 1970-01-01
      • 2013-05-10
      • 1970-01-01
      • 2021-02-05
      相关资源
      最近更新 更多