检测 iOS 应用程序的首次启动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27208103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect first launch of iOS app
提问by Julian Stellaard
I am trying to find a way in Swift to detect the first launch.
我试图在 Swift 中找到一种方法来检测第一次启动。
回答by Jon Shier
Typically you would write a value to NSUserDefaults to indicate that an app has launched before.
通常,您会向 NSUserDefaults 写入一个值以指示应用程序之前已启动。
let launchedBefore = NSUserDefaults.standardUserDefaults().boolForKey("launchedBefore")
if launchedBefore {
print("Not first launch.")
}
else {
print("First launch, setting NSUserDefault.")
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "launchedBefore")
}
UPDATE - Swift 3
更新 - 斯威夫特 3
let launchedBefore = UserDefaults.standard.bool(forKey: "launchedBefore")
if launchedBefore {
print("Not first launch.")
} else {
print("First launch, setting UserDefault.")
UserDefaults.standard.set(true, forKey: "launchedBefore")
}
回答by n13
I kinda always need this so I put it in a category
我有点总是需要这个所以我把它放在一个类别中
General Usage:
一般用法:
let isFirstLaunch = UserDefaults.isFirstLaunch()
Usage inside your AppDelegate
在您的 AppDelegate 中使用
// use this if you need to refer to it later
var optionallyStoreTheFirstLaunchFlag = false
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
optionallyStoreTheFirstLaunchFlag = UserDefaults.isFirstLaunch()
// .. do whatever else
return true
}
Some important considerations:
一些重要的考虑因素:
- This flag is only set on the first invocation. If you want to know about the first launch multiple times throughout different screens, set a variable you can later refer to, as per the 'optionallyStoreTheFirstLaunchFlag' example.
- In iOS, apps are usually never shut down. Apps are backgrounded, foregrounded, state-saved to flash memory, but they are only relaunched if they're force shutdown by the user (rare) or the user restarts their phone. So if you store it in a variable, it could potentially stick around for a long time. Manually reset it once you're done with showing all the tutorial screens and whatnot.
- 此标志仅在第一次调用时设置。如果您想在不同屏幕上多次了解首次启动,请设置一个您可以稍后参考的变量,如“optionallyStoreTheFirstLaunchFlag”示例。
- 在 iOS 中,应用程序通常永远不会关闭。应用程序是后台的、前台的、状态保存到闪存的,但只有在用户强制关闭(罕见)或用户重新启动手机时,它们才会重新启动。因此,如果将其存储在变量中,它可能会持续很长时间。完成显示所有教程屏幕等内容后,手动重置它。
Swift 4
斯威夫特 4
Put the following in UserDefaults+isFirstLaunch.swift
将以下内容放入 UserDefaults+isFirstLaunch.swift
extension UserDefaults {
// check for is first launch - only true on first invocation after app install, false on all further invocations
// Note: Store this value in AppDelegate if you have multiple places where you are checking for this flag
static func isFirstLaunch() -> Bool {
let hasBeenLaunchedBeforeFlag = "hasBeenLaunchedBeforeFlag"
let isFirstLaunch = !UserDefaults.standard.bool(forKey: hasBeenLaunchedBeforeFlag)
if (isFirstLaunch) {
UserDefaults.standard.set(true, forKey: hasBeenLaunchedBeforeFlag)
UserDefaults.standard.synchronize()
}
return isFirstLaunch
}
}
回答by Roman
Swift 3
斯威夫特 3
extension UserDefaults {
var hasLaunchBefore: Bool {
get {
return self.bool(forKey: #function)
}
set {
self.set(newValue, forKey: #function)
}
}
}
Swift 5(Property wrappers)
Swift 5(属性包装器)
UserDefaultWrapper:
用户默认包装器:
@propertyWrapper
struct UserDefaultWrapper<T> {
let key: String
let defaultValue: T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
var wrappedValue: T {
get {
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
UserDefaultsStore:
用户默认存储:
struct UserDefaultsStore {
@UserDefaultWrapper("has_launch_before", defaultValue: false)
static var hasLaunchBefore: Bool
}
Usage:
用法:
UserDefaultsStore.hasLaunchBefore = false
回答by jalone
I refined a bit user n13 answer in order to
我提炼了一点用户 n13 的答案,以便
- have the method always return true during the whole first launch
- be an extension to UIApplication
- 让该方法在整个首次启动期间始终返回 true
- 成为 UIApplication 的扩展
Just use it wherever you want as UIApplication.isFirstLaunch()
and be sure to reach it at least once during first execution.
只需随心所欲地使用它,UIApplication.isFirstLaunch()
并确保在第一次执行时至少使用一次。
Swift 3
斯威夫特 3
import UIKit
private var firstLaunch : Bool = false
extension UIApplication {
static func isFirstLaunch() -> Bool {
let firstLaunchFlag = "isFirstLaunchFlag"
let isFirstLaunch = UserDefaults.standard.string(forKey: firstLaunchFlag) == nil
if (isFirstLaunch) {
firstLaunch = isFirstLaunch
UserDefaults.standard.set("false", forKey: firstLaunchFlag)
UserDefaults.standard.synchronize()
}
return firstLaunch || isFirstLaunch
}
}
Swift 2
斯威夫特 2
import UIKit
private var firstLaunch : Bool = false
extension UIApplication {
static func isFirstLaunch() -> Bool {
let firstLaunchFlag = "isFirstLaunchFlag"
let isFirstLaunch = NSUserDefaults.standardUserDefaults().stringForKey(firstLaunchFlag) == nil
if (isFirstLaunch) {
firstLaunch = isFirstLaunch
NSUserDefaults.standardUserDefaults().setObject("false", forKey: firstLaunchFlag)
NSUserDefaults.standardUserDefaults().synchronize()
}
return firstLaunch || isFirstLaunch
}
}
回答by matt
Use NSUserDefaults. Register a BOOL key with a value of false
. Read the key at launch time; if it's false
, set it to true
and show the welcome. Next launch, it will be true
, you won't show the welcome, problem solved.
使用NSUserDefaults。注册一个值为 的 BOOL 键false
。在启动时读取密钥;如果是false
,请将其设置为true
并显示欢迎。下次启动,它将是true
,您不会显示欢迎,问题已解决。
回答by Sreedeepkesav M S
In case of Swift In applicationdidFinishLaunchingWithOptions in AppDelegate Add:
如果 Swift 在 applicationdidFinishLaunchingWithOptions 在 AppDelegate 添加:
if UserDefaults.standard.bool(forKey: "isFirstLaunch") {
UserDefaults.standard.set(true, forKey: "isFirstLaunch")
UserDefaults.standard.synchronize()
}
And Use this wherever you want to.
并在您想要的任何地方使用它。
let isFirstLaunch = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool
if isFirstLaunch {
//It's the initial launch of application.
}
else {
// not initial launch
}
回答by Frank Li
you can use UserDefaults to store the times that App has opened
您可以使用 UserDefaults 来存储 App 打开的次数
First:
第一的:
AppDelegate.swift
AppDelegate.swift
let userDefaults = UserDefaults.standard
var currentTimesOfOpenApp:Int = 0
func saveTimesOfOpenApp() -> Void {
userDefaults.set(currentTimesOfOpenApp, forKey: "timesOfOpenApp")
}
func getCurrentTimesOfOpenApp() -> Int {
return userDefaults.integer(forKey: "timesOfOpenApp") + 1
}
each time the App is open, you should add the property currentTimesOfOpenApp, so modify this property in the function func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
每次应用打开时,都应该添加属性currentTimesOfOpenApp,所以在函数func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 中修改这个属性
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.currentTimesOfOpenApp = getCurrentTimesOfOpenApp()
return true
}
in addition, when the app is closed, you should save the currentTimesOfOpenApp, that is important!
另外,当应用程序关闭时,您应该保存currentTimesOfOpenApp,这很重要!
func applicationWillTerminate(_ application: UIApplication) {
saveTimesOfOpenApp()
self.saveContext()
}
Second:
第二:
if you want to show the times, you can get this value form UserDefaults to display it on the Label.
如果要显示时间,可以从 UserDefaults 获取此值以将其显示在 Label 上。
ViewController.swift
视图控制器.swift
let delegate = UIApplication.shared.delegate as! AppDelegate
let times = delegate.currentTimesOfOpenApp
timesToOpenAppLabel.text = "\(times)"
the App is open every time, the currentTimesOfOpenApp will be increase. if you delete the App, this value will be reset as 1.
App 每次打开,currentTimesOfOpenApp 都会增加。如果您删除该应用程序,此值将重置为 1。
回答by Hanny
I did an edit of n13's post. This code seems cleaner to me. You can call as a class or instance function.
我对 n13 的帖子进行了编辑。这段代码对我来说似乎更清晰。您可以作为类或实例函数调用。
Also, according to apple docs you shouldn't call synchronize() since it's called periodically, unless the app is about to close. I have it called in the AppDelegate in applicationDidEnterBackground(). https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/#//apple_ref/occ/instm/NSUserDefaults/synchronize
此外,根据苹果文档,您不应该调用同步(),因为它会定期调用,除非应用程序即将关闭。我在 applicationDidEnterBackground() 的 AppDelegate 中调用了它。https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/#//apple_ref/occ/instm/NSUserDefaults/synchronize
if NSUserDefaults().isFirstLaunchForUser("me") {
print("First launch")
} else {
print("Not first launch")
}
if NSUserDefaults.isFirstLaunch() {
print("First launch")
} else {
print("Not first launch")
}
extension NSUserDefaults {
static func isFirstLaunch() -> Bool {
let firstLaunchFlag = "FirstLaunchFlag"
if !standardUserDefaults().boolForKey(firstLaunchFlag) {
standardUserDefaults().setBool(true, forKey: firstLaunchFlag)
// standardUserDefaults().synchronize()
return true
}
return false
}
// For multi user login
func isFirstLaunchForUser(user: String) -> Bool {
if !boolForKey(user) {
setBool(true, forKey: user)
// synchronize()
return true
}
return false
}
}
回答by Ruslan
let applicationLaunchedOnce: Bool = {
let launchedOnce = NSUserDefaults.standardUserDefaults().boolForKey(UserDefaultsService.ApplicationLaunchedOnce)
if launchedOnce {
return launchedOnce
} else {
NSUserDefaults.standardUserDefaults().setBool(true, forKey: UserDefaultsService.ApplicationLaunchedOnce)
NSUserDefaults.standardUserDefaults().synchronize()
return false
}
}()