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. mysql中查看数据库的版本,什么版本

    需求:查看当前使用的数据库是哪个版本的,什么版本 select version(); 查询结果: 备注:通过version()函数查询出来当前使用的数据库版本是5.5.57-log 文档创建时间:20 ...

  2. 如何使用 MasterPage

    MasterPageFile母版页 刚开始学,什么都不懂,看到了这段代码,才促使自己去研究MasterPageFile到底是什么含义.<%@ Page Language="C#&quo ...

  3. MyBatis 原码解析(version:3.2.7)

    mybatis-plus 实践及架构原理.pdf mybatis-plus思维导图 首先,我们看使用原生的JDBC来操作数据库的方式: // 1. 获取JDBC Connection Connecti ...

  4. GDAL------加载Shapefile文件

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...

  5. SpringBoot------Eclipce配置Spring Boot

    步骤一: 步骤二: 点击左下角Eclipse图标下的“Popular”菜单,选择Spring安装(已安装的插件在Installed中显示),一直按步骤确定就好了,如果中途下载超时什么的,就看看自己的网 ...

  6. SpringMVC由浅入深day01_6源码分析(了解)

    6 源码分析(了解) 通过前端控制器源码分析springmvc的执行过程. 入口 第一步:前端控制器接收请求 调用doDiapatch 第二步:前端控制器调用处理器映射器查找 Handler 第三步: ...

  7. logback 实例

    POM : <!-- log --> <dependency> <groupId>org.slf4j</groupId> <artifactId& ...

  8. [AX]AX2012 R2 采购订单的“Request change”

    在采购订单List或者Detail窗口的操作面板上有一个叫做“Request change”的按钮,如果这个按钮是激活的,采购订单不能直接编辑,而必须先使用这个按钮请求修改后,采购订单才能进入编辑状态 ...

  9. ios开发之--新手引导页图片适配方案

    1,图片适配,最早以前是自己命名规范,例如@1x,@2x,@3x等,3套图基本上就够用了 2,在iPhone X之后,需要适配的图就多了,因为分辨率增多了,屏幕尺寸也增多了 3,尺寸 :640*960 ...

  10. 在CentOS Linux下部署Activemq 5

    准备:安装之前首先安装jdk-1.7.x及以上版本 配置/etc/sysconfig/network文件 和/etc/hosts文件,把主机名的解析做清楚: 如: # cat /etc/sysconf ...