2014-09-21 10 views
22

Zrobiłem dziś widget dla niemieckiej ligi hokejowej DEL.iOS 8 dziś widget przestaje działać po pewnym czasie

Wczytuję kolejne gry z naszego serwera i wyświetlam je w tableView. Proces ładowania rozpoczyna się w proponowanej metodzie "widgetPerformUpdateWithCompletionHandler". Początkowo ładuję niektóre buforowane dane w "viewWillAppear".

Wszystko działa świetnie!

Screenshot of the working widget.

Ale po jakimś czasie (jeden dzień) widżet przestaje pracy. Po otwarciu centrum powiadomień widżet wygląda normalnie, ale nigdy nie jest aktualizowany ponownie. Muszę usunąć widget z centrum powiadomień i muszę go dodać ponownie. Następnie widget działa przez jeden dzień, a następnie przestaje działać.

Aby zobaczyć, co widżet robi, dodałem prosty biały widok z tekstem statusu nad widokiem tabeli podczas ładowania danych w "widgetPerformUpdateWithCompletionHandler", aby zobaczyć, czy widget robi cokolwiek. Biały widok pojawia się, gdy widget działa. Kiedy nie działa, widok statusu nie pojawia się. Więc myślę, że metoda "widgetPerformUpdateWithCompletionHandler" nie jest wywoływana po tym, jak widget jest aktywny w centrum powiadomień przez jakiś czas.

Nie mam pojęcia, co powoduje, że widget przestaje działać. Jakieś pomysły?

Odpowiedz

19

Mam ten sam problem i rozwiązałem go, dzwoniąc pod numer completionHandler(NCUpdateResultNoData); zaraz po żądaniu sieci, nawet jeśli odpowiedź nie została zwrócona. Zauważyłem, że jeśli program obsługi zakończenia nie zostanie nazwany widgetPerformUpdateWithCompletionHandler , nie będzie już wywoływany, a zatem nie będzie już żadnych aktualizacji. Upewnij się także, że wywołasz obsługę zakończenia we wszystkich gałęziach po zwróceniu twojego żądania.

+0

Tak, znalazłem to samo. Próbowałem niektórych rzeczy i zorientowałem się, że gdy żądanie sieci zajmuje trochę czasu (złe warunki sieciowe), widgetPerformUpdateWithCompletionHandler nigdy nie jest wywoływany ponownie. Wydaje mi się, że obsługa zakończenia jest jakoś nieważna. Twoje rozwiązanie będzie działać, ale nie jest to zamierzony sposób. Rozwiązałem problem, ponieważ w ogóle nie korzystałem z widgetu widgetPerformUpdateWithCompletionHandler. Mam nadzieję, że problem zostanie rozwiązany w przyszłości. –

+0

Wywołujesz swoje żądanie sieciowe gdzie indziej, jeśli nie używasz widgetPerformUpdateWithCompletionHandler? –

+0

Tak Wzywam sieć reuqest w viewDidAppear. Widżet nie będzie odświeżany w tle, ale za każdym razem, gdy użytkownik go otworzy. –

13

Jak wspomnieli inni, jest to spowodowane tym, że nie wywołano wcześniej nazwy completionHandler po widgetPerformUpdateWithCompletionHandler. Musisz się upewnić, że completionHandler jest wywoływane bez względu na to, co.

Sposób Proponuję obsługi to zapisując completionHandler jako zmiennej instancji, a następnie nazywając ją zawiódł w 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

Robię to już, ale widget przestaje działać po pewnym czasie. – donmarkusi

+0

Próbowałem tego, ponieważ wydawało się rozsądnym rozwiązaniem, aby zapewnić, że blok zakończenia był zawsze wywoływany. Niestety zastosowanie tego podejścia nie rozwiązuje w pełni problemu. – bencallis

+0

Chciałbym dać złoto tutaj, jak na Reddicie. – maksa

1

Wywołanie completionHandler z NCUpdateResultNewData w widgetPerformUpdateWithCompletionHandler przed wywołania asynchronicznego wraca i dzwoni do niego ponownie z NCUpdateResultNewData lub NCUpdateResultFailed wydaje się działać.

3

Dodatkowym problemem jest to, że po zatrzymaniu wywołania widgetPerformUpdateWithCompletionHandler:, nigdy nie będzie innego programu obsługi zakończenia. Nie znalazłem sposobu, aby ponownie wywołać systemowe wywołanie widgetPerformUpdateWithCompletionHandler:. Dlatego upewnij się, że twój widget będzie próbował ponownie załadować dane przez viewWillAppear: jako rezerwowy, lub niektórzy użytkownicy mogą utknąć z niewładującym widżetem.

+1

Niestety tak właśnie zrobiłem, szkoda, że ​​próba prawidłowego użycia widgetu widgetPerformUpdateWithCompletionHandler nie działa nawet w iOS 9. Dziękuję za tę sugestię, to jedyna rzecz, która rozwiązała dla mnie ten problem. –

+0

Jak do tego doszło? Przypuszczam, że bez odpowiedniego programu obsługi zakończenia system nigdy się nie dowie, że widget znowu działa, a zatem będzie polegać wyłącznie na wywołaniach viewWillAppear? Czy robisz synchronizację, aby zapewnić prawidłowe funkcjonowanie, że rzeczy nie są dwa razy aktualizowane? – RealCasually

Powiązane problemy