你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS省市二級聯動的數據組織PHP版

iOS省市二級聯動的數據組織PHP版

編輯:IOS開發綜合

之所以要發表這篇博客,還源於最近的開發工作所實現的一個小的Demo, 當然這個Demo不會涉及工作中App的一些內容,下方要實現的Demo是通用的。因為項目需求的迭代,要求在銀行卡綁定中添加支行所在的省市信息。在iOS中選擇這種省市信息的一個比較不錯的方式當時是使用UIPickerView進行顯示了。當然在PickerView上的省市信息是聯動顯示的,我們在此因為需求定的是讓用戶選擇省市信息,所以我們進行二級聯動,當然多級聯動的原理也是一樣的。由於之前的老項目是使用Objective-C寫的,雖然現在是Swift與OC混編,不過要在OC實現VC上添加新的功能還得用OC來實現呢,所以今天的博客的Demo咱就不用Swift來實現了,不過原理上是一樣的。

下方的的截圖就是我們今天博客中要介紹的Demo的運行效果,我們今天的博客就是生成PickerView所需的數據,以及對下方這個PickerView進行封裝。從下方的動畫中我們不難看出,在第一列選擇省後,第二列會自動的顯示該省下的所有地級市。點擊完成後,會在上方相應的Label中顯示出你所有選擇的省市以及該省市所對應的編號。具體的請看下方這個粗劣的動畫。

  

一、數據源的生成(從Excel到Plist)

1.組織數據的前奏

在封裝上述PickerView控件之前,我們得有數據不是,也就是我們得有省市的名稱,各個省市所對應的編碼,以及省與市的對應關系。當然這些數據在網上一抓一大把,權威的數據要看"國家統計局"所提供的數據了。下方這兩個截圖是一個Excel表格中的兩個Sheet,是我們服務端的一個程序媛給的,算是客戶端與服務端的一個標准吧,估計也是從網上下載的。下方的省市信息以及編碼當然與國家統計局提供的一致了,這個毋庸置疑。

我拿到這個Excel表格怎麼用呢?我就想通過OC或者Swift來直接解析excel表格來讀取數據,然後處理成我想要的格式。不過經過一番了解後,感覺該解決方案頗為復雜,於是乎就另尋他路。又於是乎,想起了之前用過的PHPExcel這個框架,因為之前做PHP開發的時候使用過PHPExcel來讀取Excel文件。這個PHPExcel使用起來還是蠻順手的,用起來也不復雜,於是乎我就決定使用PHPExcel來讀取下方這兩個Sheet中的數據。

使用PHPExcel讀取數據後,重新將數據進行關聯組織並生成json提供給iOS這邊使用。iOS這邊獲取到Json後,將其進行解析後存儲到plist文件中,這樣我們就可以從plist文件中來獲取“省市”相關數據了,然後我們就可以封裝我們的PickerView了。今天博客就一步一步的來完成這個東西。當然你也可以使用SQLite數據庫來存儲下方Excel中的數據,create兩張表,一張放省,一張放市,使用外鍵進行一對多的關聯即可。使用SQLite數據庫是另一種解決方案,在此我們使用的是plist文件,因為相對簡單嗎,因為數據少,plist文件度過了就可以在我們的pickerView上使用了,如果你想使用SQLite也是相當OK的,此篇博客值提供plist文件這種解決方案。

2.使用PHPExecl讀取省市Excel數據

在上面的Excel數據中第一個Sheet中存儲的是每個省以及每個省所對應的編碼,而第二個Sheet中是存儲的每個市和市的編碼,並給出了每個市所在的省。接下來我們要使用PHPExcel這個第三方框架對上述Excel的數據進行讀取,關於PHPExcel的東西請看其官方文檔,地址為:https://phpexcel.codeplex.com/。下方代碼就是我們使用PHPExcel讀取上述Excel文件的代碼了,並且將上述數據進行處理,將處理後的數據進行json編碼。下方我們將介紹相關的PHP代碼。

(1)加載PHPExcel框架以及省市excel文件--province.xls

下方的PHP代碼片段就是加載PHPExcel框架,以及通過PHPExcel_IOFactory來創建文件讀取器對象$objReader, 並公告$objReader對象來加載我們的province.xls文件。打開後會返回一個操作Excel文件的一個文件句柄對象$objPHPExcel,我們可以通過$objPHPExcel來操作已經打開的Excel文件。具體代碼如下所示。

