前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架。本篇博客就作一个阶段性的总结,作一个完整的实例,其实这个实例在《Swift3.0服务端开发(一)》这篇博客中已经简单的介绍过了,本篇博客就来详细的聊一下这个工程的具体实现细节。固然包括iOS端和服务端的代码。本篇博客的介绍顺序按照功能模块来划分的,如登陆注册模块、记事本列表,记事本的增删改查等功能。在每一个功能模块,咱们先给出服务端代码的实现,而后给出客户端代码的实现。html
本篇博客的前几部分主要介绍整个工程的公用模块,为工程的实现作准备,下方就是咱们今天博客要作的东西。本篇博客iOS端的网络请求主要使用的NSURLSession来实现的,关于URLSession更详细的介绍请参考以前发布的博客《NSURLSession全家桶》git
1、记事本数据库的设计github
数据库的设计以及数据库表的建立我都使用Sequel Pro来实现的,关于Sequel Pro的使用请看上篇博客的介绍,本篇博客关于Sequel Pro的介绍就不作过多赘述了。首先咱们先给出记事本数据库表的设计,以备使用。咱们先建立一个名为perfect_note的数据库(步骤略),而后再建立相应的数据库表。由于咱们的记事本比较简单,主要包括登陆、注册以及记事本的增删改查。因此咱们的数据库结构也是比较简单的,perfect_note数据库中只有两个表,一个是user表,一个是content表,下方会给出详细的介绍过程。数据库
1.user表的建立json
首先咱们来建立user表,user表负责存储用户信息,当用户注册和登陆时都会操做这个表。注册用户时就是往该表中插入用户,登陆时就是查询相应的用户信息。固然,为了Demo的简洁性,咱们的user表中的字段也是比较少的。下方就是建立user表的SQL语句。其中有四个字段,主键id是整型并且是自增的,是用户的惟一表示。username字段存储的是用户名,password存储的就是用户密码。register_date存储的是用户注册时间,是时间戳,而且默认值是当前时间。服务器
CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '', `password` varchar(30) CHARACTER SET latin1 NOT NULL DEFAULT '', `register_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
2.content表的建立网络
建立完user表后,接下来就要建立咱们的content表了。content表用来存储用户录入的笔记,下方就是content表的建立SQL语句。从下方的SQL语句中不难看出content表的字段包括自增的主键id,记录的标题title,记录的内容content,以及外键userID和建立时间create_time。session
CREATE TABLE `content` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(30) CHARACTER SET gb2312 NOT NULL DEFAULT '', `content` text CHARACTER SET gb2312 NOT NULL, `userID` int(11) unsigned NOT NULL, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `USER_FOREIGN_KEY` (`userID`), CONSTRAINT `USER_FOREIGN_KEY` FOREIGN KEY (`userID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
2、iOS端基于NSURLSession网络请求类的封装闭包
建立完数据库后,接下来咱们来封装iOS端网络请求的共用代码。也就是说,iOS端的网络请求就会调用本部分封装的内容。固然本部分封装的网络请求类是使用NSURLSession类封装的。框架
1.字符串常量、闭包回调类型以及枚举的定义
首先咱们先来定义一些封装网络请求类要使用的字符串常量以及枚举闭包回调。下方代码段作的就是这件事情,第一个框中定义了解析响应数据时使用到的字符串常量。“SUCCESS”表示请求成功,“FAILE”表示请求失败等等。
第二个框中定义的是三个闭包变量,用来将请求结果回调给调用者。RequestStart就是开始请求要调用的闭包类型,RequestSuccess则是请求成功后调用的闭包类型,RequestFailed则是请求失败要调用的闭包类型。这三者是请求类对外交流的桥梁。
第三个框则是请求方式的枚举,主要包括GET、POST、PUT、DELETE,固然还留了CUSTOM()自定义的扩展类型。在该枚举中的description计算属性负责将当前的枚举对象转换成其对于的字符串,具体以下所示:
二、网络请求基类的建立
接下来网络请求的基类,全部与网络请求相关的类都要继承自此类,下方的BaseRequest就是咱们网络请求的基类。该类比较简单,主要声明了上面定义的三个闭包类型的变量,而后给出了相应的构造器。具体以下所示。
3.网络请求类的封装
接下来咱们使用NSURLSession来封装咱们的网络请求类,下方的Request类就是咱们封装的网络请求类,该类继承自BaseRequest。下方是Request的部分代码,下方每一个方法对应着GET、POST、PUT等请求,能够结合者REST一块儿使用。在每一个具体请求的方法中会调用sessionDataTaskRequest()方法。会给这个方法传入不一样的请求方式以及路径和参数。稍后咱们会给出sessionDataTaskRequest()方法的具体实现,sessionDataTaskRequest()方法其中就使用了NSURLSession相关的内容发起了网络请求,具体请看下方对sessionDataTaskRequest()方法的详细介绍。
下方这个代码段就是sessionDataTaskRequest()方法的总体结构,首先咱们根据函数的请求路径和参数拼接URL字符串,也就是第一个框中的部分。在该部分中的query()函数是将参数进行URL编码转换,这个函数是从AlamoFire框架中摘过来的。而后建立请求用的URLRequest对象。最后是建立Session对象发起DataTask任务了。固然请求的结果是在completionHandler闭包中进行处理,稍后会给出completionHandler闭包中的处理方式。
接着,咱们给出请求成功后,对json数据的解析以及对返回结果的处理。下方就是completionHandler闭包中的代码片断。首先对服务器返回的json数据进行解析,解析后将json数据转换成对应的数据类型。而后根据响应报文的result字段来进行相应的操做。若是报文响应正常,就调用success()闭包,不然调用failure()闭包,以下所示:
至此咱们iOS客户端的网络请求部分就封装完了,其余具体业务逻辑的网络请求调用上述的Request类便可,稍后会用到Request。
3、登陆注册模块的开发
上面的基础工做完毕后,接下来咱们就要来作咱们相应的业务模块了。首先咱们来进行登陆注册模块的开发工做。 首先给出服务端相应模块的代码,而后在给出相应模块的iOS端的实现。关于Swift3.0链接和操做MySQL的详细内容请参考上一篇博客《Swift3.0服务端开发(四) MySQL数据库的链接与操做》,数据库的链接在本部分就不作过多赘述了。
一、服务端代码
(1)、登陆或注册的第一步:接收用户名
下方代码是用户登陆或者注册的第一步,经过用户名来查询用户信息,从而来判断该用户是否注册,若是未注册则去注册,若是注册过就去登陆。若是查询成功,那么就将查询的用户ID和UserName返回给客户端。用户登陆的代码和下方差很少,就是经过Select语句来匹配该用户名的密码是否与用户输入的一致,在此就不作过多赘述了。
(2)、用户注册
下方就是用户注册是调用的接口实现,主要是插入相应的用户信息,具体以下所示:
上面这些代码写完后,配置完相应的路由调用上述方法,咱们的服务端代码就完成了。具体路由的配置由于篇幅有限,本篇博客就不作过多赘述了。
二、iOS客户端代码实现
接下来咱们来实现iOS客户端的登陆和注册的代码,下方就是登陆或者注册的相关UI。用户输入用户后,点击下一步,会调用后台接口判断用户是否注册过,若是已注册输入密码登陆,若是未注册就输入密码注册和登陆。右边的UIViewController是共用的,两个页面,一个让用户输入用户名,一个则负责接收密码。UI比较简单,以下所示:
看完UI, 咱们来看一下登陆或注册的相关网络请求的代码。下方的UserInfoRequest类就负责全部与用户信息相关的网络请求,从下方的代码截图中,咱们能够看到UserInfoRequest的基类是BaseRequest。下方的queryUserInfo(userName)就是上面左边的页面所调用的方法,用来判断该用户是不是注册过的用户。在queryUserInfo()中对Request类进行了实例化,而且调用了相应的请求方法。而且对相应的事件回调作了处理,具体以下所示。
在咱们相应的ViewController中会调用上述的方法,下方就是用户在输入相应的用户信息后点击next所调用的方法。经过相应的闭包事件,最终将网络请求的结果回调到了VC中。
至此咱们iOS客户端的登陆就实现完毕了。 其余的代码和上面的思路相似,在此就不作过多赘述了。
本篇博客,就先到这儿吧,其余代码和上述的思路一直,按照上述的思路去实现笔记的增删改查便可,在此就很少废话了。完整Demo请移步github相关连接。
github分享连接: https://github.com/lizelu/PerfectDemo