我們業務有這樣的一個需求場景,當用戶走進某一商戶附近時,我們可以給用戶發送和此商戶相關的推送消息,從而爲業務引流。針對這種需求,我們啓動了這個技術調研,android的方案大致是不斷獲取用戶當前位置經緯度,並上報到後端,後端經過計算判斷用戶是否已經進入提前劃好的區域,如果進入,則發送遠程通知給用戶即可。由於iOS和android的後臺能力不同,所以實現此功能的方案也不同。如果App一直處於Active狀態時還好,但是一旦App處於Backgroud後臺,就複雜了。經過調研,發現Core Location提供了Region Monitoring這種功能。
一、使用Region Monitoring需要滿足的條件
根據蘋果官方文檔中介紹,需要滿足以下幾個條件,纔可以使用Region Monitoring:
翻譯過來就是:
1、用戶的手機沒有區域監控所需的硬件;
2、用戶拒絕了App使用區域監控功能;
3、在設置裏面用戶關閉了App的定位服務;
4、用戶關閉了後臺應用刷新;
5、設備處於飛行模式狀態;
當然我們可以通過調用CLLocationManager的isMonitoringAvailableForClass:類方法和authorizationStatus(kCLAuthorizationStatusAuthorizedAlways)來判斷Region Monitoring功能的可用性。
二、CLCircularRegion監控區域
我們可以使用CLCircularRegion定義被監控的區域,看下這個類的定義就可以發現,有個center和radius,說明我們監控的區域都是圓形的。通過以下方法來進行初始化被檢測的區域:
identifier是region的唯一標識,如果添加的region的identifier相同,新的region將會替換掉舊的region。
三、啓動使用
調用CLLocationManager的startMonitoringForRegion:方法進行區域監測。區域監測結束時,可調用stopMonitoringForRegion:方法結束區域監測。
但是註冊了區域之後就立刻開始監控了,但不會收到事件,這是因爲事件觸發的條件必須是“boundary crossings”,也就是必須穿進或者穿出一個區域才能觸發回調方法:
可以使用CLLocationManager的requestStateForRegion:方法檢查用戶是否已經處於某個區域。當使用者進入、離開監測區域時,如果app沒有在執行,這個app會在Backgroud被relaunched,處理所觸發的進入、離開動作。如果app在後臺處於suspended狀態,這個app會被wokenup一小段時間(大概10秒,必要時可以要求更多背景執行時間)。細心的人一定會想,如果有用戶在邊界處不停地“徘徊”,難道會一直出發回調,對於這種情況,蘋果也有對應的解決方案,如下:
四、Region limit
蘋果的官方文檔中指出,每個App最多可以monitor 20個區域,監測的region是共享的系統資源,而整個系統所提供的監測數量是有限的。對於這個限制,蘋果給出的一個策略是,根據用戶當前所在位置設置不同的區域,用戶改變位置後,移除遠離的區域,設置新的區域。如果你超出了20繼續添加的話,會執行fail回調給你,如下:
通過下面stop方法即可停止monitor一個區域:
- (void)stopMonitoringForRegion:(CLRegion *)region
五、注意事項
1、如果用戶遠離了註冊的region,建議有對應的remove策略,畢竟定位相關的服務是比較耗電的;
2、請慎重地按需選擇定位accuracy精度和monitor的radius,它們的值都不宜設置的太大或太小;
3、經過測試,region monitor會將處於not running或suspend狀態下的app喚起到backgroud狀態,期間會執行appdelegate中的方法,
例如,application:didFinishLaunchingWithOptions:,如果你的app在這裏有比較大的性耗操作,建議優化下。
六、demo演示操作
下面我們來看一下一個演示demo,這個demo是代碼地址已在下面備註,可以自行下載:
1、我們在陸家嘴區域register一個center爲31.239394,121.499781,半徑爲1000米的區域,如下:
2、改變一下模擬定位的位置爲:31.259394,121.499781,如下:
3、此時我們再次改變當前位置經緯度爲:31.240394,121.499781,已經進入被檢測區域,如下:
同樣的,如果我們把App切到後臺或者殺掉,改變當前位置,依然可以收到本地local的通知,如下:
七、參考資料:
1、蘋果Region Monitoring文檔
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/RegionMonitoring/RegionMonitoring.html#//apple_ref/doc/uid/TP40009497-CH9-SW11
2、https://www.raywenderlich.com/136165/core-location-geofencing-tutorial
3、運行demo: