iOS学习入门分享
2016-03-27 » iOS开发基础基于公司普及全栈工程师的情况,给大家做了一次IOS入门分享。简单描述一下IOS开发是怎么进行的。
概述
开发工具 :Xcode (本机 MBP 8G + 256固态 ,非Mac 可以安装黑苹果转MAC OS)
当前版本 Xcode 基本不支持插件,自带功能够用
IOS API 可以在Xcode中直接查找 (路径:菜单 - Window - Documenttion And Api Reference)
语言基础
1.C 语言
熟悉基本数据类型、判断与循环语句、函数与变量作用域、
基本运算与进制、基本算法、数组与指针、枚举、宏定义
2.Objective-C 语言
扩充C的面向对象编程语言,面向对象、完全兼容C语言
-
.h/.m
.h 表示头文件,用来声明各种成员变量,方法,属性之类的。 .m 主要用来实现.h 里声明的方法 import的引入对应头文件。#import "xxx.h"
-
@符号的使用
声明属性 @property (nonatomic,assign) int running 声明类 @interface myView : UIView @end 实现类 @implementation myView @end //结束标示,类的声明实现,协议的声明等标签都是开始结束成对出现。 声明协议 @protocol myProtocol <NSObject> @end 实现协议 @interface myView : UIView <myProtocol> @end 用作数组字典等OC专用类型 NSArray *array = @[]; NSDictionary *dic = @{}; 还可以把普通的数据类型转换为OC的对象类型 NSString *str = @"xxx"; 等等
-
方法、block
声明方法 - (void)apiAction:(UIButton *)btn; 实现方法 - (void)apiAction:(UIButton *)btn { } 方法调用 [self apiAction:nil]; 声明 block typedef void (^PickPhotoCompleteBlock)(UIImage *image); block 作为方法参数 - (void)setPickPhotoBlock:(PickPhotoCompleteBlock)pickPhotoCompleteBlock { 其他执行 执行block pickPhotoCompleteBlock(); } 方法调用 [self setPickPhotoBlock:^(UIImage *image) { 方法执行后、这里的内容执行 }];
-
其他
代理模式, 分类 categroy 延展 extension、协议 (类似java接口) 和泛型 (IOS7 以后)等等
3.Swift 语言
Swift 是 Apple 自创的一门专门为 Cocoa 和 CocoaTouch 设计的语言,意在用来替代 OC ( Xcode 6 / IOS 7 以上)。Swift采用了安全的编程模式和添加现代的功能来使得编程更加简单、灵活和有趣、更容易阅读。界面则基于广受人民群众爱戴的Cocoa和Cocoa Touch框架,展示了软件开发的新方向。
cocoa包含Foundation和AppKit、Core Data等框架,可用于开发Mac OS X系统的应用程序
cocoa touch包含Foundation和UIKit框架,可用于开发iPhone OS 系统的应用程序
所有的 Swift 代码都将被 LLVM 编译为 native code,以极高的效率运行。
按照官方今天给出的 数据,运行时比 Python 快 3.9 倍,比 objc 快 1.4 倍左右。
Swift 特性:
-
let & var
let 和 var 都是属性声明使用 let 表示 常量,不可变更 var 表示 变量,可变更
-
Swift中的函数和闭包都是一等公民
-
Swift是强类型 :意思就是一个变量或者常量要有确定的类型 (目的是把错误推到编译时发生,减少运行时bug出现的几率, 安全)
声明属性有严格的类型要求 直接设置类型, 如果属性可能为空,则需要设为可选值 var num1: Int? 或者赋值,通过Swift的类型推断自动推断类型 var num2 = 10
-
类型推断 (语法糖)
//变量intValue没有显式声明一个特定的类型,编译器会根据其赋值语句推断出它的类型为Int var intValue = 10 intValue被自动推断成Int型。 intValue = "" //无法通过
-
结构体(Struct)
结构体和类几乎一样,都可以定义属性,定义方法,实现协议,初始化方法,定义拓展,定义下标支持。但是类又多了继承,运行时类型检查以及转换,deinit方法允许释放资源,引用计数。总得来说,类多了内存管理和继承。结构体的设计初衷就是为了简单封装一些数据,并不需要太多的面向对象的特性
-
可选值(Optional)
Swift语言中的全新类型、可以有值,也可以没有值,当它没有值时,就是nil。 用 ? 标示 var num1: Int? 此处的 ? 标示 num1 变量有值的时候是 Int型 还可能为 nil var num2 = num1! // 此处感叹号为强制解析,若果num1为nil此处必然抛异常
-
POP 面向协议的编程
除了类,Swift的协议让值类型的struct、 枚举都实现类似多态的能力 1.Protocol Composition protocol 有点类似于 java 的接口,同样可以多实现 2.Protocol extension 协议可以扩展到提供方法和属性实现符合类型,所有实现了协议的类或者结构体等 都会默认获得这些方法,属性默认实现,与默认值 3.class Protocol 类专用协议
-
Playground的使用
Playground是苹果公司在2014年WWDC(苹果开发者大会)随Swift一起推出的,可以实现一边写代码,一边预览效果(即实时预览代码的效果)的工具。 相对于以前写代码要经过Build→Run漫长的等待才能看到代码的效果来说,Playground给程序员带来的方便不言而喻。
Xcode的使用
1.Xcode 操作面板
-
工具栏(Toolbar)
你选择工作视图,运行app, 在不同布局界面切换的工具栏
从左到右分别是:
运行、停止按钮、Scheme列表、模拟器列表、活动查看器、编辑器模式配置按钮组、切换界面布局按钮组
-
导航区(Navigator area)
导航你整个工程、警告、报错、搜索等的地方
从左到右八个按钮分别是:
项目导航:检索项目源代码和资源文件 符号导航:显示代码中得类、对象、函数、变量、属性等元素 搜索导航:全工程搜索器 事件导航:显示工作区找到的事件,如编译错误、语法错误等错误、异常提示信息 测试导航:显示单元测试用例以及测试结果 调试导航:显示程序在调试状态下得资源占用状态以及堆栈信息 断点导航:显示开发过程中在工程中打的断点信息 日志导航:显示日志信息,编译、分析、调试方面的日志
-
编辑区(Editor area)
所有奇迹诞生的地方
跳转栏:显示当前编辑器编辑的文件路径,还可以直接跳转到项目任意层次任意文件
编辑区域:源代码编辑器、辅助编辑器、界面生成器、版本编辑器等等
-
工具区(Utilities area)
包含检查器和一些库
检查器:查看更改编辑器选中元素的相关特性
库导航栏:资源库导航(文件模板、代码片段、对象、媒体文件)
-
调试区(Debug area)
包括调试窗口和变量检测器
断点执行、位置模拟、输出控制台、调试功能区。具体后面 ”Xcode项目调试“ 有详细描述。
-
Xcode系统工具条
常用菜单:Product
Run 运行app Test 运行单元测试 Build 编译 Clean 清空缓存 Scheme 修改编译运行需要的一些 Configuration
2.Xcode 创建项目
-
新建项目流程
Xcode File - New - Project
-
设置 Project Options
Product Name :项目名称 Team :开发者信息 Organization Name :一般是反转域名方式保证唯一性 Organization Identifier : 一般是反转域名方式保证唯一性 Bundle Identifier :Organization Identifier 再加上 "." 再加上 Product Name Language :开发语言 (Objective-C、Swift) Devices :设备支持 (Universal、iPhone、iPad) Use Core Data : 是否使用数据持久化 Include Unit Tests :是否包含单元测试Target Include UI Tests : 是否包含UI测试Target
-
项目目录结构(swift)
demo --demo ----AppDelefate.swift ----ViewController.swift ----Main.storyboard ----Assets.xcassets ----LaunchScreen.storyboard ----Info.plist ----demo.xcdatamodeld //勾选了 Use Core Data 才有 --demoTests //勾选了 Include Unit Tests 才有 --demoUITests //勾选了 Include UI Tests 才有 --Products --Frameworks //添加了第三方库才有
3.Xcode 配置分析
详细分析传送门
-
PROJECT 和 TARGETS
project就是一个工程,一个project可以对应多个target (创建一个project,xcode会默认生成一个target)。
targets之间完全没有关系。但target和project有关系,target的setting会从project settings中继承一部分。
targets : 一个target对应一个新的product(基于同一份代码的情况下)。
虽然代码是同一份, 但编译设置(比如编译条件), 以及包含的资源文件却可以有很大的差别. 于是即使同一份代码, 产出的product也可能大不相同。例如我们一份代码需要做出不同应用环境的 app 这个时候target的作用就出来了。
每个target单独会有一份 info.plist。
Manage Schemes 可以管理变更target。
-
PROJECT 部分 - Info
Deployment Target :运行应用需要的最低操作系统版本
configurations :编译环境
Localizations : 语言本地化
-
PROJECT 部分 - Build Settings
刚接触IOS开发比较少需要更改
-
TARGET 部分 - Info
Custom iOS Target Properties
Bundle versions string, short : 是正式的版本号,跟itunes上的版本号一致,Bundle Version 可用作内部版本时使用,当Bundle Version String缺省时,Bundle Version替代Bundle Version String的功能,同时也继承他的限制(比如格式,位数等),需与itunes上的版本号保持一致。 Bundle identifier :app标识,一般按反域名的方式写,默认使用创建项目的时候填写的内容。 Main storyboard file base name : 主 storyboard 文件名字。 Bundle version:内部版本号,不对外公开。 Launch screen interface file base name : 启动图 storyboard 文件名字。 Executable file :$(EXECUTABLE_NAME) 执行程序名,默认与 Product Name 一致。 Bundle name:目标项目的名字(TARGETS下面的名字),默认使用创建项目的时候填写的 Product Name。 Bundle display name : 显示在手机屏幕上的应用名字。 Supported interface orientations :横竖屏支持。 Localization native development region : 本地开发默认地区。 Required device capabilities : 设备运行环境、比如有的静态库不支持某些指令集(CPU决定)。 当我们需要使用某些系统权限和对应的提示文案也是配置在这里: Privacy - Photo Library Usage Description : 照片库权限弹窗说明。 Privacy - Camera Usage Description : 相机权限弹窗说明。
URL Types
iOS的App 可以注册自己的URL Scheme,URL Scheme是为方便App之间互相调用而设计的。我们可以通过系统的OpenURL来打开该App,并可以传递一些参数。 URL Identifier是自定义的 URL Scheme 的名字,一般采用反转域名的方法保证该名字的唯一性。 URL Scheme 用于外部唤起 如: URL Identifier :com.yang.XcodeProjectDemo URL Scheme :yang 然后我们在浏览器输入 yang:// 就会收到提示询问是否跳转到demo App了
-
TARGET 部分 - General
Identity
Display Name : 显示在手机屏幕上的应用名字。 Bundle Identifier : App标识,一般按反域名的方式写,默认使用创建项目的时候填写的内容。 Version :正式的版本号 Build : 内部版本号,不对外公开。
Signing
Automatically manage signing :Xcode新增的证书自动管理,Xcode会自动选择合适证书 Team : 对应的开发者账号 Apple ID Provisioning Profile : 配置文件 Signing Certificate : 签名证书
Deployment Info
Deployment Target :运行应用需要的最低操作系统版本 Devices :设备支持(Universal、Iphone、Ipad) Main Interface :主界面对应文件。 Devices Orientation :横竖屏支持。 Status Bar Style :顶部状态栏类型。
App Icons and Launch Images
App 图标 和 启动图配置
Linked Frameworks and Libraries
需要引入的 frameworks 或者 libraries 列表
-
TARGET 部分 - Capabilities
功能配置、一部分是绑定开发账号的,如 Push Notifications 推送
-
TARGET 部分 - Build Phases
Target Dependencies :Target依赖,某些Target可能依赖某个Target。
Compile Sources : 已编译文件
Link Binary With Libraries :第三方类库
Copy Bundle Resources :资源文件
-
Scheme部分 - Info (Product-Scheme-Edit Scheme)
Build Configuration : 配置当前target使用 Debug 或者 Release 编译环境
4.Xcode 资源内容
-
图片资源
1.图片集
Assets.xcassets 以 Image Set (图片集)的方式存储图片。
IOS 初始化图片 : let image = UIImage(named: “xxx”)
一个图片集包括 @1x、@2x、@3x 三个规格的图片,分别对应不同的scale(分辨率)。
同时,也可以针对不同设备设置图片(比如同一个名字的图片集,iphone和ipad要用不一样的图片)。
通常上面初始化方法中的 “xxx” 就是图片集的名字, 在图片集里面放两张不一样的@2x和@3x图片,在iPhone6和iPhone6 Plus加载出来的会不一样。
2.AppIcon
AppIcon 表示 应用图标的图片集
3.LaunchImage
LaunchImage表示启动页那张图的图片集,也可以通过 LaunchScreen.storyboard 配图。
4.Slicing
例如微信聊天气泡图片的处理,slicing可以自动拉伸图片并且不影响气泡边角。
-
代码片段
常用的代码封装成代码片段
图中从上到下的含义依次是: Title 代码片段的标题 Summary 代码片段的描述文字 Platform 可以使用代码片段的平台 Language 可以在哪些语言中使用该代码片段 Completion Shortcut 代码片段的快捷方式,比如本文开头用到的dowhile,在这里,把属性设置的快捷方式设为property Completion Scopes 可以在哪些文件中使用当前代码片段,比如全部位置,头文件中等,当然可以添加多个支持的位置。 最后的一个大得空白区域是对代码片段的效果预览。 一切设置完成以后,点击该菜单右下角的Done按钮,新建工作就结束了。 代码片段存放地址:~/Library/Developer/Xcode/UserData/CodeSnippets
5.Xcode 项目调试
-
单元测试
1、写完代码以后:想要验证一下自己写的代码是否有问题。
2、写代码之前:就是写代码之前所有的功能分模块的设计好,测试通过了再写。
3、修复某个bug后:一般修复完某个bug,为了确保修复是成功的,可以写测试。
4、检查方法执行时间,也可以写单元测试。
-
断点调试
1.运行App、并在需要的位置设置断点
2.断点调试区域也是大多数IDE 都有的调试方式,开启关闭断点、进入断点,下一步、跳入、跳出
3.视图调试 :上图中的Debug view graph 用于视图调试,可以看到当前控制器的每一层视图。
4.导航条-调试导航 :管理全局断点,还可以添加一些特殊类型断点,例如全局异常断点
-
LLDB调试
在控制台输入命令进行调试, 详细说明 : LLDB调试
IOS模拟器调试
1.选择 Scheme 和 选择模拟器
2.模拟器列表,可以选择真机、模拟器,可以添加或者下载更多模拟器
3.模拟器菜单操作(Hardware菜单 包括 旋转、锁屏、回到主页面等等)
IOS真机调试 (模拟器毕竟是模拟器)
需要一个普通的AppleID,使用Xcode自动证书即可
如果之前使用过证书,需要在新项目使用证书,删除keychain中得你这个appleID中得证书,关开一下自动使用xcode证书,然后会自动生成对应的签名证书
IOS开发基础知识
1.IOS代码开发
-
生成控制器、控件
override func viewDidLoad() { super.viewDidLoad() let button = UIButton(type: UIButtonType.custom) button.setTitle("按钮", for: UIControlState.normal) button.setTitleColor(UIColor.blue, for: UIControlState.normal) button.frame = CGRect(x: 100, y: 100, width: 100, height: 100) view.addSubview(button) }
-
事件绑定
1.按钮事件的绑定
所有继承自 UIControl的控件都具有 以 Target-action(目标-行为)设计模式 添加事件的方法。
事件主要包括:点击、拖拽、编辑内容等类型
target 事件响应目标(用于执行响应方法) action 事件响应行为(即方法)
绑定事件的方法 open func addTarget(_ target: Any?, action: Selector, for controlEvents: UIControlEvents) 事件响应行为 方法 func buttonAction(btn: UIButton) { print("按钮事件") } 方法调用,给按钮绑定点击事件,事件响应行为方法 为 buttonAction button.addTarget(self, action: #selector(buttonAction(btn:)), for: UIControlEvents.touchUpInside)
2.其他手势事件的绑定
除开上面的UIControl事件,一些没有继承自UIControl的控件可以通过手势事件处理事件响应。
let ges = UITapGestureRecognizer(target: self, action: #selector(tapAction(_:))) myView.addGestureRecognizer(ges) UITapGestureRecognizer 轻触手势 UIPinchGestureRecognizer 捏合手势 UIRotationGestureRecognizer 旋转手势 UISwipeGestureRecognizer 轻扫手势 UIPanGestureRecognizer 拖动手势 UIScreenEdgePanGestureRecognizer 屏幕边缘拖动手势 UILongPressGestureRecognizer 长按手势
-
委托代理
在iOS中委托通过 @protocol (协议) 的方式实现 ,协议中定义但不实现方法。方法的具体实现交由具体的 实现了这个协议的对象去实现。
我们需要使用tableView的代理,需要控制器实现对应的协议和方法,同时,tableView中定义了一个变量用于接收实现了协议的对象,从而通过这个对象去调用具体的方法实现。实现了协议,必然被要求实现一些方法,如果这些方法写在控制器中,也就是 self 下面,那么我们传入delegate 和 dataSource的对象 就是 self。
let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: 320, height: 568), style: UITableViewStyle.grouped) view.addSubview(tableView) //设置委托代理 tableView.delegate = self tableView.dataSource = self
-
控制器跳转
1.没使用系统导航条
let vc = UIViewController() self.show(vc, sender: nil) 参数传递 : 属性传值 let vc = ViewControllerTwo() vc.style = "xxx" self.show(vc, sender: self)
2.使用了系统导航条
let vc = UIViewController() self.navigationController?.show(vc, sender: nil)
2.IOS可视化开发
-
storyboard & xib
纯代码写界面有时候会降低开发效率,对于一些通用简单的界面,例如程序设置界面,可以使用xib / storyboard 进行开发。相对于xib,使用storyboard可以更好地了解App中所有的视图以及它们之间的关联的概况。掌控全局更加容易,因为所有的设计都包含在一个文件中,而不是分散在很多单独的nib文件中。
xib / storyboard文件本质上是一个xml文件。 XIB doucument类型:com.apple.InterfaceBuilder3.CocoaTouch.XIB storyboard document类型:com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB scenes 场景,可以理解为一个个页面(navigationViewController、viewController等等) segue 转场,通过连接不同的视图控制器来创建转场实现视图控制器之间的过渡,并且可以携带参数 不过一般不直接进行编辑 xml。
storyboard 界面生成器 如下:
Outline view :对象窗口 Canvas :画布,主要操作区域 Attributes inspector :检查器 Object library :组件库
认识起始标签和场景
1.起始标签 (Storyboard Entry Point)指定的控制器就是app启动后的第一个页面。
storyboard 默认创建的时候会有一个如下的箭头,也就是起始标签。
如果找不到起始标签,可以选择需要设置为初始场景的View controller 打开检查器,勾选 “ Is Initial View Controller” 即可。
2.场景和控件可以通过上图中的右侧组件库(Object library)中拖拽到画布(Canvas)区域生成。
两个场景之间设置 segue
1.通过控件事件设置 segue
按住CTRL键,从一个对象 (比如一个按钮), 点击拖拽出一条线连接到目标控制器范围内松开鼠标。
注意:可以拖拽生成 segue 的控件必须支持事件响应 (右键控件查看弹出菜单,看是否支持send events)
2.通过View controller 设置 segue
按住CTRL键,从场景的View controller, 点击拖拽出一条线连接到目标控制器范围内松开鼠标。
然后再代码中通过 segueId 进行转场、并可以传递参数。
self.performSegue(withIdentifier: segueId, sender: nil)
3.松开鼠标后,在弹出菜单中 选择 Manual Segue 中的选项,这里选择 Show。
Manual Segue 区别 Show: Show Detial: Present Modally:模态方式展示内容(从下往上推出) Present As Popover:弹窗方式展示内容 Custom:自定义转场
设置成功, 得到如下一条蓝色线。
选中创建好的蓝色线,并在右侧检查器( Attributes inspector) 下设置好 identifier 为 “segueId”,那么到此就成功创建一个 segue。
segue 传值
A 转场到 B 并携带参数 self.performSegue(withIdentifier: segueId, sender: "参数") A中 需要 覆盖实现父类的一个方法: //segue转场中会执行的方法 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { //sender为参数 segue.identifier 为segueId //segue 为转场对象 segue.destination 为目标控制器 if segue.identifier == "segueId" { guard let vc_b = segue.destination as? B else { return } vc_b.style = "" //给B控制器赋值 属性传值 } } B 返回 A 参数返回、使用代理或者闭包
-
常用UI控件
1.tableview委托代理设置:
-
IBOutlet & IBAction
1.先打开辅助编辑器,选择到对应的源代码文件
2.点击控件,拖拽出一根线到源代码区域并松开鼠标
3.根据弹窗内容填写属性信息, 然后单击连接
4.然后我们就可以在在源代码区域看见Outlet property 了
5.根据弹窗上的connection 不同 (Outlet、Action)可以分别关联属性对象 和对象的响应事件
-
IOS 自动布局
AutoLayout则是苹果公司在iOS6推出的一种基于约束的,描述性的布局系统。
自动布局基于约束的设置。
约束具有很简单的可描述性,根据约束列表的说明,自行设置view的相对约束
但是约束的设置需要成套,例如view的约束需要可计算的高度,宽度,坐标位置,否则会出现错误提示:
-
自定义控件
继承、拓展
其他内容
1.生命周期
-
控制器的生命周期
-
App的生命周期
程序入口:
OC :main.m 文件中的 main 方法 调用 UIApplicationMain
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
Swift :Appdelegate.swift 中 的 @UIApplicationMain 相当于 main方法
App启动:
App进入后台: