当前位置: 首页 > 新闻 > 信息荟萃
编号:3862
ios企业级应用开发技术.pdf
http://www.100md.com 2020年3月18日
第1页
第5页
第14页
第30页
第37页
第52页

    参见附件(6092KB,261页)。

     ios企业级应用开发技术是作者和凌志写的关于ios开发的书籍,主要讲述了ios基础知识,App与服务器接口的定义,Block的应用,javascript基础知识等等内容。

    ios企业级应用开发技术内容提要

    本书聚焦在APP“产品”的设计、开发和运营层面,特别强调架构和设计模式的重要性,有意识地将设计模式应用到代码的编写中,重点介绍iOS企业级应用开发的设计思维方式,并与全栈开发技术结合起来。 全书分为iOS基础篇、Web与Native混合开发模式篇和全栈开发技术篇。iOS基础篇主要介绍iOS基础知识、多种设计模式下的视图控制器之间的传值、App与服务器接口的定义、CollectionView的应用;Web与Native混合开发模式篇主要介绍Block的应用、iOS网络请求、JavaScript基础、Web与Native的交互;全栈开发技术篇主要介绍Node.js、Express、AngularJS、MongoDB、MEAN全栈技术的实现。

    作者简介

    和凌志,客座教授,工信部人才交流中心认证讲师;拥有十多年移动互联网开发经验,先后在 Siemens Mobile、 Flextronics 等欧美公司担任手机软件架构师。2014年, 为北京高校录制慕课“iOS企业级应用开发技术”。近几年,专注于全栈技术开发, 代表产品有“点时”APP ――轻量级知识分享平台。

    目录

    iOS基础篇

    第1章 iOS基础知识

    1.1 Objective-C语法简介

    1.1.1 Objective-C的奇特之处

    1.1.2 如何声明一个实例变量

    1.1.3 Objective-C字符串

    1.2 Objective-C的对象类型与基本数据类型

    1.2.1 对象类型与基本数据类型的混合使用

    1.2.2 对象类型与基本数据类型的转换

    1.3 不可变数组与可变数组

    1.3.1 不可变数组(NSArray)的特征

    1.3.2 可变数组(NSMutableArray)的特征

    1.3.3 如何遍历数组中的对象

    1.3.4 NSArray与NSMutableArray的应用

    1.4 不可变字典与可变字典

    1.4.1 不可变字典(NSDictionary)

    1.4.2 可变字典(NSMutableDictionary)

    1.4.3 如何遍历字典中的对象

    1.4.4 NSArray与NSDictionary的应用

    1.4.5 创建类的对象

    1.5 iOS应用程序概述

    1.5.1 应用程序的入口

    1.5.2 应用程序委托(AppDelegate)

    1.5.3 UIApplication应用场景

    1.5.4 一种简单的永久数据存储方式

    1.6 iOS定制化控件

    1.6.1 定制化View的创建

    1.6.2 小标签(UILabel),大用场

    1.6.3 如何实现输入框随键盘上移

    1.7 视图的层级管理

    1.7.1 创建视图的方法

    1.7.2 如何从父视图中移除子视图

    1.7.3 登录页面的实现

    1.8 iOS编程规范

    1.8.1 代码的可维护性

    1.8.2 面向对象的编程思想

    1.8.3 优先编写轻量级的

    1.9 小结

    第2章 视图控制器之间的传值

    2.1 通过Delegate实现ViewController之间的传值

    2.1.1 Delegate概述

    2.1.2 学习Delegate的困惑

    2.1.3 从一道经典的面试题说起

    2.1.4 学习Delegate常出现的几个误区

    2.1.5 Delegate技术难点在哪里

    2.1.6 数据逆向传送一定要通过Delegate吗

    2.1.7 Delegate应用五步曲

    2.1.8 Delegate优势

    2.2 通过单例实现ViewController之间的传值

    2.2.1 单例的创建

    2.2.2 单例的初始化

    2.2.3 单例设计模式的本质

    2.2.4 通过单例实现传值

    2.2.5 单例模式在登录模块中的应用

    2.2.6 单例模式的优势

    2.3 通过KVO实现ViewController之间的传值

    2.3.1 什么是

    2.3.2 什么是

    2.3.3 KVO的特点

    2.3.4 使用KVO的步骤

    2.3.5 KVO的实现方法

    2.3.6 KVO应用注意事项

    2.4 通过NSNotification实现ViewController之间的传值

    2.4.1 NSNotification的定义

    2.4.3 发出通知

    2.4.4 接收通知

    2.4.5 移除通知

    2.4.6 异步模式下的通知操作

    2.4.7 通过NSNotification实现ViewController之间的传值

    2.4.8 NSNotification与Delegate的区别

    2.4.9 监听系统自带的

    2.5 小结

    第3章 App与服务器接口的定义

    3.1 关于JSON的认识

    3.2 App与服务器接口的定义

    3.2.1 App与后台的接口设计

    3.2.2 后台返回的数据格式

    3.2.3 后台返回的提示信息

    3.3 JSON与Model的转换

    3.3.1 JSONModel常见的用法

    3.3.2 JSONModel的几个属性用法

    3.4 小结

    第4章 CollectionView的应用

    4.1 CollectionView与TableView孰优孰劣

    4.1.1 TableView的应用场景

    4.1.2 CollectionView的应用场景

    4.1.3 CollectionView与TableView概念对比

    4.1.4 CollectionView与TableView的性能对比

    4.2 什么是

    4.3 实现一个简单的

    4.4 UICollectionViewCell视图层级

    4.6 关于Cell的重用

    4.9 实现一个简单的瀑布流

    4.9.1 通过手动编码创建

    4.9.2 直接拖曳一个

    4.9.3 基于Xib创建一个

    4.10 自定义瀑布流的应用场景

    4.11 自定义Flow Layout进行瀑布流布局

    4.11.1 自定义瀑布流的应用场景

    4.11.2 自定义瀑布流的实现思路

    4.11.3 创建自定义的

    4.11.4 创建自定义的

    4.11.5 关于initWithFrame:方法的使用

    4.11.6 自定义瀑布流的完整实现

    4.11.7 UICollectionView相关的类图

    4.11.8 如何实现UICollectionView的轮播

    4.12 CollectionView与TableView的区别

    4.13 图片轮播的实现思路

    4.14 CollectionView注意事项

    4.15 小结

    Web与Native混合开发模式

    第5章 Block的应用

    5.1 Block缘起

    5.2 Block概述

    5.3 Block的声明、实现与调用

    5.3.1 Block的声明

    5.3.2 Block的实现

    5.3.3 Block的调用

    5.3.4 Block外部变量的访问

    5.4 Block的应用场景

    5.4.1 Block用于

    5.4.2 Block声明为实例变量

    5.5 通过Block实现视图控制器之间的逆向传值

    5.5.1 应用场景

    5.5.2 代码实现

    5.6 小结

    第6章 iOS网络请求

    6.1 iOS网络请求概述

    6.2 AFNetworking的应用

    6.2.1 AFNetworking概述

    6.2.2 AFNetworking框架使用方法

    6.2.3 影响网络请求的几个条件

    6.2.4 善用URL宏定义

    6.2.5 URl接口应统一管理

    6.2.6 AFNetworking的二次封装

    6.3 AFNetworking的序列化问题

    6.3.1 AFNetworking请求格式

    6.3.2 AFNetworking响应格式

    6.4 异步请求数据并刷新UI页面

    6.5 远程文件

    6.5.1 基于AFNetworking的文件

    6.5.2 基于NSURLSession的文件

    6.5.3 网络安全访问设置

    6.6 小结

    第7章 JavaScript基础

    7.1 JavaScript语法

    7.2 变量的声明与赋值

    7.3 如何判断两个字符串是否相等

    7.4 创建JavaScript对象的三种方法

    7.5 函数声明与函数表达式

    7.6 可立即调用的函数表达式

    7.7 循环的实现

    7.8 防止JavaScript自动插入分号

    7.9 严格模式

    7.10 如何运行与调试JavaScript代码

    7.10.1 把JavaScript代码内嵌到HTML页面中

    7.10.2 通过Node.js运行JavaScript代码

    7.11 JavaScript的面向对象设计思想

    7.12 JavaScript的异步编程模式

    7.12.1 Promise对象

    7.12.2 生成Promise实例对象

    7.12.3 Promise原型方法

    7.12.4 Promise的catch方法

    7.13 如何在HTML中嵌入

    ios企业级应用开发技术截图

    更多精彩尽在www.sxpdf.com更多精彩尽在www.sxpdf.com

    内 容 简 介

    本书聚焦在 App“产品”的设计、开发和运营层面,特别强调架构和设计模式的重要性,有意识地将设

    计模式应用到代码的编写中,重点介绍iOS企业级应用开发的设计思维方式,并与全栈开发技术结合起来。

    全书分为 iOS 基础篇、Web 与 Native 混合开发模式篇和全栈开发技术篇。iOS 基础篇主要介绍 iOS 基础

    知识、多种设计模式下的视图控制器之间的传值、App与服务器接口的定义、CollectionView的应用;Web与

    Native 混合开发模式篇主要介绍 Block 的应用、iOS 网络请求、JavaScript 基础、Web 与 Native 的交互;全栈

    开发技术篇主要介绍Node.js、Express、AngularJS、MongoDB、MEAN全栈技术的实现。

    本书适合从事iOS开发的人员,以及有一定iOS基础、想学习全栈技术的人员阅读。

    源码下载地址:https:github.comleopard168iOS-Enterprise。

    未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。

    版权所有,侵权必究。

    图书在版编目(CIP)数据

    iOS企业级应用开发技术

    和凌志著. — 北京:电子工业出版社,2017.10

    ISBN 978-7-121-32828-2

    I.①i… II.①和… III.①移动终端-应用程序-程序设计 IV.①TN929.53

    中国版本图书馆CIP数据核字(2017)第244091号

    责任编辑:田宏峰

    印 刷:

    装 订:

    出版发行:电子工业出版社

    北京市海淀区万寿路173信箱 邮编:100036

    开 本:787×980 116 印张:16.25 字数:366千字

    版 次:2017年10月第1 版

    印 次:2017年10月第1 次印刷

    定 价:68.00元

    凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。若书店售缺,请与本社发行部联系,联

    系及邮购电话: (010)88254888,88258888。

    质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件至dbqq@phei.com.cn。

    本书咨询联系方式:tianhf@phei.com.cn。

    更多精彩尽在www.sxpdf.com

    III

    序

    认识和凌志先生,是在2013 年。

    在那一年,北方工业大学计算机学院新增了新的数字媒体技术实验室,作为学生创新、创

    业、企业实训培养基地,为学生提供了更好的设计与开发实验环境。为了进一步激发学生的学

    习兴趣,促进产学研的结合,同时紧跟技术发展趋势,我们开设了一门基于移动终端的互联网

    课程,聘请经验丰富的和凌志先生讲授“iOS 企业级应用开发技术”。

    和凌志早期担任西门子手机软件平台架构师,近十多年来,一直从事移动互联网的产品开

    发工作,在电商平台、移动流媒体方面,积累了丰富的行业经验。他把这些宝贵的企业经验应

    用在了教学实践中。早在开课之前,和凌志就已经完成了《iOS开发之美》一书,该书通俗易

    懂,很适合初学者快速上手。

    为了给学生创造一个更好的学习条件,我们与北京高校计算机信息类专业群合作,特意录

    制了 iOS开发的 MOOC(慕课)视频课程,从Objective-C编程语言、表视图,到网络请求、数据存储,都给出了详细的实例。

    与市面上已有的 iOS 参考书不同的是, 《iOS 企业级应用开发技术》一书聚焦在“产

    品”的设计、开发和运营层面。所谓企业级应用,指开发出来的产品是可上线、可运营

    的,而不是仅仅用来演示的,而且企业级应用还要考虑开发周期、研发成本、运行和维

    护的投入。

    书中特别强调架构和设计模式的重要性,坚持倡导一个理念:“在一个给定的场景下,最

    佳方案只有一个”。比如,在讲述视图控制器之间的传值时,先后列举了五种不同的实现方案,对比不同的方案,给出相应的应用场景;在讲述 Web 与 Native 交互时,给出了多个应用实例;

    类似的场景还有很多。

    从书名上看,《iOS 企业级应用开发技术》的主题是在讲述 iOS 开发技术,但作者并没有

    仅仅停留在 iOS 开发本身,而是延伸到“全栈(Full Stack)”技术路线上。以 Node.js 为平台

    的全栈技术越来越受到互联网公司的热捧。

    当下,我们正处于共享经济的时代,知识分享也日益成为一种时尚。通过尝试校企合作,更多精彩尽在www.sxpdf.com

    IV

    从适应技术发展的角度提升学校课程设置使之与社会需求紧密结合, 为学生在校期间掌握前沿

    技术提供一种良好手段,为毕业后走向社会打下扎实的技术基础。

    马 礼

    北方工业大学计算机学院院长

    更多精彩尽在www.sxpdf.com

    V

    前 言

    缘起

    为何要写一本《iOS企业级应用开发技术》的书?这还得从我的工作经历说起。

    早在 2014 年,北方工业大学计算机学院就创建了数字媒体技术实验室,并为此配备了国

    内一流的实验设备。在过去的几年,我一直为学生们讲授“iOS企业级应用开发”课程,本书

    记录了学生实战的心路历程。

    本书成稿历经两年,其间几易其稿。在这个过程中,北方工业大学计算机学院的学生和老

    师,都给我了很多无私的帮助。每次审视这些教学案例,都会得到一次技术上的升华。在本书

    出版之前,初稿曾在北方工业大学计算机学院试用,在整个教学过程中,我为学生们在课堂上

    勇于“质问”的精神点赞。

    北方工业大学计算机学院数字媒体技术实验室

    读者对象

    本书所面向的读者对象是有一定 iOS 基础的开发者。如果你是第一次接触 iOS 开发,建

    议还是翻阅一下笔者的拙作——《iOS 开发之美》。

    更多精彩尽在www.sxpdf.com

    VI

    既然书名命名为“iOS 企业级应用开发技术” ,说明它不是一本泛泛的 iOS 基础的普及,相反,本书所关注的是,在企业项目开发中碰到疑难杂症时,如何开具良方,对症下药。

    具体来说,这本书适宜的读者有:

    (1)想学习Objective-C 2.0 编程语言的初学者。

    过去的几年,几乎每年的 WWDC 开发者大会,苹果公司都会隆重地推广 Swift 语言,但

    现实情况是,在 iOS企业级应用开发中,Objective-C依然是主流。

    作为一门编程语言,Swift 还在处于不断的更新中,从早期的 1.0,发展到今天的 3.0,可

    见其变化之大。从另一个角度来讲,说明它还存在不稳定性。

    本书的所有实例,都是基于 Objective-C 2.0 编写的。尽管 Objective-C 与 Swift 都是基于

    Xcode 进行开发的,从设计模式上讲,它们有异曲同工之妙;但从编程风格上讲,二者的差异

    还是蛮大的。

    (2)有了一定的 iOS基础,想扩展iOS知识面的。

    就 iOS 技能而言,本书花了大量篇幅介绍:不同设计模式下的视图控制器之间的传值;

    对表视图(UITableView)一笔带过,而对集合视图(UICollectionView)则通过多个维度

    来演练,这是因为在笔者看来,表视图是 iOS 的基础控件,而在其之上,才是集合视图;

    还有 Block(块)——这个令初学者感到望而生畏的地方;网络请求、断点下载,都在本书

    中娓娓道来; 在构建企业级应用时, 混合开发模式越来越受到青睐, 书中详细讲述了 Native

    与 Web 的交互。

    (3)已经在iOS领域久经沙场,想学习“大前端” 、 “全端”及“全栈”的。

    随着 App 多年的发展,App 的优势和短板日益明显,原生技术无法解决的问题,需要前

    端技术(HTML5)来弥补,二者才能相得益彰,所以混合开发模式越来越受欢迎。

    常听到有人感叹,iOS App 的用武之地没有想象得那么广阔,即使不转型,也想再扩展一

    下自己的技术路线。从产品形态上看,iOS App 也属于前端范畴,这里,笔者给出的建议是学

    点前端技术,掌握点 JavaScript,向“全栈”进军。

    如果一个 App 开发工程师同时具备了原生与全端的技能,由“单翼”变成了“双翼” ,其

    技术路线的前景将变得越来越广阔。

    如何阅读本书

    作为一门 iOS 企业级应用开发技术,其蕴含的知识点无疑有多个方面。本书的特点是,针对同一个应用场景,用不同的方案来实现它,经过演绎推理,得出一个结论——在给定的场

    景下,最佳方案只有一个!

    本书分为iOS基础篇、Web与 Native混合开发模式、全栈开发技术。

    更多精彩尽在www.sxpdf.com

    VII

    (1)iOS 基础篇。

    就 iOS 技能而言,本书先介绍了 Objective-C 语法,再过渡到定制化视图的创建和管理,以及 App 与服务器接口的定义。此外,本篇还有两个重要部分。

    视图控制器之间的传值:总结以往的项目经验,我们发现,视图控制器之间的传值是必不

    可少的,而且实现的方式有多种。在同一个项目中,对同一类问题的解决会出现多个“门派”,如果不统一约定,后期维护将非常被动。为便于理解,这里给出了同一个场景下的4 种实现方

    案(Delegate、Singleton、KVO、Notification),还有一种 Block 实现方式,放在了混合开发模

    式中讲解。以上实现方案,每一种方法的背后都有一种设计模式的支撑。只有掌握了设计模式,才能更好地理解和融会贯通。

    集合视图的应用:我们没有讲述传统的表视图,而是聚焦在集合视图(UICollectionView)

    上,旨在说明,如要构建一个华丽的 UI 页面,就要善用集合视图。通过自定义的

    UICollectionViewLayout,可以轻松地实现一个瀑布流,而这种瀑布流效果是表视图所无法比

    拟的。为了能够掌握集合视图的应用,书中给出了大量的实例。

    iOS的基础知识是没有穷尽的,只要掌握了核心的实现模式,其他的便迎刃而解,正所谓

    “一叶知秋”!

    (2)Web 与Native混合开发模式。

    当我们面向企业级 App 开发时,需要用一种产品设计的思路来引导学习技术路线,而不

    是仅仅停留在 iOS 知识本身。之所以采用 Web与 Native 混合开发模式,是因为iOS 原生开发

    有着明显的短板,而 Web(HTML5)为产品的推广带来了新的生命力。从 Web 技术的角度来

    看,总是希望有一种方法能够取代Native(原生) ,事实上,这种趋势也越来越明显。

    具体到本篇内容,分为Block的应用、网络请求、JavaScript 基础、Web与 Native 的交互,这四部分并不是独立的,而是通过一条主线贯穿在一起的。

    本质上讲,Web与 Native的交互是 Web 与 Native技术的融合。没有网络请求,Web无从

    谈起。而 iOS 的网络请求,必然用到 AFNetworking;既然是网络请求,就会用到异步调用,回调和 Block 是异步处理机制的基础,所以才出现了 Block和网络请求两章。

    从 iOS 自身技术来讲,似乎 Web 加载再简单不过了,不就是调用一个 UIWebView吗?其

    实,技术水平的差异就体现在这个缝隙地带。我们是否具备 Web 的基础技能呢?是否懂得一

    些 JavaScript呢?这些知识看似与iOS无关,实际上它们是密不可分的。如果 iOS 开发者不懂

    得 JavaScript,那么在涉及 Web 与 Native 交互时,沟通将会很吃力,以至于影响到产品开发的

    进度和团队的合作效率。

    从技术层面上讲,Web 与 Native 的交互方式有多种,尽管苹果公司推出的

    JavaScriptCore.framework 已有多年,但在项目开发中,还是有人在用传统的HTTP特殊字符拦

    更多精彩尽在www.sxpdf.com

    VIII

    截方式。虽然也能满足项目的需求,殊不知,一个过时的框架技术,会对产品后期的维护埋下

    太多的坑。

    本篇讲到的JavaScript基础,目的是指出,相比其他编程语言,JavaScript有什么特别之处。

    Web 与 Native 的交互,重点在讲述网页与 iOS 之间的相互调用。具体来说,Objective-C

    如何调用 JavaScript,反之,JavaScript 又如何调用 Objective-C。而它们相互调用的桥梁是

    JavaScriptCore.framework,前期的 Block概念在这里得到充分的应用。

    (3)全栈开发技术。

    iOS 开发者在经历几年的积淀之后,常常会产生一种莫名的困惑,未来的技术路线何

    去何从?尽管 iOS SDK 博大精深, 但作为一个 App 开发者来说, 并没有那么多金矿可挖。

    历经十年的发展, iOS 的第三方框架已非常成熟, 如果你的工作仅仅是为了开发一个 App,随着时间的推移,对技术路线的方向会愈发渴望。这个时候,有必要停下来,仔细规划

    一下了。

    学无止境!问题是该怎么学。摆在 iOS 开发者面前的有两个选择:先熟悉 Objective-C,再向 Swift 深入,这是一种纵向学习方法,试图将 iOS开发进行到底,这种方法适合开源框架

    的打造者, 紧跟 Apple 技术更新的步伐; 还有一种学习方法——横向发展, 不仅掌握iOS技能,还需要扩展羽翼,学习更多的知识。IT 知识如同浩瀚的海洋,该如何撷取一朵适合自己发展

    的浪花呢?我们先来看看 iOS App 的生态环境,或许从中能得到答案。

    无论是iOS还是Android, App原生开发模式的最大弊端是版本的迭代与升级的任务繁重。

    为了解决这个问题, 才引入了 HTML5技术。 移动互联网产品, 从产品形态来看, 分为 iOS App、Android App、微信公众号(小程序) 、后台管理页面、数据管理等;从开发的技术工种来看,分为 App(iOS、Android)工程师、前端工程师、后端工程师;从广义层面来看,App 也是前

    端的一种展现形式,App 开发离不开 Web 技术。从某种意义上说,前端=App+JavaScript。作

    为 iOS App 开发者,一旦掌握了 JavaScript,其技术路线的前景瞬间开阔了很多,而前景的方

    向就是“全栈技术”路线。

    一个偶然机会,我接触到了全栈(Full Stack)的概念,并瞬间被它的理念所吸引。这里

    说的全栈,不是传统的 LAMP(Linux、Apache、MySQL、PHP) ,而是一种全新的以前端为

    主导的框架,所谓“大前端” 、 “全端” ,指的是以前端为核心的框架。最终,我把框架选型聚

    焦在 MEAN(MongoDB、Express、AngularJS、Node.js)上。MEAN 全栈技术框架所用到的

    每个组件(MongoDB、Express、AngularJS和 Node.js)都是基于JavaScript 语言开发的,原本

    JavaScript是为网页设计的语言, 但自从有了Node.js之后, 前端工程师也可以写后台了。 Node.js

    让前端开发像子弹一样飞!

    选用 MEAN 全栈技术,可以快速地实现开发,尤其是到了产品的运营阶段,其优势表现

    得非常明显。我们知道,今天的任何一款移动互联网产品,都离不开微信公众号的推广,大多

    更多精彩尽在www.sxpdf.com

    IX

    出彩的产品,在它的微信公众号内,所展示的是一套完整的业务逻辑,而不是几个简单的页面。

    这就是说,一个运营成功的产品,越来越倚重于全栈技术。

    为此,本书在后半部分引入了全栈技术开发,从而进入全栈开发的世界。

    全栈技术包括后台与前端。一说到服务器端开发,自然想起 Java、.Net、PHP,不过,近

    几年来,Node.js 风生水起,如果你想学习一门更具前沿技术的服务器端开发平台,Node.js 是

    一个不错的选择。

    尽管 Node.js 自身已足够强大,但其生态系统的构建还要借助于 Express、AngularJS、MongoDB以及模板引擎。既然 Express 是基于 Node.js 之上的后端框架,对初学者来说,借助

    Express框架更容易快速上手。

    前端框架,本书选用了AngularJS。在吹响全端号角的今天,我们越来越强调前端框架的重要

    性。在前端的世界,AngularJS可谓“玉树临风” 。在MEAN全栈中,Node.js和Express负责后端

    处理,而与网页交互的正是AngularJS,因此,可以想象AngularJS在前端框架地位之高。

    把 MongoDB数据库应用到 MEAN 全栈中,可谓相得益彰。通过 MongoDB,你对全栈开

    发会有一个完整的、全新的认知。

    学习一门编程技术,最有效的途径还是实践。对于书中出现的每个知识点,都辅以相关的

    代码实例。书中的实例不是独立的,而是贯穿了整个全栈的技术点。

    践行全栈之路

    用了 MEAN全栈,它到底能带来什么好处呢?这里,以我们发布的一款产品——“点时”

    App 为例。“点时”是一款轻量级的知识分享平台,内容以语音为主。这样的一款产品,从生

    态上讲,包括 iOS App、Android App、微信、后台的课程发布与运维管理。传统的做法是项目

    开发组分为前端与后台两套人马,要么前端等后端,要么后端等前端,而我们采用了 MEAN

    全栈架构,不再区分前端与后台,开发效率明显提升。借助 MEAN 全栈框架,它带来的最大

    好处是减少了前后端之间的依赖,App 开发工程师可以通过全栈技术实现一次华丽的转身!

    本书的源码

    在学习本书示例代码时,可以按照书中讲解的步骤,一步一步地手工敲入所有代码,也可

    以下载随书所带的源码。本书所有的源代码都可以从 GitHub 下载。

    源码下载地址:https:github.comleopard168iOS-Enterprise。

    勘误和支持

    我尽最大的努力确保正文和代码没有错误,但随着开发环境版本的变化,错误在所难免。

    更多精彩尽在www.sxpdf.com

    X

    如果读者发现书中的任何错误,例如错别字或代码片段无法运行等,希望您能及时反馈给我。

    您提交的勘误不仅能帮助自己,还能让其他读者受益。

    读者可以在下载源码的地方 (GitHub) 进行反馈, 也可以通过下面的联系方式与笔者沟通。

    致谢

    参与本书编写的还有林志红、尹陆军、张俊、马钧君、和凌群、高宁、刘晓波、牛雪峰。

    在本书成稿的过程中, 得到了很多人的指点和帮助。 这里, 特别感谢北方工业大学计算机学院,从学生到老师,都给我了很多的支持与帮助,每次审视这些教学案例,都会在技术上得到一次

    升华。

    在本书出版之前,初稿曾在北方工业大学计算机学院试用。在整个教学过程中,学生们提

    出的很多疑惑,都在本书中得到诠释。

    这里,特别感谢北方工业大学计算机学院院长马礼教授在百忙中抽出时间为本书作序。

    感谢电子工业出版社,正是你们卓有成效的工作使我保持了敲击代码的激情。

    作者交流方式

    作者的 QQ:2385911707@qq.com。

    作者的微信号:leopard2385911707。

    作 者

    2017 年9 月

    更多精彩尽在www.sxpdf.com

    XI

    我的 iOS授课经历

    在过去的几年,我为北方工业大学计算机学院的大四学生讲授过几期 iOS 课程,在听课

    前,学生们已经具备了一定的编程基础,如 C、Java 语言等。每次开课都是从iOS 入门讲起。

    每学期结束后,我都会对自己的教学心得稍做总结,感触颇深。

    初学者习惯于敲击代码,对设计模式没有多大兴趣。

    每当讲到代码部分,大家都容易理解,尤其是敲击代码阶段,轻车熟路。而让人感到困惑

    的是,一旦涉及 Storyboard 中的对象拖曳,瞬间一片茫然。仿佛对象的拖曳是天外来客,难道

    作为一名程序员,就一定要比拼代码量吗?

    我们习惯于大谈特谈软件的设计模式,但又有多少人会有意识地将设计模式应用到自己编

    写的代码中呢?不错,MVC(Model-View-Controller)设计模式是最为主流的设计模式之一。

    如果真正领悟了 MVC 设计模式,就不会对 Xcode 拖曳对象感到别扭,相反,你会为这种

    Ctrl-Drag 操作而叫绝。这是因为,MVC 设计思想在 Xcode平台上表现得淋漓尽致!

    对于软件开发者来说,MVC 设计模式是极其重要的。如果不善用 MVC,软件的后期维

    护将变成一场灾难。

    从事软件开发的人都有这样的经历,很不习惯维护别人的代码。也就是说,代码的可维护

    性着实让人头疼。在我的工作中,需要经常走查他人编写的代码。最不想看到的是,代码中有

    通篇的、莫名的数字。对于 App 开发者来说,看到大量的控件坐标会着实令人不解。通过代

    码创建自定义的视图,会充斥大量的坐标数字。这是因为,创建一个视图(按钮、标签、编辑

    框),至少需要设置它的左上角(原点)的坐标,还有其宽度和高度。这样的代码,如果让别

    人来维护,简直让人抓狂!

    如果善用MVC 设计模式,这些痛苦将会迎刃而解!

    MVC 中的 V(View)- C(Controller)关系,完美地体现在了 Storyboard 的对象拖曳上。

    如果真正理解了 MVC 的设计精髓,就不会为对象的拖曳操作而烦恼。对一个 App 来说,主要

    解决这样几个问题:页面(视图)的展示、页面(场景)的跳转和数据的交互。可以说,App

    的开发,大部分的工作量都花在了页面的布局上。对于像App 这类 UI产品,我们自然希望有

    这样的一个可视化开发平台,做到所见即所得,需要哪个控件,就拖曳哪个控件,再根据产品

    更多精彩尽在www.sxpdf.com

    XII

    的设计要求,对页面上的控件进行布局。这样一来,通过简单的拖曳操作,一个完整的页面便

    会跃然纸上。回头一想,Xcode 不就是我们所期望的那个图形化开发平台吗?

    在 Storyboard 或 Xib 上,拖曳一个对象(控件) ,从本质上讲,这个操作就是自动生成了

    一个视图(View) 。至于视图要显示的具体内容,这是需要控制的。Xcode 通过创建视图的

    IBOutlet 和 IBAction 来控制视图。ViewController,顾名思义,是视图控制器的意思。而视图

    控制器就是一个类,具体来说,就是一个.h 和.m 文件。在创建 IBOutlet 和 IBAction 时,初学

    者所遇到的困惑是,不清楚往哪个文件拖曳,也不清楚拖曳到文件的哪个部分。为了搞明白这

    个问题,需要弄清楚一个概念:只有该视图所对应的视图控制器,才能控制对应的视图;拖曳

    的方向是对应的.h 或.m文件,拖曳的具体指向是@interface与@end 之间。

    为了熟记这种 Ctrl+Drag操作,这里给出三步法。

    第一步:拖曳,在 Storyboard中,直接拖曳一个UIViewController。

    第二步:创建,创建该视图所对应的视图控制器类(UIViewController) 。

    第三步:关联,将拖曳的 UIViewController与创建的视图控制器类关联起来。

    尽管通过拖曳对象的方式可以省去很多不必要的代码,但这也仅仅是节省一部分代码而

    已。Storyboard 和 Xib不是万能的,对于平台无法直接满足的定制化的控件,需要我们通过手

    动编码的方式来实现。

    开发一款可用的、可运营的 App 产品,是一件很不容易的事, “生命,本不该浪费在一些

    无趣的事上” 。我们应该把精力集中在产品的业务实现和用户体验上,而不是为 UI 的实现花

    费太多的时间。

    更多精彩尽在www.sxpdf.com

    XIII

    忍不住也来说说 iOS的设计模式

    不管是什么软件开发平台,都会宣扬其设计理念,大谈特谈其设计模式。这里也忍不住想

    说说 iOS 的设计模式。

    iOS最基本的设计模式就是 MVC。

    大多 MVC 参考书都是这样介绍的:MVC 是一种设计模式,M(Model)、V(View)、C(Controller)。Controller 控制视图的显示,Model 提供数据,Model 与 Controller 交互,但

    Model 从不与 View直接打交道。MVC 解决了视图与数据隔离的问题,降低了数据与视图的耦

    合性,便于维护。

    对于 iOS 初学者来说,看完这段话,是没有感觉的。当我们学习某种模式时,首先要明

    白它讲的是什么?为什么用它?怎么用它?明白了这三点,那才是真正地明白了。

    MVC 的概念,我们已经清楚了。不清楚的是:为什么要用 MVC?仅仅讲到数据与视图

    的分离,这是不接地气的。也就是说,大道理都明白,谈到具体的使用,仍是模棱两可。

    如果不想再单独创建一个 Model文件,直接把数据放在 Controller中,难道这样不行吗?

    这还真的行。我们注意到,确实有些 App 就是这样做的。当 App 数据量很小时,体现不出设

    计模式的优势,想怎么用就怎么用,反正功能也实现了,而且,还减少了 Model 文件,感觉

    更容易些。

    这里,我们所讨论的是较为复杂的 App。对于复杂的 App 来说,首要特征就是数据量庞

    大,数据的管理是一个难点(这里暂不讨论数据管理问题,后续章节有单独的介绍)。

    做软件,总是希望能复用。对于 App 来说,复用有以下几种情况。

    (1)数据的复用:如果新创建了一个项目,想重用之前 App 的数据。也就是说,换汤不

    换药。同一套数据,不同的 View。这个时候,就需要把之前的数据分离出来了,分离到一个

    独立的数据文件中。在新的项目中,直接加载这个数据文件就可以了(这里说的数据文件,不

    是某个plist、sqlite 文件,而是 Model 下具有逻辑功能的文件)。

    (2)视图的复用:同一套 UI框架,只是展示的数据不同。这个时候,数据文件、视图(View)

    文件和视图控制器(View Controller)文件是完全独立的。

    更多精彩尽在www.sxpdf.com

    XIV

    (3)Universal App:是指一个 App 可以根据终端自适应布局,既支持iPhone 版,又支持

    iPad 版,这样的 App 称之为 Universal App。既然是同一个App,就应该共享同一数据。如果

    数据不是独立的模块,而是将数据混在了 View Controller中,那么管理起来将非常不方便。难

    怪有 iOS 开发者抱怨,做一个 Universal App 还不如单独开发两个 App 简单:一个 iPhone 版

    App,一个iPad版 App。如果真的是对同一个产品创建两个工程的话,后期维护的工作量可想

    而知。

    更多精彩尽在www.sxpdf.com

    XV

    目 录

    iOS基础篇

    第 1章 iOS 基础知识 ··················································································································· 2

    1.1 Objective-C 语法简介 ······································································································· 2

    1.1.1 Objective-C的奇特之处 ······························································································ 2

    1.1.2 如何声明一个实例变量 ······························································································ 4

    1.1.3 Objective-C字符串 ····································································································· 5

    1.2 Objective-C 的对象类型与基本数据类型 ········································································ 6

    1.2.1 对象类型与基本数据类型的混合使用 ·········································································· 6

    1.2.2 对象类型与基本数据类型的转换 ················································································· 7

    1.3 不可变数组与可变数组 ···································································································· 7

    1.3.1 不可变数组(NSArray)的特征 ·················································································· 8

    1.3.2 可变数组(NSMutableArray)的特征 ··········································································· 8

    1.3.3 如何遍历数组中的对象 ······························································································ 8

    1.3.4 NSArray 与NSMutableArray 的应用 ··········································································· 10

    1.4 不可变字典与可变字典 ·································································································· 11

    1.4.1 不可变字典(NSDictionary) ···················································································· 11

    1.4.2 可变字典(NSMutableDictionary) ············································································ 12

    1.4.3 如何遍历字典中的对象 ···························································································· 12

    1.4.4 NSArray 与NSDictionary 的应用 ··············································································· 13

    1.4.5 创建类的对象 ·········································································································· 13

    1.5 iOS应用程序概述 ·········································································································· 14

    1.5.1 应用程序的入口 ······································································································ 14

    1.5.2 应用程序委托(AppDelegate) ·················································································· 14

    1.5.3 UIApplication应用场景 ···························································································· 15

    1.5.4 一种简单的永久数据存储方式 ·················································································· 16

    1.6 iOS定制化控件 ·············································································································· 17

    1.6.1 定制化View的创建 ································································································· 17

    更多精彩尽在www.sxpdf.com

    XVI

    1.6.2 小标签(UILabel) ,大用场 ······················································································ 19

    1.6.3 如何实现输入框随键盘上移 ······················································································ 20

    1.7 视图的层级管理 ············································································································· 23

    1.7.1 创建视图的方法 ······································································································ 23

    1.7.2 如何从父视图中移除子视图 ······················································································ 25

    1.7.3 登录页面的实现 ······································································································ 26

    1.8 iOS编程规范 ·················································································································· 28

    1.8.1 代码的可维护性 ······································································································ 29

    1.8.2 面向对象的编程思想 ································································································ 29

    1.8.3 优先编写轻量级的ViewController ·············································································· 30

    1.9 小结 ································································································································· 31

    第 2章 视图控制器之间的传值 ································································································· 32

    2.1 通过 Delegate 实现 ViewController之间的传值 ···························································· 32

    2.1.1 Delegate概述 ·········································································································· 32

    2.1.2 学习Delegate的困惑 ································································································ 32

    2.1.3 从一道经典的面试题说起 ························································································· 33

    2.1.4 学习Delegate常出现的几个误区 ··············································································· 33

    2.1.5 Delegate技术难点在哪里 ·························································································· 34

    2.1.6 数据逆向传送一定要通过Delegate吗 ········································································ 34

    2.1.7 Delegate应用五步曲 ································································································ 35

    2.1.8 Delegate优势 ·········································································································· 38

    2.2 通过单例实现 ViewController之间的传值 ···································································· 38

    2.2.1 单例的创建 ············································································································· 39

    2.2.2 单例的初始化 ·········································································································· 40

    2.2.3 单例设计模式的本质 ································································································ 41

    2.2.4 通过单例实现传值 ··································································································· 41

    2.2.5 单例模式在登录模块中的应用 ·················································································· 42

    2.2.6 单例模式的优势 ······································································································ 44

    2.3 通过 KVO实现 ViewController之间的传值 ································································· 44

    2.3.1 什么是KVC ············································································································ 44

    2.3.2 什么是KVO ············································································································ 45

    2.3.3 KVO的特点 ············································································································ 46

    2.3.4 使用KVO的步骤 ···································································································· 46

    2.3.5 KVO的实现方法 ····································································································· 46

    2.3.6 KVO应用注意事项 ·································································································· 50

    更多精彩尽在www.sxpdf.com

    XVII

    2.4 通过 NSNotification实现 ViewController之间的传值 ·················································· 50

    2.4.1 NSNotification的定义 ······························································································· 51

    2.4.2 NSNotificationCenter ································································································· 51

    2.4.3 发出通知 ················································································································ 51

    2.4.4 接收通知 ················································································································ 52

    2.4.5 移除通知 ················································································································ 52

    2.4.6 异步模式下的通知操作 ···························································································· 53

    2.4.7 通过NSNotification实现ViewController之间的传值 ··················································· 53

    2.4.8 NSNotification与Delegate的区别 ·············································································· 55

    2.4.9 监听系统自带的NSNotification ················································································· 56

    2.5 小结 ································································································································· 58

    第 3 章 App与服务器接口的定义 ····························································································· 59

    3.1 关于 JSON 的认识 ·········································································································· 59

    3.2 App 与服务器接口的定义 ······························································································ 61

    3.2.1 App与后台的接口设计 ····························································································· 61

    3.2.2 后台返回的数据格式 ································································································ 61

    3.2.3 后台返回的提示信息 ································································································ 62

    3.3 JSON与 Model的转换 ··································································································· 62

    3.3.1 JSONModel常见的用法 ···························································································· 63

    3.3.2 JSONModel的几个属性用法 ····················································································· 67

    3.4 小结 ································································································································· 69

    第 4 章 CollectionView的应用 ·································································································· 70

    4.1 CollectionView与 TableView孰优孰劣 ········································································· 70

    4.1.1 TableView的应用场景 ······························································································ 70

    4.1.2 CollectionView的应用场景 ······················································································· 71

    4.1.3 CollectionView与TableView概念对比 ······································································· 71

    4.1.4 CollectionView与TableView的性能对比 ···································································· 71

    4.2 什么是UICollectionView ······························································································· 71

    4.3 实现一个简单的 UICollectionView ················································································ 72

    4.4 UICollectionViewCell 视图层级 ····················································································· 73

    4.5 UICollectionViewDataSource ·························································································· 74

    4.6 关于Cell 的重用 ············································································································· 74

    4.7 UICollectionViewDelegate ······························································································ 75

    4.8 UICollectionViewLayout ································································································· 76

    4.9 实现一个简单的瀑布流 ·································································································· 77

    更多精彩尽在www.sxpdf.com

    XVIII

    4.9.1 通过手动编码创建UICollectionView ·········································································· 78

    4.9.2 直接拖曳一个CollectionViewController ······································································ 81

    4.9.3 基于Xib创建一个UICollectionViewCell ···································································· 86

    4.10 自定义瀑布流的应用场景 ···························································································· 88

    4.11 自定义 Flow Layout 进行瀑布流布局 ·········································································· 88

    4.11.1 自定义瀑布流的应用场景 ························································································ 89

    4.11.2 自定义瀑布流的实现思路 ························································································ 90

    4.11.3 创建自定义的Flow Layout ······················································································ 90

    4.11.4 创建自定义的CollectionViewCell ············································································· 92

    4.11.5 关于initWithFrame:方法的使用 ················································································ 93

    4.11.6 自定义瀑布流的完整实现 ························································································ 94

    4.11.7 UICollectionView相关的类图 ·················································································· 96

    4.11.8 如何实现UICollectionView的轮播 ··········································································· 97

    4.12 CollectionView与TableView的区别 ··········································································· 98

    4.13 图片轮播的实现思路 ···································································································· 98

    4.14 CollectionView注意事项 ······························································································ 99

    4.15 小结 ····························································································································· 100

    Web与 Native混合开发模式

    第 5章 Block 的应用 ················································································································ 102

    5.1 Block缘起 ···················································································································· 102

    5.2 Block概述 ···················································································································· 103

    5.3 Block的声明、实现与调用 ························································································· 104

    5.3.1 Block的声明 ········································································································· 104

    5.3.2 Block的实现 ········································································································· 106

    5.3.3 Block的调用 ········································································································· 108

    5.3.4 Block外部变量的访问 ···························································································· 109

    5.4 Block的应用场景 ········································································································· 110

    5.4.1 Block用于completionHandler ·················································································· 110

    5.4.2 Block声明为实例变量 ···························································································· 113

    5.4.3 typedef Block ········································································································· 114

    5.5 通过Block 实现视图控制器之间的逆向传值 ····························································· 115

    5.5.1 应用场景 ·············································································································· 115

    5.5.2 代码实现 ·············································································································· 115

    5.6 小结 ······························································································································· 118

    更多精彩尽在www.sxpdf.com

    XIX

    第 6 章 iOS 网络请求 ··············································································································· 119

    6.1 iOS网络请求概述 ········································································································ 119

    6.2 AFNetworking 的应用 ·································································································· 119

    6.2.1 AFNetworking概述 ································································································ 119

    6.2.2 AFNetworking框架使用方法 ··················································································· 121

    6.2.3 影响网络请求的几个条件 ······················································································· 122

    6.2.4 善用URL宏定义 ··································································································· 124

    6.2.5 URl接口应统一管理 ······························································································ 124

    6.2.6 AFNetworking的二次封装 ······················································································ 126

    6.3 AFNetworking 的序列化问题 ······················································································· 126

    6.3.1 AFNetworking请求格式 ························································································· 127

    6.3.2 AFNetworking响应格式 ························································································· 128

    6.4 异步请求数据并刷新 UI 页面 ······················································································ 128

    6.5 远程文件下载 ··············································································································· 130

    6.5.1 基于AFNetworking的文件下载 ··············································································· 130

    6.5.2 基于NSURLSession的文件下载 ·············································································· 132

    6.5.3 网络安全访问设置 ································································································· 133

    6.6 小结 ······························································································································· 134

    第 7 章 JavaScript基础 ··········································································································· 135

    7.1 JavaScript语法 ·············································································································· 135

    7.2 变量的声明与赋值 ······································································································· 136

    7.3 如何判断两个字符串是否相等 ···················································································· 137

    7.4 创建 JavaScript 对象的三种方法 ················································································· 138

    7.5 函数声明与函数表达式 ································································································ 140

    7.6 可立即调用的函数表达式 ···························································································· 143

    7.7 循环的实现 ··················································································································· 145

    7.8 防止 JavaScript 自动插入分号 ····················································································· 146

    7.9 严格模式 ····················································································································· 147

    7.10 如何运行与调试 JavaScript 代码 ··············································································· 148

    7.10.1 把JavaScript代码内嵌到HTML 页面中 ································································· 148

    7.10.2 通过Node.js运行JavaScript代码 ··········································································· 150

    7.11 JavaScript 的面向对象设计思想 ················································································· 150

    7.12 JavaScript 的异步编程模式 ························································································ 151

    7.12.1 Promise对象 ········································································································ 152

    7.12.2 生成Promise实例对象 ·························································································· 152

    更多精彩尽在www.sxpdf.com

    XX

    7.12.3 Promise原型方法 ································································································· 154

    7.12.4 Promise的catch方法 ···························································································· 154

    7.13 如何在 HTML中嵌入 JavaScript ··············································································· 155

    7.13.1