(2)通過上述$objPHPExcel對象來讀取Excel文件內容

接下來我們要通過$objPHPExcel這個操作文件的對象來獲取province.xml中的數據。下方對主要的代碼添加的注釋,應該還算是清晰。在下方代碼片段中$dataArray數組我們用來存儲province.xml中所有Sheet的數據。我們循環了兩次來打開該Excel中的兩個Sheet,通過$objPHPExcel對象的setActiveSheetIndex()方法通過索引來選擇相應Sheet(從左到右,從0到n),並通過該對象的getActiveSheet()方法來獲取當前選擇的Sheet,選擇後返回一個$objWorksheet對象,我們可以通過$objWorksheet對象來讀取當前Sheet中每行每列的數據。

我們通過foreach來迭代當前Sheet中的每行數據,同樣適用foreach來迭代一行中每列的數據。我們將每列的數據存入$tempRowArray數組中,然後在將每行的數據即$tempRowArray存入到Sheet數據的$tempSheetArray中。最後將當前的Sheet的數據$tempSheetArray存入到$dataArray中。具體實現如下:

3.數據的驗證

通過上述步驟,我們就可以將Excel中的每個Sheet中的數據存入到我們的數組中。其中的數據結果是這樣的: $dataArray中存儲的是每個Sheet($tempSheetArray)的數據,Sheet($tempSheetArray)中又有多行($tempRowArray),每行($tempRowArray)中又有多列。所以dataArray就對應著整個Excel表格。我們也就獲取了所有的Excel數據。經過上述代碼,$dataArray中就存儲了Excel的數據。為了保險起見我們將$dataArray中的數據進行打印,下方是我們的測試代碼。

還有在我們寫程序時呢,為了減少bug量,以及減少調試bug的難度,我們一定要養成一邊寫代碼一遍調試的好習慣。這樣會及時發現bug並修正,寫好一個小的功能模塊我們就對其進行測試,如果出了問題就很容易定位bug的所在之處。下方代碼就是對上述代碼的測試:

  

上述代碼對$dataArray中存儲的數據進行了一個打印,可以幫助我們查看我們$dataArray中所存儲的數據是否符合我們的預期。下方的輸出結果就是我們上述的測試用例所輸出的結果,上面紅框中是第一個Sheet中的數據,下方的是第二個Sheet中的數據,我們大體上一看符合我們的預期,就說明我們之前的代碼沒有什麼問題,我們就可以對$data中的數據進行關聯並生成JSON數據了。

 

4.省市數據進行關聯

上面我們已經將數據從Excel中讀取出來了,並且將量Sheet中的數據存入了不同的數組,接下來我們將要對數據進行處理。該部分就是將省市的數據進行關聯,也就是將兩個Sheet中的數據合並成一個數據塊。下方就是我們要存儲數據的一個結構圖。整個是一個數組,數組中是一個字典,每個字典就代表一個省。每個省的字典又省編碼Code、省名Name、所有市Citys組成。Citys中存儲的又是一個數組。該數組中的每一項又是一個字典,此處的每個字典代表著一個市,每個市的字典中有包括市名Name和市編碼Code。數據結構如下所示。

  

參考上圖,我們要對讀取的數據進行處理,將數據重新組織成上述結構。下方代碼段就是對讀取的Excel表格中的數據進行重組。經過下方代碼的處理我們就可以得到上述結構的數據了。下面的$allDataArray就存儲的是所有的數據信息,$provinceTempData中暫存著每次省的所有信息,$currentProvinceCitys中存儲的就是當前省中所有市的信息。第二個循環中的if語句則負責管理省市間的關系了,具體代碼以及代碼注釋如下所示。

經過上面的代碼我們所有的數據就會存入到$allDataArray中,上面對$allDataArray進行了Json編碼並輸出,下方就是處理後輸出的Josn數據。在此我們以河北省為例。下圖中的結構是與上面我們數據結構圖一一對應的,這正是我們想要的數據。到此我們數據處理的任務就完成一大半了,因為我們得到了我們想要的JSON。

5. 將上述JSON數據進行解析並存入Plist文件

經過上述步驟,PHP的工作算是告一段落。接下來我們就是要使用iOS客戶端來訪問上述地址,獲取上述生成的JSON數據。獲取到JSON數據後,我們將JSON數據進行解析,並存儲到沙盒中的plist文件。這樣我們就可以從plist文件中來加載我們的省市數據了。

下方代碼段是我們的iOS客戶端的代碼,該代碼通過NSURLSessionDataTask來請求上述PHP代碼所在的文件獲取省市的JSON數據。請求到JSON數據後對數據進行解析,將JSON數據解析成數組後在通過NSFileManager存儲到沙盒中的PList文件中。如果你要在外部使用,只需要找到模擬器中的沙盒路徑拷貝出plist文件即可。下方代碼就是網絡請求+JSON解析+Plist文件存儲的的代碼。

經過上述代碼的執行,你會在你的模擬器中上述App的沙盒中發現一個叫province.plist的文件,該文件中存儲的就是我們要使用的省市數據。該plist文件的數據存儲結構是我們上面的介紹過的數據結構,下方就是該plist文件中數據的部分截圖。至此我們就獲得了一個按我們的預期存有省市數據plist文件了。

 

二、封裝選擇省市的PickerView的使用方式

封裝當然不是簡單的將PickerView的簡單使用,在封裝代碼時我們要考慮到用戶的易用性和可擴展性。在此我只對PickerView做了一個簡單的封裝,不過干貨還是有的,主要是思想呢。經過上面一大模塊的數據組織呢,我們就可以將之前服務端所給的Excel文檔中的數據組織成我們想要的plist數據。本部分所做的主題就是讀取plist文件中的數據,將該數據顯示在二級聯動的PickerView上供用戶選擇。用戶選擇完成後返回用戶選擇的省市名以及省市所對應的編碼。開始我們控件的封裝。

1.所封裝控件的目錄結構

首先我們先整體的看一下我們所封裝控件的目錄結構是怎樣的,先整體的了解一下我們這個封裝的控件。下方截圖中就是我們所封裝控件的目錄結構了,因為我們是對顯示省市信息的UIPikcerView進行的封裝,所以在此我們稱其為ProvincePickerView,ProvincePickerView就是我們所封裝的組件了。用戶只需要對其進行實例化並添加到其視圖上就可以進行使用了。下方的province.plist數據就是我們上面所生成的存有省市信息是數據,我們ProvincePickerView中的數據源就是province.plist文件。

ProvinceModel就存儲著當前選中的省市的名稱以及編碼,下面第二張截圖就是ProvinceModel中的內容了。provinceCode存儲的是當前選中的省的編碼,provinceName存儲的就是當前所選省的名稱,cityCode存儲的是所選市的編碼,cityName存儲的是所選市的名稱。具體代碼如下所示。

2. 所封裝控件的初始化以及調用方式

接下來我們看一下我們封裝的這個ProvincePickerView的使用方式,使用起來還算簡單。下方代碼段就是ProvincePickerView初始化方式,將ProvincePickerView進行初始化然後添加到所要顯示ProvincePickerView的視圖上,然後設置ProvincePickerView對象的Block回調。該回調會在用戶點擊ProvincePickerView上的完成按鈕時執行,並返回當前用戶選中的省市信息的Model數據。

上面是初始化ProvincePickerView,並且設置數據回調Block。下方的代碼段就是用來顯示ProvincePickerView的,調用showPickerView方法就會在下方彈出ProvincePickerView,因為ProvincePickerView本身就有取消按鈕,取消後就會自動收回ProvincePickerView,所以我們不需要為用戶提供收回ProvincePickerView的方法,所以使用起來還是比較簡單的。

三、代碼分享

由於博客篇幅有限,至於ProvincePickerView中封裝的代碼在此就不一一的往上粘貼了。說白了最核心就是對UIPickerViewDelegate和UIPickerViewDataSource兩個代理中的相應的方法的封裝。還有就是如何顯示和隱藏PickerView,換一句話說,就是講PickerView放在什麼地方進行顯示。有感興趣的小伙伴可以從下方的github中分享的代碼來自行分析呢。事無巨細,所以在此就不做過多的贅述了。

下方的代碼截圖就是在github上分享的部分代碼,可以說是添加了詳細的注釋,有感興趣的小伙伴可以進行自行閱讀。代碼中如有偏頗之處,還望指出。

上述所有的代碼都是使用截圖的方式呈現的,這無關緊要,在博客的結尾會給出所有相關的代碼,當然也包括上述的PHP代碼,以及PickerView的具體實現呢。好了,由於博客篇幅有限,今天就先到這兒吧。下方就是本篇博客相關代碼的分享鏈接。

github分享地址:https://github.com/lizelu/ProvincePickerDemo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved