2013-07-31 148 views
3

概述後臺位置更新

我COMPAGNY要求我釋放,可以檢查該設備的位置,每兩小時的iOS版應用的最佳實踐。應用程序會通過TCP/IP套接字將這些位置數據發送到我的服務器,然後根據這些非常數據(直接並通過相同的TCP/IP套接字)接收相應的信息。所以我不是試圖讓我的應用程序在後臺模式下連續運行(實際上,這似乎是iOS中的熱門話題,也不適合我的項目)。

問題

爲了可靠,什麼是實現這一目標的最佳做法?所以,我想知道:

  • 由於我的應用程序被暫停(=無效),並允許蘋果打開一個套接字時,它喚醒通過didUpdateToLocation發送位置?
  • 我需要多長時間通過套接字執行發送/接收任務?
  • 我應該使用beginBackgroundTaskWithExpirationHandler創建一個真實的後臺任務,並使用Cocoa允許的10分鐘來執行我的發送/接收任務嗎?
  • 這是可能的(並允許蘋果)要求每2小時10分鐘的後臺任務,沒有人爲干預(即用戶應該重新打開應用程序等)?

我取得了什麼/迄今發現

  • 我加入了location鑰匙在我Info.plist能夠運行didUpdateToLocation處理程序時,我的應用程序是無效的。
  • 我能夠通過套接字發送和接收數據,當我的應用程序處於前臺(=活動狀態)時打開了套接字。
  • 我試圖在調用didUpdateToLocation時檢查backgroundTimeRemaining。我得到了一個非常大的結果數字,這似乎是正常的,因爲在這一點上,applicationState不在UIApplicationStateBackground中,而是在UIApplicationStateActive中。

這些問題在官方文檔中並不十分清楚,我沒有找到與我的具體案例相關的主題。

感謝您的幫助。

+1

'beginBackgroundTaskWithExpirationHandler'不會創建後臺任務,它會將當前線程標記爲希望在應用程序後臺運行時繼續運行的內容。 – progrmr

+1

@ user1382094:請記住將正確的答案標記爲您的問題的接受答案,以防萬一它幫助您。謝謝! – veducm

回答

4

根據Apple's documentation,您可以通過使用與您描述的非常類似的方法來實現這些目標。我會做的是類似於在this post by mindsizzlers解釋了一句:

  • ,推薦,打開顯著位置更新時,應用程序在後臺進入,讓您節省電池。你可以做到這一點,當應用程序被切換到後臺:

    - (void) applicationDidEnterBackground:(UIApplication *) application 
    { 
        // Create the location manager if you do not already have one. 
        if (nil == locationManager) 
         locationManager = [[CLLocationManager alloc] init]; 
    
        locationManager.delegate = self; 
        [locationManager startMonitoringSignificantLocationChanges]; 
    } 
    

    然後,系統將喚醒您的應用程序時的位置變化,如documentation解釋。

    如果你離開這個業務正常運行,您的應用程序隨後被暫停或終止,服務時新的位置數據到達時自動喚醒你的應用程序。在起牀時間,您的應用程序將放入後臺並給予少量時間來處理位置數據。由於您的應用程序位於後臺,因此應該儘可能少地完成工作,並避免任何可能阻止其在分配的時間到期之前返回的任務(如查詢網絡)。如果沒有,您的應用可能會被終止。

    爲了避免將新位置發送到服務器的行爲非常不可靠(有時可能有效),您應該事先告訴iOS您正在執行的後臺任務應該允許運行到完成。

  • 更改您的位置管理器委託(didUpdateToLocation)來處理後臺位置更新。

    - (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation 
    fromLocation:(CLLocation *)oldLocation 
    { 
        if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) { 
         // Send the new location to your server in a background task 
         // bgTask is defined as an instance variable of type UIBackgroundTaskIdentifier 
         bgTask = [[UIApplication sharedApplication] 
         beginBackgroundTaskWithExpirationHandler: 
         ^{ 
          [[UIApplication sharedApplication] endBackgroundTask:bgTask]; 
         }]; 
    
         // Make a SYNCHRONOUS call to send the new location to our server 
    
         // Close the task 
         if (bgTask != UIBackgroundTaskInvalid) { 
          [[UIApplication sharedApplication] endBackgroundTask:bgTask]; 
          bgTask = UIBackgroundTaskInvalid; 
         } 
    
        } else { 
          // Handle location updates in the normal way 
        } 
    } 
    

這樣一來,你就不會需要有定時器運行。由於每當它發生顯着變化時,您都會自動喚醒並將更新的位置發送到您的服務器。

當然,如果你想確保這種情況發生在一個特定的時間間隔,你仍然可以去設置一個計時器開始接收位置更新,一旦你得到它的方式,你把它發送到服務器。看看this post談論iOS的背景模式(部分:接收位置更新)和other 看看如何做到這一點。

相關問題