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 创建项目

  1. 新建项目流程

    Xcode File - New - Project

  2. 设置 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
    

  3. 项目目录结构(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 配置分析

详细分析传送门

  1. 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。

  2. PROJECT 部分 - Info

    Deployment Target :运行应用需要的最低操作系统版本

    configurations :编译环境

    Localizations : 语言本地化

  3. PROJECT 部分 - Build Settings

    刚接触IOS开发比较少需要更改

  4. 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了
    

  5. 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 列表

  6. TARGET 部分 - Capabilities

    功能配置、一部分是绑定开发账号的,如 Push Notifications 推送

  7. TARGET 部分 - Build Phases

    Target Dependencies :Target依赖,某些Target可能依赖某个Target。

    Compile Sources : 已编译文件

    Link Binary With Libraries :第三方类库

    Copy Bundle Resources :资源文件

  8. 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进入后台:

2.CocoaPods

CocoaPods 从安装到使用

参考资料

官方文档

Xcode官方文档