2016-08-01 12 views
9

Mam plik JSON wypełniony danymi ciągów w Katalogu dokumentów. W interfejsie użytkownika aplikacji znajduje się UIButton. Po naciśnięciu przycisku nowy ciąg dołącza się do pliku JSON.Jak uruchomić operacje w tle, gdy aplikacja na iOS znajduje się na pierwszym planie

Teraz szukam dowolnej usługi iOS, która pomoże mi wysłać te ciągi (z pliku JSON) na serwer przy użyciu szybkiego. Ta usługa powinna być całkowicie niezależna od mojego kodu. Chodzi o to, kiedy naciskam UIButton, pierwszym krokiem jest zapisanie ciągu znaków do pliku JSON, wtedy usługa powinna przyjąć ten ciąg i wysłać go do serwera, jeśli Internet jest dostępny.

Po wysłaniu łańcucha należy go usunąć z pliku JSON. Ta usługa powinna śledzić co 30 sekund, jeśli w pliku JSON jest zapisany dowolny ciąg, a następnie wysłać go do serwera.

I Googled i znalazłem background fetch, ale automatycznie uruchamia się funkcja performFetchWithCompletionHandler i nie wiem, kiedy system iOS ją uruchomi. Chcę uruchamiać ten rodzaj usługi samodzielnie po każdych 30 sekundach.

+0

Znalazłeś rozwiązanie dla swojej prośby? Dzięki! – jcasadellaoller

+1

jak/dlaczego byłby niezależny od twojej aplikacji? – Wain

+2

Jeśli szukasz demona/usługi, to masz pecha, system iOS nie obsługuje niestandardowych aplikacji uruchamianych na czas nieokreślony. – Cristik

Odpowiedz

10

Zapoznaj się z częścią przewodnika programowania aplikacji Apple dla systemu iOS w wersji Background Execution.

UIApplication zapewnia interfejs do uruchamiania i kończenia zadań w tle za pomocą UIBackgroundTaskIdentifier.

W górnym poziomie swoimi AppDelegate utwórz identyfikator zadania na poziomie klasy:

var backgroundTask = UIBackgroundTaskInvalid 

Teraz utworzyć zadanie z operacji, którą chcesz zakończyć i wdrożyć sprawę błędu w której zadaniem nie ukończono przed upływem terminu:

backgroundTask = application.beginBackgroundTaskWithName("MyBackgroundTask") { 
    // This expirationHandler is called when your task expired 
    // Cleanup the task here, remove objects from memory, etc 

    application.endBackgroundTask(self.backgroundTask) 
    self.backgroundTask = UIBackgroundTaskInvalid 
} 

// Implement the operation of your task as background task 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
    // Begin your upload and clean up JSON 
    // NSURLSession, AlamoFire, etc 

    // On completion, end your task 
    application.endBackgroundTask(self.backgroundTask) 
    self.backgroundTask = UIBackgroundTaskInvalid 
} 
+1

Pamiętaj, że będzie to wykonywane na pierwszym planie, jeśli aplikacja nie jest w tle, dopóki praca się nie zakończy. – Cristik

+0

Świetny punkt @Cristik. Sądzę, że jest to ostateczne rozwiązanie tego, o co prosi OP w związku z restrykcjami Apple. – JAL

+0

Dziękuję przyjacielu, że już rozwiązałem mój problem przez to samo podejście, które podałeś. – user3314286

0

Proszę odnieść się do NSURLSessionUploadTask, może to pomóc.

2

Co zrobiłem, po prostu używam podejścia omawianego przez JAL powyżej.

były trzy metody, które użyłem

func reinstateBackgroundTask() { 
     if updateTimer != nil && (backgroundTask == UIBackgroundTaskInvalid) { 
      registerBackgroundTask() 
      } 
    } 
    func registerBackgroundTask() { 
     backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { 
      [unowned self] in 
      self.endBackgroundTask() 
     } 
     assert(backgroundTask != UIBackgroundTaskInvalid) 
    } 

    func endBackgroundTask() { 
     NSLog("Background task ended.") 
     UIApplication.sharedApplication().endBackgroundTask(backgroundTask) 
     backgroundTask = UIBackgroundTaskInvalid 
    } 

gdzie updateTimer jest typu NSTIMER klasy Powyższe funkcje są w moim utworzonej klasy o nazwie „syncService” Ta klasa ma initialiser który

init(){ 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.reinstateBackgroundTask), name: UIApplicationDidBecomeActiveNotification, object: nil) 

     updateTimer = NSTimer.scheduledTimerWithTimeInterval(30.0, target: self, selector: #selector(self.syncAudit), userInfo: nil, repeats: true) 
     registerBackgroundTask() 

} 

Wtedy właśnie nazwałem tę klasę i cały problem został rozwiązany.

0
DispatchQueue.global(qos: .background).async { // sends registration to background queue 

} 
Powiązane problemy