# 应用启动

初始化应用数据结构，准备应用运行，想用启动时的系统请求。

## 概述

在主屏幕上点击应用图标，系统拉起用用。如果应用需要特殊的事件，系统可能后台启动应用来处理。对于基于scene的应用，系统也同样的加载一个需要显示的scene或者其他工作。

所有的应用有一个关联的进程 UIApplication。应用也有一个委托对象（遵守UIApplicationDelegate协议），该对象响应进程中发生的重要事件。基于scene的app也适用应用代理在管理基础的事件像启动和停止。在启动时，UIKit自动创建UIApplication对象和应用代理。然后启动应用主事件循环。

## 提供一个启动Storyboard

当用户第一次加载应用，系统显示启动storyboard直到应用准备好显示UI。显示启动storyboard提示用户应用已启动正在准备中。如果应用启动和UI准备非常快，用户可能只是扫了启动storyboard一眼就过去了。

xcode自动创建一个默认的启动storyboard以供自定义，也可以根据需要增加多个启动storyboard。按照以下步骤新建启动storyboard：

* xcode中打开项目；
* 选择 文件 > 新建 > 文件；
* 增加启动storyboard；

  增加view到启动storyboard不能改使用自动布局约束来调整位置和大小以适应屏幕。UIKit使用这些限制来适配可用的空间并显示。

## 初始化应用数据结构

启动时间初始化代码放在以下两个方法內：

* application（willFinishLaunchingWithOptions）
* application（didFinishLaunchingWithOptions）

  UIKit在应用启动的时候调用这些方法调用他们：
* 初始化应用数据结构；
* 验证应用是否满足运行所需要的资源；
* 第一次运行的时候执行one-time设置，例如，在可写文件夹中创建用户可编辑文件模版；
* 连接到应用适用的关键服务上。例如，如果应用支持推送功能，要连接到苹果推送服务；
* 检查启动选项，了解应用启动原因。

对于不是基于scene的应用，UIKit加载默认的用户界面。使用 application（didFinishLaunchingWithOptions）方法来在显示之前对其更改。例如，你可能使用一个不同的view controller 来反应用户上次使用应用时的操作。

## 不要再主线程中运行耗时间的任务

当用户启动应用的时候，启动速度快能留下一个好印象。UIKit在 application（didFinishLaunchingWithOptions）方法结束之前不会显示应用界面。在 application（willFinishLaunchingWithOptions）方法执行长时间的任务会使用户觉得应用反应迟钝。后台任务返回速度快也是很重要的，因为系统会限制应用后台运行时间。

把对于应用初始化不重要的任务从启动序列中移除，例如：

* 推迟初始化应用不立即需要的特性；
* 更重要的，不再主线程运行长期运行的任务。例如，在一个全局调度队列中异步执行。

## 确定应用启动原因

当UIKit启动应用，传递一个问什么启动的启动配置通过如下两个方法 application（willFinishLaunchingWithOptions）和 application（didFinishLaunchingWithOptions）。字典中的键表明需要立即执行的重要任务。例如，可能反应用户从其他地方开始并想本应用中继续的操作。总是需要检查启动参数中所期望的键，并做出响应的反馈。

> 对于基于scene的应用，通过检查UIKit传递给 application（configurationForConnecting:options）方法的参数。

除非应用支持响应的功能，否则不会包含对应的键。例如，如果应用不支持推送，那么不会包含 remoteNotification 键。

[支持的启动选项](https://developer.apple.com/documentation/uikit/uiapplication/launchoptionskey)
