2014-09-21 99 views
22

我为德国冰球联赛DEL制作了一个今日小部件。iOS 8今天的小部件在一段时间后停止工作

我从我们的服务器中加载下一个游戏并在tableView中显示它们。加载过程在提议的方法“widgetPerformUpdateWithCompletionHandler”中开始。最初我在“viewWillAppear”中加载了一些缓存数据。

一切工作到目前为止!

Screenshot of the working widget.

但是,一段时间(一天)的小工具停止工作后。当我打开通知中心时,窗口小部件显示正常,但不会再次更新。我必须从通知中心删除小部件,并且必须重新添加它。之后,小部件工作了一天,然后又停止工作。

要查看窗口小部件不在做什么,我在表格视图上方添加了一个状态文本的简单白色视图,同时在“widgetPerformUpdateWithCompletionHandler”中加载数据以查看窗口小部件是否在执行任何操作。小部件工作时会出现白色视图。当它不工作状态视图不会出现。所以我认为在widget在通知中心处于活动状态一段时间后,不会调用“widgetPerformUpdateWithCompletionHandler”方法。

我不知道是什么原因导致小部件停止工作。有任何想法吗?

回答

19

我遇到了同样的问题,我通过在网络请求后立即调用completionHandler(NCUpdateResultNoData); 解决了这个问题,即使响应还没有返回。我发现如果没有调用完成处理程序,则不会再调用widgetPerformUpdateWithCompletionHandler ,因此不会再有更新。请确保您在请求调用返回后,在所有分支中调用完成处理程序。

+0

是的,我发现相同。我尝试了一些东西,发现当网络请求需要一些时间(网络条件不好)时,widgetPerformUpdateWithCompletionHandler再也不会被调用。我认为完成处理程序以某种方式变得无效。你的解决方案将起作用,但这不是预期的方式。我根本没有使用widgetPerformUpdateWithCompletionHandler解决了这个问题。我希望这个问题在未来得到解决。 – 2014-10-09 16:54:06

+0

因此,如果不使用widgetPerformUpdateWithCompletionHandler,你在其他地方调用你的网络请求? – 2014-10-10 03:44:48

+0

是的,我调用viewDidAppear中的网络reuqest。所以小部件不会在后台刷新,但每次用户打开它。 – 2014-10-10 05:05:30

13

正如其他人所提到的,这是由于widgetPerformUpdateWithCompletionHandler被调用后没有以前称为completionHandler而引起的。 您需要确保completionHandler被调用,不管是什么

我建议处理这个问题的方法是通过保存completionHandler作为一个实例变量,然后在viewDidDisappear失败调用它:

@property(nonatomic, copy) void (^completionHandler)(NCUpdateResult); 
@property(nonatomic) BOOL hasSignaled; 

- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler { 
    self.completionHandler = completionHandler; 
    // Do work. 
} 

- (void)viewDidDisappear:(BOOL)animated { 
    [super viewDidDisappear:animated]; 
    if (!self.hasSignaled) [self signalComplete:NCUpdateResultFailed]; 
} 

- (void)signalComplete:(NCUpdateResult)updateResult { 
    NSLog(@"Signaling complete: %lu", updateResult); 
    self.hasSignaled = YES; 
    if (self.completionHandler) self.completionHandler(updateResult); 
} 
+2

我已经这样做了,但小部件在一段时间后也会停止工作.. – donmarkusi 2015-03-02 13:53:40

+0

我试过这样做,它似乎是一个明智的解决方案,以确保始终调用完成块。令人遗憾的是,使用这种方法并不能完全解决问题。 – bencallis 2015-03-16 21:23:55

+0

希望我可以在这里捐献金币,就像在reddit上一样。 – maksa 2015-05-18 16:46:34

1

一个异步调用前调用内widgetPerformUpdateWithCompletionHandler与NCUpdateResultNewData的completionHandler回来,用NCUpdateResultNewData或NCUpdateResultFailed再次调用它似乎工作。

3

另一个问题是,一旦widgetPerformUpdateWithCompletionHandler:停止被调用,将永远不会有另一个完成处理程序调用。我还没找到让系统再次拨打widgetPerformUpdateWithCompletionHandler:的方法。因此,请确保您的小部件也将尝试通过viewWillAppear:作为回退重新加载数据,或者某些用户可能会遇到未加载小部件。

+1

不幸的是,这是我最终做的,它的一个耻辱,即尝试正确使用widgetPerformUpdateWithCompletionHandler即使在iOS 9中也不起作用。谢谢你的建议,它是唯一真正为我解决这个问题的东西。 – 2015-09-19 02:47:03

+0

你是怎么做到这一点的?我认为没有一个合适的完成处理程序,系统永远不会知道这个小部件会返回执行状态,因此完全依赖于viewWillAppear调用?你是否做了任何同步,以确保正常运行时,事情不会重复更新两次? – RealCasually 2016-01-24 18:18:49