1 实现原理

(1)我们会发现许多 App 在一次启动时会显示一个新手引导页(下次启动就不会再显示)
 
(2)其判断原理就是在 AppDelegate 里的 didFinishLaunchingWithOptions 方法中检查 UserDefaults 中是否存在特定的键值:
  • 不存在则说明是第一次运行,我们便把根视图控制器改成引导页,并保存这个特定的键值(Bool 类型即可)。
  • 已存在则说明之前已运行过该应用,那么就显示默认视图。
 
(3)有时我们还想在应用更新后,新版本第一次启动时显示个新功能说明页,其原理同样是判断 UserDefaults 里的键值。只不过这次保存的是版本号,每次将之前保存的版本号与当前应用的版本号做比较:
  • 不同则说明新版本第一次启动。
  • 相同则说明新版本之前已经启动过。
 

2 样例代码

(1)为方便使用,这里对 UserDefaults 进行扩展,增加两个判断是否是第一次启动的方法:
extension UserDefaults {
//应用第一次启动
static func isFirstLaunch() -> Bool {
let hasBeenLaunched = "hasBeenLaunched"
let isFirstLaunch = !UserDefaults.standard.bool(forKey: hasBeenLaunched)
if isFirstLaunch {
UserDefaults.standard.set(true, forKey: hasBeenLaunched)
UserDefaults.standard.synchronize()
}
return isFirstLaunch
} //当前版本第一次启动
static func isFirstLaunchOfNewVersion() -> Bool {
//主程序版本号
let infoDictionary = Bundle.main.infoDictionary!
let majorVersion = infoDictionary["CFBundleShortVersionString"] as! String //上次启动的版本号
let hasBeenLaunchedOfNewVersion = "hasBeenLaunchedOfNewVersion"
let lastLaunchVersion = UserDefaults.standard.string(forKey:
hasBeenLaunchedOfNewVersion) //版本号比较
let isFirstLaunchOfNewVersion = majorVersion != lastLaunchVersion
if isFirstLaunchOfNewVersion {
UserDefaults.standard.set(majorVersion, forKey:
hasBeenLaunchedOfNewVersion)
UserDefaults.standard.synchronize()
}
return isFirstLaunchOfNewVersion
}
}

(2)在 AppDelegate.swift 中调用上面的扩展方法进行判断,并执行相应逻辑。

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? //程序启动
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { //判断当前版本是否第一次启动
if UserDefaults.isFirstLaunchOfNewVersion() {
//显示新功能介绍页
print("当前版本第一次启动")
let introductionViewController = IntroductionViewController()
self.window!.rootViewController = introductionViewController
} //判断是否第一次启动(两个都是第一次则以这个为准)
if UserDefaults.isFirstLaunch() {
//显示新手指导页
print("应用第一次启动")
let guideViewController = GuideViewController()
self.window!.rootViewController = guideViewController
} return true
} func applicationWillResignActive(_ application: UIApplication) {
} func applicationDidEnterBackground(_ application: UIApplication) {
} func applicationWillEnterForeground(_ application: UIApplication) {
} func applicationDidBecomeActive(_ application: UIApplication) {
} func applicationWillTerminate(_ application: UIApplication) {
}
}

Swift - 判断应用是否是第一次启动(或当前版本是否第一次启动)的更多相关文章

  1. 解决:阿里云ECS上启动tomcat后,第一次访问时间特别长

    Re在ECS上启动tomcat后,第一次访问时间特别长      2017-04-25 10:16:04 INFO com.world.socket.ServerSocketListener  25- ...

  2. 通过从代码层面分析Linux内核启动来探知操作系统的启动过程

    通过从代码层面分析Linux内核启动来探知操作系统的启动过程 前言说明 本篇为网易云课堂Linux内核分析课程的第三周作业,我将围绕Linux 3.18的内核中的start_kernel到init进程 ...

  3. init进程 && 解析Android启动脚本init.rc && 修改它使不启动android && init.rc中启动一个sh文件

    Android启动后,系统执行的第一个进程是一个名称为init 的可执行程序.提供了以下的功能:设备管理.解析启动脚本.执行基本的功能.启动各种服务.代码的路径:system/core/init,编译 ...

  4. Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7)

    http://blog.chinaunix.net/uid-20543672-id-3157283.html Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3 ...

  5. UEFI启动视频详解:启动分析+N项操作实例

    ============================================================= ※※※※最给力的视频解说※※※※ 2011hiboy全部共享资料:立刻去   ...

  6. Tomcat8源码笔记(七)组件启动Server Service Engine Host启动

    一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...

  7. tomcat 1)启动时不识别执行启动命令 2)启动报错 3)关闭不了,用myEclipse启动时显示jvm_bind,端口占用

  8. 使用servers 启动项目时 ,一直处于启动中, 最后出现无法的问题。

    使用eclipse 中的servers 配置了一个server 来启动项目, 发现无法启动 排除法: 去掉项目配置,单独启动该server ,发现可以启动, 说明是项目出现问题 但是项目并没有报错, ...

  9. Chorme中启动阿里旺旺误点取消启动并记住选择,如何更改。

    今天在Chorme中启动阿里旺旺误点取消启动并记住选择,然后如何也点不开了.从网上找到了一种解决方法: 找到路径   C:\Users\\AppData\Local\Google\Chrome\Use ...

随机推荐

  1. Blender 建模

    1.多图层切换 Blender也有图层的概念,我们在一个图层上建立了一个模型,可以在另外一个图层新建一个独立的模型.界面底部包含了Layer切换按钮.如下图所示: 当前我们正在操作第一个图层,如果想在 ...

  2. mysql 直接拷贝data 目录下文件用不的解决方案

    innodb 的表,直接复制文件是无法使用的,会提示 table doesn’t exists ,在复制的时候,应将data目录下的 ibdata1 文件一并复制过去,并且删除 ib_logfile0 ...

  3. HTML5标签canvas图像处理

    摘要: canvas可以读取图片后,使用drawImage方法在画布内进行重绘.本文介绍canvas的图像处理 drawImage drawImage() 方法在画布上绘制图像.画布或视频.drawI ...

  4. MsChart,饼状图

    HTML 后台代码:(dt为数据源)数据库中数据Sample 1 Chart1.Series["Series1"].Label = "#PERCENT{P}"; ...

  5. IIS------如何安装IIS

    1.打开“控制面板”->“程序”->“打开或关闭Windows功能” 2.如图所示: 3.如图所示: 4.点击确定,配置完成

  6. PHP 5.4 中的traits

    PHP 5.4中的traits,是新引入的特性,中文还真不知道如何准确翻译好.其实际的目的,是为了有的场合想用多继承,但PHP又没多继承,于是就发明了这样的一个东西. Traits (横向重用/多重继 ...

  7. Docker应用之镜像

    一.Docker包括三个基本概念 1.镜像(Image):Docker镜像是一个只读模板,例如一个镜像可以包含完整的Linux系统环境,里面仅仅安装了Apache或用户其他应用程序:镜像可以用来创建D ...

  8. zabbix加入TCP连接数及状态的监控

    一 监控原理: [root@ nginx]# /bin/netstat -an|awk '/^tcp/{++S[$NF]}END{for(a in S) print a,S[a]}' TIME_WAI ...

  9. mysql 字符串转数据丢失精度,mysql转换丢失精度,mysql CAST 丢失精度

    mysql 字符串转数据丢失精度,mysql转换丢失精度,mysql CAST 丢失精度 =============================== ©Copyright 蕃薯耀 2017年9月1 ...

  10. [Cubieboard] 在 Cubieboard 上安装 Node.js 和 npm

    你有两个选择可以实现在Cubieboard上安装NodeJS,下载别人已经编译完成适用于Cubieboard的NodeJS二进制包,或者自己下载源码自行在Cubieboard上进行编译. 使用编译完成 ...