0001    // VersionTracking.swift
0002    //
0003    // Copyright (c) 2016 Tom Baranes
0004    //
0005    // Permission is hereby granted, free of charge, to any person obtaining a copy
0006    // of this software and associated documentation files (the "Software"), to deal
0007    // in the Software without restriction, including without limitation the rights
0008    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0009    // copies of the Software, and to permit persons to whom the Software is
0010    // furnished to do so, subject to the following conditions:
0011    //
0012    // The above copyright notice and this permission notice shall be included in
0013    // all copies or substantial portions of the Software.
0014    //
0015    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0018    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0021    // THE SOFTWARE.
0022    
0023    import Foundation
0024    
0025    private let kUserDefaultsVersionHistory
VersionTracker.swift:119
        if let versionHistory = NSUserDefaults.standardUserDefaults().dictionaryForKey(kUserDefaultsVersionHistory) as? [String: [String]] {
VersionTracker.swift:137
            NSUserDefaults.standardUserDefaults().setObject(versions, forKey: kUserDefaultsVersionHistory)
= "kVTVersionHistory" 0026 private let kVersionsKey
VersionTracker.swift:84
        guard let versionHistory = sharedInstance.versions[kVersionsKey] else {
VersionTracker.swift:122
            versions = [kVersionsKey: [String](), kBuildsKey: [String]()]
VersionTracker.swift:144
        if versions[kVersionsKey]?.contains(currentVersion) == false {
VersionTracker.swift:145
            versions[kVersionsKey]?.append(currentVersion)
VersionTracker.swift:161
        guard let versionsHistory = versions[kVersionsKey] else {
VersionTracker.swift:175
        guard let versionsHistory = versions[kVersionsKey] where versionsHistory.count >= 2 else {
= "kVTVersions" 0027 private let kBuildsKey
VersionTracker.swift:105
        guard let buildHistory = sharedInstance.versions[kBuildsKey] else {
VersionTracker.swift:122
            versions = [kVersionsKey: [String](), kBuildsKey: [String]()]
VersionTracker.swift:152
        if versions[kBuildsKey]?.contains(currentBuild) == false {
VersionTracker.swift:153
            versions[kBuildsKey]?.append(currentBuild)
VersionTracker.swift:168
        guard let buildHistory = versions[kBuildsKey] else {
VersionTracker.swift:182
        guard let buildsHistory = versions[kBuildsKey] where buildsHistory.count >= 2 else {
= "kVTBuilds" 0028 0029 public struct VersionTracking
VersionTracker.swift:33
    static var sharedInstance = VersionTracking()
VersionTracker.swift:129
private extension VersionTracking {
VersionTracker.swift:143
        let currentVersion = VersionTracking.currentVersion()
VersionTracker.swift:151
        let currentBuild = VersionTracking.currentBuild()
{ 0030 0031 public typealias FirstLaunch
VersionTracker.swift:45
    public static func isFirstLaunchForVersion(version: String = "", firstLaunch: FirstLaunch? = nil) -> Bool {
VersionTracker.swift:57
    public static func isFirstLaunchForBuild(build: String = "", firstLaunch: FirstLaunch? = nil) -> Bool {
= () -> Void 0032 0033 static var sharedInstance
VersionTracker.swift:38
        sharedInstance.startTracking()
VersionTracker.swift:42
        return sharedInstance.firstLaunchEver
VersionTracker.swift:46
        var isFirstVersion = sharedInstance.firstLaunchForVersion
VersionTracker.swift:48
            isFirstVersion = sharedInstance.historyContainsVersion(version)
VersionTracker.swift:58
        var isFirstBuild = sharedInstance.firstLaunchForBuild
VersionTracker.swift:60
            isFirstBuild = sharedInstance.historyContainsBuild(build)
VersionTracker.swift:80
        return sharedInstance.previousVersion()
VersionTracker.swift:84
        guard let versionHistory = sharedInstance.versions[kVersionsKey] else {
VersionTracker.swift:101
        return sharedInstance.previousBuild()
VersionTracker.swift:105
        guard let buildHistory = sharedInstance.versions[kBuildsKey] else {
= VersionTracking() 0034 0035 // MARK: - Tracker 0036 0037 public static func track() { 0038 sharedInstance.startTracking() 0039 } 0040 0041 public static func isFirstLaunchEver() -> Bool { 0042 return sharedInstance.firstLaunchEver 0043 } 0044 0045 public static func isFirstLaunchForVersion(version: String = "", firstLaunch: FirstLaunch? = nil) -> Bool { 0046 var isFirstVersion = sharedInstance.firstLaunchForVersion 0047 if version != "" { 0048 isFirstVersion = sharedInstance.historyContainsVersion(version) 0049 } 0050 0051 if let closure = firstLaunch where isFirstVersion == true{ 0052 closure() 0053 } 0054 return isFirstVersion 0055 } 0056 0057 public static func isFirstLaunchForBuild(build: String = "", firstLaunch: FirstLaunch? = nil) -> Bool { 0058 var isFirstBuild = sharedInstance.firstLaunchForBuild 0059 if build != "" { 0060 isFirstBuild = sharedInstance.historyContainsBuild(build) 0061 } 0062 0063 if let closure = firstLaunch where isFirstBuild == true { 0064 closure() 0065 } 0066 return isFirstBuild 0067 } 0068 0069 // MARK: - Version 0070 0071 public static func currentVersion
VersionTracker.swift:143
        let currentVersion = VersionTracking.currentVersion()
() -> String { 0072 let currentVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") 0073 if let version = currentVersion as? String { 0074 return version 0075 } 0076 return "" 0077 } 0078 0079 public static func previousVersion() -> String? { 0080 return sharedInstance.previousVersion() 0081 } 0082 0083 public static func versionHistory() -> [String] { 0084 guard let versionHistory = sharedInstance.versions[kVersionsKey] else { 0085 return [] 0086 } 0087 return versionHistory 0088 } 0089 0090 // MARK: - Build 0091 0092 public static func currentBuild
VersionTracker.swift:151
        let currentBuild = VersionTracking.currentBuild()
() -> String { 0093 let currentVersion = NSBundle.mainBundle().objectForInfoDictionaryKey(kCFBundleVersionKey as String) 0094 if let version = currentVersion as? String { 0095 return version 0096 } 0097 return "" 0098 } 0099 0100 public static func previousBuild() -> String? { 0101 return sharedInstance.previousBuild() 0102 } 0103 0104 public static func buildHistory() -> [String] { 0105 guard let buildHistory = sharedInstance.versions[kBuildsKey] else { 0106 return [] 0107 } 0108 return buildHistory 0109 } 0110 0111 // MARK: Private 0112 0113 private var versions
VersionTracker.swift:84
        guard let versionHistory = sharedInstance.versions[kVersionsKey] else {
VersionTracker.swift:105
        guard let buildHistory = sharedInstance.versions[kBuildsKey] else {
VersionTracker.swift:120
            versions = versionHistory
VersionTracker.swift:122
            versions = [kVersionsKey: [String](), kBuildsKey: [String]()]
VersionTracker.swift:137
            NSUserDefaults.standardUserDefaults().setObject(versions, forKey: kUserDefaultsVersionHistory)
VersionTracker.swift:144
        if versions[kVersionsKey]?.contains(currentVersion) == false {
VersionTracker.swift:145
            versions[kVersionsKey]?.append(currentVersion)
VersionTracker.swift:152
        if versions[kBuildsKey]?.contains(currentBuild) == false {
VersionTracker.swift:153
            versions[kBuildsKey]?.append(currentBuild)
VersionTracker.swift:161
        guard let versionsHistory = versions[kVersionsKey] else {
VersionTracker.swift:168
        guard let buildHistory = versions[kBuildsKey] else {
VersionTracker.swift:175
        guard let versionsHistory = versions[kVersionsKey] where versionsHistory.count >= 2 else {
VersionTracker.swift:182
        guard let buildsHistory = versions[kBuildsKey] where buildsHistory.count >= 2 else {
: [String: [String]] 0114 private var firstLaunchEver
VersionTracker.swift:42
        return sharedInstance.firstLaunchEver
VersionTracker.swift:123
            firstLaunchEver = true
: Bool = false 0115 private var firstLaunchForVersion
VersionTracker.swift:46
        var isFirstVersion = sharedInstance.firstLaunchForVersion
VersionTracker.swift:136
        if firstLaunchForVersion || firstLaunchForBuild {
VersionTracker.swift:146
            firstLaunchForVersion = true
: Bool = false 0116 private var firstLaunchForBuild
VersionTracker.swift:58
        var isFirstBuild = sharedInstance.firstLaunchForBuild
VersionTracker.swift:136
        if firstLaunchForVersion || firstLaunchForBuild {
VersionTracker.swift:154
            firstLaunchForBuild = true
: Bool = false 0117 0118 private init
VersionTracker.swift:33
    static var sharedInstance = VersionTracking()
() { 0119 if let versionHistory = NSUserDefaults.standardUserDefaults().dictionaryForKey(kUserDefaultsVersionHistory) as? [String: [String]] { 0120 versions = versionHistory 0121 } else { 0122 versions = [kVersionsKey: [String](), kBuildsKey: [String]()] 0123 firstLaunchEver = true 0124 } 0125 } 0126 0127 } 0128 0129 private extension VersionTracking { 0130 0131 // MARK: - Initializer 0132 0133 mutating func startTracking
VersionTracker.swift:38
        sharedInstance.startTracking()
() { 0134 updateFirstLaunchForVersion() 0135 updateFirstLaunchForBuild() 0136 if firstLaunchForVersion || firstLaunchForBuild { 0137 NSUserDefaults.standardUserDefaults().setObject(versions, forKey: kUserDefaultsVersionHistory) 0138 NSUserDefaults.standardUserDefaults().synchronize() 0139 } 0140 } 0141 0142 mutating func updateFirstLaunchForVersion
VersionTracker.swift:134
        updateFirstLaunchForVersion()
() { 0143 let currentVersion = VersionTracking.currentVersion() 0144 if versions[kVersionsKey]?.contains(currentVersion) == false { 0145 versions[kVersionsKey]?.append(currentVersion) 0146 firstLaunchForVersion = true 0147 } 0148 } 0149 0150 mutating func updateFirstLaunchForBuild
VersionTracker.swift:135
        updateFirstLaunchForBuild()
() { 0151 let currentBuild = VersionTracking.currentBuild() 0152 if versions[kBuildsKey]?.contains(currentBuild) == false { 0153 versions[kBuildsKey]?.append(currentBuild) 0154 firstLaunchForBuild = true 0155 } 0156 } 0157 0158 // MARK: - Helper 0159 0160 private func historyContainsVersion
VersionTracker.swift:48
            isFirstVersion = sharedInstance.historyContainsVersion(version)
(version: String) -> Bool { 0161 guard let versionsHistory = versions[kVersionsKey] else { 0162 return false 0163 } 0164 return versionsHistory.contains(version) 0165 } 0166 0167 private func historyContainsBuild
VersionTracker.swift:60
            isFirstBuild = sharedInstance.historyContainsBuild(build)
(build: String) -> Bool { 0168 guard let buildHistory = versions[kBuildsKey] else { 0169 return false 0170 } 0171 return buildHistory.contains(build) 0172 } 0173 0174 private func previousBuild
VersionTracker.swift:101
        return sharedInstance.previousBuild()
() -> String? { 0175 guard let versionsHistory = versions[kVersionsKey] where versionsHistory.count >= 2 else { 0176 return nil 0177 } 0178 return versionsHistory[versionsHistory.count - 2] 0179 } 0180 0181 private func previousVersion
VersionTracker.swift:80
        return sharedInstance.previousVersion()
() -> String? { 0182 guard let buildsHistory = versions[kBuildsKey] where buildsHistory.count >= 2 else { 0183 return nil 0184 } 0185 return buildsHistory[buildsHistory.count - 2] 0186 } 0187 0188 } 0189 0190