欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS省市二级联动的数据组织PHP版

程序员文章站 2023-12-15 15:13:52
之所以要发表这篇博客,还源于最近的开发工作所实现的一个小的demo, 当然这个demo不会涉及工作中app的一些内容,下方要实现的demo是通用的。因为项目需求的迭代,要求...

之所以要发表这篇博客,还源于最近的开发工作所实现的一个小的demo, 当然这个demo不会涉及工作中app的一些内容,下方要实现的demo是通用的。因为项目需求的迭代,要求在银行卡绑定中添加支行所在的省市信息。在ios中选择这种省市信息的一个比较不错的方式当时是使用uipickerview进行显示了。当然在pickerview上的省市信息是联动显示的,我们在此因为需求定的是让用户选择省市信息,所以我们进行二级联动,当然多级联动的原理也是一样的。由于之前的老项目是使用objective-c写的,虽然现在是swift与oc混编,不过要在oc实现vc上添加新的功能还得用oc来实现呢,所以今天的博客的demo咱就不用swift来实现了,不过原理上是一样的。

下方的的截图就是我们今天博客中要介绍的demo的运行效果,我们今天的博客就是生成pickerview所需的数据,以及对下方这个pickerview进行封装。从下方的动画中我们不难看出,在第一列选择省后,第二列会自动的显示该省下的所有地级市。点击完成后,会在上方相应的label中显示出你所有选择的省市以及该省市所对应的编号。具体的请看下方这个粗劣的动画。

  iOS省市二级联动的数据组织PHP版

一、数据源的生成(从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文件这种解决方案。

iOS省市二级联动的数据组织PHP版

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文件。具体代码如下所示。

iOS省市二级联动的数据组织PHP版

(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中。具体实现如下:

iOS省市二级联动的数据组织PHP版

3.数据的验证

通过上述步骤,我们就可以将excel中的每个sheet中的数据存入到我们的数组中。其中的数据结果是这样的: $dataarray中存储的是每个sheet($tempsheetarray)的数据,sheet($tempsheetarray)中又有多行($temprowarray),每行($temprowarray)中又有多列。所以dataarray就对应着整个excel表格。我们也就获取了所有的excel数据。经过上述代码,$dataarray中就存储了excel的数据。为了保险起见我们将$dataarray中的数据进行打印,下方是我们的测试代码。

还有在我们写程序时呢,为了减少bug量,以及减少调试bug的难度,我们一定要养成一边写代码一遍调试的好习惯。这样会及时发现bug并修正,写好一个小的功能模块我们就对其进行测试,如果出了问题就很容易定位bug的所在之处。下方代码就是对上述代码的测试:

  iOS省市二级联动的数据组织PHP版

上述代码对$dataarray中存储的数据进行了一个打印,可以帮助我们查看我们$dataarray中所存储的数据是否符合我们的预期。下方的输出结果就是我们上述的测试用例所输出的结果,上面红框中是第一个sheet中的数据,下方的是第二个sheet中的数据,我们大体上一看符合我们的预期,就说明我们之前的代码没有什么问题,我们就可以对$data中的数据进行关联并生成json数据了。

 iOS省市二级联动的数据组织PHP版

4.省市数据进行关联

上面我们已经将数据从excel中读取出来了,并且将量sheet中的数据存入了不同的数组,接下来我们将要对数据进行处理。该部分就是将省市的数据进行关联,也就是将两个sheet中的数据合并成一个数据块。下方就是我们要存储数据的一个结构图。整个是一个数组,数组中是一个字典,每个字典就代表一个省。每个省的字典又省编码code、省名name、所有市citys组成。citys中存储的又是一个数组。该数组中的每一项又是一个字典,此处的每个字典代表着一个市,每个市的字典中有包括市名name和市编码code。数据结构如下所示。

  iOS省市二级联动的数据组织PHP版

参考上图,我们要对读取的数据进行处理,将数据重新组织成上述结构。下方代码段就是对读取的excel表格中的数据进行重组。经过下方代码的处理我们就可以得到上述结构的数据了。下面的$alldataarray就存储的是所有的数据信息,$provincetempdata中暂存着每次省的所有信息,$currentprovincecitys中存储的就是当前省中所有市的信息。第二个循环中的if语句则负责管理省市间的关系了,具体代码以及代码注释如下所示。

iOS省市二级联动的数据组织PHP版

经过上面的代码我们所有的数据就会存入到$alldataarray中,上面对$alldataarray进行了json编码并输出,下方就是处理后输出的josn数据。在此我们以河北省为例。下图中的结构是与上面我们数据结构图一一对应的,这正是我们想要的数据。到此我们数据处理的任务就完成一大半了,因为我们得到了我们想要的json。

iOS省市二级联动的数据组织PHP版

5. 将上述json数据进行解析并存入plist文件

经过上述步骤,php的工作算是告一段落。接下来我们就是要使用ios客户端来访问上述地址,获取上述生成的json数据。获取到json数据后,我们将json数据进行解析,并存储到沙盒中的plist文件。这样我们就可以从plist文件中来加载我们的省市数据了。

下方代码段是我们的ios客户端的代码,该代码通过nsurlsessiondatatask来请求上述php代码所在的文件获取省市的json数据。请求到json数据后对数据进行解析,将json数据解析成数组后在通过nsfilemanager存储到沙盒中的plist文件中。如果你要在外部使用,只需要找到模拟器中的沙盒路径拷贝出plist文件即可。下方代码就是网络请求+json解析+plist文件存储的的代码。

iOS省市二级联动的数据组织PHP版

经过上述代码的执行,你会在你的模拟器中上述app的沙盒中发现一个叫province.plist的文件,该文件中存储的就是我们要使用的省市数据。该plist文件的数据存储结构是我们上面的介绍过的数据结构,下方就是该plist文件中数据的部分截图。至此我们就获得了一个按我们的预期存有省市数据plist文件了。

 iOS省市二级联动的数据组织PHP版

二、封装选择省市的pickerview的使用方式

封装当然不是简单的将pickerview的简单使用,在封装代码时我们要考虑到用户的易用性和可扩展性。在此我只对pickerview做了一个简单的封装,不过干货还是有的,主要是思想呢。经过上面一大模块的数据组织呢,我们就可以将之前服务端所给的excel文档中的数据组织成我们想要的plist数据。本部分所做的主题就是读取plist文件中的数据,将该数据显示在二级联动的pickerview上供用户选择。用户选择完成后返回用户选择的省市名以及省市所对应的编码。开始我们控件的封装。

1.所封装控件的目录结构

首先我们先整体的看一下我们所封装控件的目录结构是怎样的,先整体的了解一下我们这个封装的控件。下方截图中就是我们所封装控件的目录结构了,因为我们是对显示省市信息的uipikcerview进行的封装,所以在此我们称其为provincepickerview,provincepickerview就是我们所封装的组件了。用户只需要对其进行实例化并添加到其视图上就可以进行使用了。下方的province.plist数据就是我们上面所生成的存有省市信息是数据,我们provincepickerview中的数据源就是province.plist文件。

provincemodel就存储着当前选中的省市的名称以及编码,下面第二张截图就是provincemodel中的内容了。provincecode存储的是当前选中的省的编码,provincename存储的就是当前所选省的名称,citycode存储的是所选市的编码,cityname存储的是所选市的名称。具体代码如下所示。

iOS省市二级联动的数据组织PHP版

iOS省市二级联动的数据组织PHP版

2. 所封装控件的初始化以及调用方式

接下来我们看一下我们封装的这个provincepickerview的使用方式,使用起来还算简单。下方代码段就是provincepickerview初始化方式,将provincepickerview进行初始化然后添加到所要显示provincepickerview的视图上,然后设置provincepickerview对象的block回调。该回调会在用户点击provincepickerview上的完成按钮时执行,并返回当前用户选中的省市信息的model数据。

iOS省市二级联动的数据组织PHP版

上面是初始化provincepickerview,并且设置数据回调block。下方的代码段就是用来显示provincepickerview的,调用showpickerview方法就会在下方弹出provincepickerview,因为provincepickerview本身就有取消按钮,取消后就会自动收回provincepickerview,所以我们不需要为用户提供收回provincepickerview的方法,所以使用起来还是比较简单的。

iOS省市二级联动的数据组织PHP版

三、代码分享

由于博客篇幅有限,至于provincepickerview中封装的代码在此就不一一的往上粘贴了。说白了最核心就是对uipickerviewdelegate和uipickerviewdatasource两个代理中的相应的方法的封装。还有就是如何显示和隐藏pickerview,换一句话说,就是讲pickerview放在什么地方进行显示。有感兴趣的小伙伴可以从下方的github中分享的代码来自行分析呢。事无巨细,所以在此就不做过多的赘述了。

下方的代码截图就是在github上分享的部分代码,可以说是添加了详细的注释,有感兴趣的小伙伴可以进行自行阅读。代码中如有偏颇之处,还望指出。

iOS省市二级联动的数据组织PHP版

上述所有的代码都是使用截图的方式呈现的,这无关紧要,在博客的结尾会给出所有相关的代码,当然也包括上述的php代码,以及pickerview的具体实现呢。好了,由于博客篇幅有限,今天就先到这儿吧。下方就是本篇博客相关代码的分享链接。

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: