前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架。本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在《Swift3.0服务端开发(一)》这篇博客中已经简单的介绍过了,本篇博客就来详细的聊一下这个工程的具体实现细节。当然包括iOS端和服务端的代码。本篇博客的介绍顺序按照功能模块来划分的,如登录注册模块、记事本列表,记事本的增删改查等功能。在每个功能模块,我们先给出服务端代码的实现,然后给出客户端代码的实现。

本篇博客的前几部分主要介绍整个工程的公用模块,为工程的实现做准备,下方就是我们今天博客要做的东西。本篇博客iOS端的网络请求主要使用的NSURLSession来实现的,关于URLSession更详细的介绍请参考之前发布的博客《NSURLSession全家桶

  

一、记事本数据库的设计

数据库的设计以及数据库表的创建我都使用Sequel Pro来实现的,关于Sequel Pro的使用请看上篇博客的介绍,本篇博客关于Sequel Pro的介绍就不做过多赘述了。首先我们先给出记事本数据库表的设计,以备使用。我们先创建一个名为perfect_note的数据库(步骤略),然后再创建相应的数据库表。因为我们的记事本比较简单,主要包括登录、注册以及记事本的增删改查。所以我们的数据库结构也是比较简单的,perfect_note数据库中只有两个表,一个是user表,一个是content表,下方会给出详细的介绍过程。

1.user表的创建

首先我们来创建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。

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;

二、iOS端基于NSURLSession网络请求类的封装

创建完数据库后,接下来我们来封装iOS端网络请求的共用代码。也就是说,iOS端的网络请求就会调用本部分封装的内容。当然本部分封装的网络请求类是使用NSURLSession类封装的。

1.字符串常量、闭包回调类型以及枚举的定义

首先我们先来定义一些封装网络请求类要使用的字符串常量以及枚举闭包回调。下方代码段做的就是这件事情,第一个框中定义了解析响应数据时使用到的字符串常量。“SUCCESS”表示请求成功,“FAILE”表示请求失败等等。

第二个框中定义的是三个闭包变量,用来将请求结果回调给调用者。RequestStart就是开始请求要调用的闭包类型,RequestSuccess则是请求成功后调用的闭包类型,RequestFailed则是请求失败要调用的闭包类型。这三者是请求类对外交流的桥梁。

第三个框则是请求方式的枚举,主要包括GET、POST、PUT、DELETE,当然还留了CUSTOM()自定义的扩展类型。在该枚举中的description计算属性负责将当前的枚举对象转换成其对于的字符串,具体如下所示:

  

2、网络请求基类的创建

接下来网络请求的基类,所有与网络请求相关的类都要继承自此类,下方的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。

三、登录注册模块的开发

上面的基础工作完毕后,接下来我们就要来做我们相应的业务模块了。首先我们来进行登录注册模块的开发工作。 首先给出服务端相应模块的代码,然后在给出相应模块的iOS端的实现。关于Swift3.0连接和操作MySQL的详细内容请参考上一篇博客《Swift3.0服务端开发(四) MySQL数据库的连接与操作》,数据库的连接在本部分就不做过多赘述了。

1、服务端代码

(1)、登录或注册的第一步:接收用户名

下方代码是用户登录或者注册的第一步,通过用户名来查询用户信息,从而来判断该用户是否注册,如果未注册则去注册,如果注册过就去登录。如果查询成功,那么就将查询的用户ID和UserName返回给客户端。用户登录的代码和下方差不多,就是通过Select语句来匹配该用户名的密码是否与用户输入的一致,在此就不做过多赘述了。

  

(2)、用户注册

下方就是用户注册是调用的接口实现,主要是插入相应的用户信息,具体如下所示:

  

上面这些代码写完后,配置完相应的路由调用上述方法,我们的服务端代码就完成了。具体路由的配置因为篇幅有限,本篇博客就不做过多赘述了。

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

Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)的更多相关文章

  1. SpringBoot开发五-社区首页开发

    需求介绍-社区首页 根据之前的学习,我们一般都是先按照DAO->Service->Controller这个顺序去开发 分布实现: 开发社区首页,显示前十个帖子. 开发分页组件,分页显示所有 ...

  2. Swift3.0基础语法学习<五>

    异常处理: // // ViewController5.swift // SwiftBasicDemo // // Created by 思 彭 on 16/11/16. // Copyright © ...

  3. JavaEE开发之记事本完整案例(SpringBoot + iOS端)

    上篇博客我们聊了<JavaEE开发之SpringBoot整合MyBatis以及Thymeleaf模板引擎>,并且在之前我们也聊了<Swift3.0服务端开发(五) 记事本的开发(iO ...

  4. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  5. Swift3.0服务端开发(二) 静态文件添加、路由配置以及表单提交

    今天博客中就来聊一下Perfect框架的静态文件的添加与访问,路由的配置以及表单的提交.虽然官网上有聊静态文件的访问的部分,但是在使用Perfect框架来访问静态文件时还是有些点需要注意的,这些关键点 ...

  6. XData -–无需开发、基于配置的数据库RESTful服务,可作为移动App和ExtJS、WPF/Silverlight、Ajax等应用的服务端

    XData -–无需开发.基于配置的数据库RESTful服务,可作为移动App和ExtJS.WPF/Silverlight.Ajax等应用的服务端   源起一个App项目,Web服务器就一台,已经装了 ...

  7. app开发中如何利用sessionId来实现服务端与客户端保持回话

    app开发中如何利用sessionId来实现服务端与客户端保持回话 这个问题太过于常见,也过于简单,以至于大部分开发者根本没有关注过这个问题,我根据和我沟通的开发者中,总结出来常用的方法有以下几种: ...

  8. 国内物联网平台初探(五) ——机智云IoT物联网云服务平台及智能硬件自助开发平台

    平台定位 机智云平台是致力于物联网.智能硬件云服务的开放平台.平台提供了从定义产品.设备端开发调试.应用开发.产测.运营管理等覆盖智能硬件接入到运营管理全生命周期服务的能力. 机智云平台为开发者提供了 ...

  9. Dubbo入门到精通学习笔记(十二):Dubbo消费端直连提供者(开发调试)、Dubbo服务只订阅(开发调试)、Dubbo服务只注册

    文章目录 Dubbo消费端直连提供者(开发调试) Dubbo服务只订阅(开发调试) Dubbo服务只注册 Dubbo消费端直连提供者(开发调试) Dubbo 官方文档: 用户指南 >> 示 ...

随机推荐

  1. Size Balanced Tree(SBT) 模板

    首先是从二叉搜索树开始,一棵二叉搜索树的定义是: 1.这是一棵二叉树: 2.令x为二叉树中某个结点上表示的值,那么其左子树上所有结点的值都要不大于x,其右子树上所有结点的值都要不小于x. 由二叉搜索树 ...

  2. TextView 设置图片

    TextView 设置图片 2012-05-17 15:12:38|  分类: Android |  标签:android  textview图片  |举报|字号 订阅     Drawable im ...

  3. office加载项部署清单签名的证书或其位置不受信任

    异常信息: System.Security.SecurityException: 此应用程序中的自定义功能将不起作用,原因是用于为 BIMT写作指导 的部署清单签名的证书或其位置不受信任.请向管理员寻 ...

  4. js图片未加载完显示loading效果

    <html> <title>js图片未加载完显示loading效果</title> <body> <style> img{float:lef ...

  5. 求最长连续公共子序列 POJ 3080

    Description The Genographic Project is a research partnership between IBM and The National Geographi ...

  6. 不小心删掉root目录......

    1.先保存还剩下的的东西,比如说桌面的文件,保存在/下面其他目录 2.执行命令 cp -R /etc/skel/.[!.]* ./ 3.reboot

  7. javascript模拟鼠标双击事件

    通常我们在做开发的时候需要通过单击切换对立事件,简单做了一个模型. <!DOCTYPE html> <html> <head> <title>javas ...

  8. MFC中PeekMessage的使用,非阻塞消息循环

    在程序设计的时候经常要进行一个数据循环,比如播放音乐需要循环的向缓冲区里面写入数据,在这个时候比较通用的方法是建立一个线程做事情,但是有时候不想创建多线程就可以使用微软提供的PeekMessage方法 ...

  9. echarts 系列一

    由于近期项目需要做地图方便的可视化图标,经过比较最终选定echarts. echarts在可视化视图方面非常强大,可以满足大多数开发需求. 采用标签式引入js文件,引用的js 文件位置 echarts ...

  10. 安装php扩展后,执行时找不到扩展 class xxx no found

    当编译安装一个新的php扩展,例如安装redis, 安装后 执行 new Redis(), 如果发现找不到class Redis,可以先检查redis.so文件是否在php的扩展目录下, 如果发现是, ...