總結關於iOS室內定位開發踩過的一些坑。。。


直接正題,沒得BB

首先說明一下室內定位從架構上嚴格來講分為3步:

1、室內地圖以及室內地圖能相關的一些成熟API

2、以任意方式來獲取室內定位的坐標

3、將室內定位的坐標轉化成室內地圖的API或者一種能兼容兩者的轉換方式

(可選)4、定位穩定性的濾波處理,試定位坐標點不出現 跳點、卡頓、掉幀、北偏角指向性錯誤等影響用戶體驗的處理方案

 

目前市場中室內定位資源比較散亂,主要分為地圖供應商和定位服務商兩種,也有將室內定位資源合並的企業,比如 某石科技

所以要是想對室內定位有研究的最好還是需要多方了解提供商的SDK相關信息

最近我們公司的室內定位項目馬上殺青了,才有空寫個博客散散心,總結一下iOS開發中踩過的坑:

1、手機端地圖出現黑色無色模型,Web端出現透明模型。

2、路徑導航無法規划路線。

3、無法繪制路徑/SDK的相關方法/對象不執行。

4、地圖對象創建后未銷毀,造成第二次地圖對象在規划路徑的時候閃退、崩潰。

5、地圖圖標出現黑塊。

6、返回上一級界面后未執行dealloc方法。

7、路徑繞遠。

8、U型彎道或L型彎道在路網吸附的模式下路過會出現跳點。

9、地圖加載失敗。

10、地圖的繪制/解析慢。

========================分割線=========================

我的解決方案:

1、手機端地圖出現黑色無色模型,Web端出現透明模型。

原因:這個是因為主題不兼容造成的,地圖在SDK解析過程中根據資源包已經賦予其顏色屬性了,如果沒有相關資源包就默認為黑色

我使用的是蜂鳥視圖,我們地圖屬性和顯示是經過定制的,所以使用常規的主題就會造成黑塊模型的出現。

WEB端JS的SDK做過相關處理,所以展示只是透明的模型。

解決:與其相關開發人員溝通,重新更新一個定制的主題即可。

2、路徑導航無法規划路線。

原因:因為沒有相關路網能抵達終點,路網的結構大致是這樣的:

黑色區域是可到達的路網,紅色是禁止掉的路網。明白了吧,如果終點的附近沒有黑色路網,那么就代表這個點位是無法到達的

具體附近是多少,請注意供應商的API文檔說明

解決:要和相關地圖供應商聯合解決這個問題,因為具體有那些點位可達/不可達,最好去實地勘探一下。

3、無法繪制路徑/SDK的相關方法/對象不執行。

原因:請核對和官方的工程配置的做法是否有出入的地方,我出現這個原因是因為Other Linker Flags 中有個-ObjC錯寫成-Objc了,

C必須是大寫,要么XCode編譯器不會全編譯框架中的OC文件,編譯確實無錯,但是一旦調用相關API的時候,這個API會引起崩潰等風險。

解決:Other Linker Flags 中添加-ObjC,大小寫要分清

4、地圖對象創建后未銷毀,造成第二次地圖對象在規划路徑的時候閃退、崩潰。

原因:上一個地圖對象成為了僵屍對象,在執行規划路線/或者其他操作的時候同時操作了僵屍對象,這個在崩潰的時候會有日志:

“你操作了一個不可操作的對象/指針”

解決:不管怎么使用地圖視圖對象,一定要在這個VC地圖界面推出棧的時候(我用的push方法)查看是否執行dealloc方法,

如果沒有,最好在點擊退出的一瞬間將全部View remove掉,包括地圖視圖和相關View對象,然后指針置空,一定保證執行了dealloc。

保證程序穩定的情況下才能做更多事。

5、地圖圖標出現黑塊。

原因:這個說起來很尷尬=。=  因為需求中有一個模擬導航,需要模擬這個定位點一點點移動在線路上,並且行走等事件。

是吧、、肯定用到了NSTimer啊。。。所以這個原因是因為在另一種我沒想到的邏輯下退出界面,導致Timer沒被銷毀和暫停。

然后呢,地圖又是OpenGL繪制的。。在下一次進入地圖界面的時候,Timer占用了一個子線程,導致OpenGL一直沒時間去繪制圖標

導致地圖一些元素顯示成了黑塊。。

解決:一定要統計有幾種退出界面的方法,然后封裝一個安全的方法(就是在不釋放空對象的前提下能kill掉Timer),

在每種情況下退出界面都要執行這個能安全的kill掉Timer的方法,最后一定要監督dealloc方法的執行與否。

6、返回上一級界面后未執行dealloc方法。

原因:之前也提過很多了,主要是SDK中一些對象與主控制器的強引用造成的,這種很常見,要養成隨時查看dealloc的習慣。

有些人會想了:現在不都ARC了么?誰還會關心這些啊?

這樣想很不對,ARC可以為開發者節省很多代碼,使用ARC以后再也不需要關心什么時候retain,什么時候release,

但是這並不意味你可以不思考內存管理,你可能需要經常性地問自己這個問題:誰持有這個對象?

解決:注意哪些是Strong引用的對象再被操作,什么時候把他置nil,保證能降低一個內存開銷,性能上也是有很大的提升。

7、路徑繞遠。

原因:因為路網稀疏,導致想到達一個終點必須按照路網的規划來走,有興趣的可以研究一下dijstra算法,

這個是大部分主流地圖/導航的一個解決方案。

路網稀疏,只能這么走:

路網原因繞的遠,不怪你不怪SDK,只怪地圖路網沒設計好。

解決:當然是與供應商溝通咯=。=。。程序又做不了什么。。。。

8、U型彎道或L型彎道在路網吸附的模式下路過會出現跳點。

原因:因為路徑吸附的原理是判斷你的定位點在路徑周邊大概多少米之內,將點位強制吸附到路徑上

遇到U型彎道/L型彎道就會出現兩個判定,,說白了就是兩條路吸附范圍發生重疊造成的判定混亂。。懂了吧 =。=

解決:還是溝通咯。。只能讓他們把路網規划的更密一些,減少U型彎道的產生,至於L型么。。。小跳而已

誰也不會全程盯着手機看吧。。室內導航。。抬抬頭就能知道該咋走了,,我就跳跳 =。=

9、地圖加載失敗。以及 10、地圖的繪制/解析慢。

原因:因為整個地圖文件是經過混淆的,而且解析引擎是C++(蜂鳥視圖),解析完后再OpenGL繪制。。

聽着都繁瑣=。=。。當然慢了。。而且整個SDK流程是必須先經過認證后才能獲得解析權限。。當然慢咯。。

解決:沒辦法。。但是可以把解析和UI操作分開來做:

我們希望多個任務同時(在多個線程里)執行,再他們都完成之后,再執行其他的任務,
於是可以建立一個分組,讓多個任務形成一個組,下面的代碼在組中多個任務都執行完畢之后再執行后續的任務:

先解析地圖,然后頁面隨便展示一個 HUB或者Toast或者小菊花等等。。表示我們正在瘋狂的畫地圖。。。

然后設置兩個回調,一個地圖成功和失敗:

這個BOOL是在地圖解析完后,准備執行下一個操作的時候的限制判斷

如果解析成功則執行UI的創建和添加等等。。。如果失敗則顯示一個加載失敗的圖片。

注意,最后我是將所有操作全部回調到了主線程來執行的。。

這樣就可以不卡死主線程的情況下先推出界面,同時進行解析、解析完成后再將地圖添加到視圖,失敗了就展示失敗的頁面就好。

如果把解析(就是地圖的構造方法)放在ViewDidLoad中,會卡死主線程1~8秒不等。。。這樣肯定行不通的,比較平滑的處理先暫時只能這樣。。

養成注釋的習慣最好=。=  維護和二次開發的時候會很方便 =。= 

 

曬一張我的一個主繼承對象的h文件=。=

被人吐槽成把項目當SDK做。。

最后=。=  Axc大法好。。。。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM