web-dev-qa-db-ja.com

私のIOSアプリケーションが更新されているかどうかを確認してください

アプリが最初にインストールされたときにのみ表示されるビューを作成して、更新後に再び表示する必要があるため、アプリが更新されているかどうかをいつ起動するかを確認する必要があります。

21
user2412870

値(現在のアプリのバージョン番号など)をNSUserDefaultsに保存し、ユーザーがアプリを起動するたびに確認できます。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ...

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString *currentAppVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    NSString *previousVersion = [defaults objectForKey:@"appVersion"];
    if (!previousVersion) {
        // first launch

        // ...

        [defaults setObject:currentAppVersion forKey:@"appVersion"];
        [defaults synchronize];
    } else if ([previousVersion isEqualToString:currentAppVersion]) {
        // same version
    } else {
        // other version

        // ...

        [defaults setObject:currentAppVersion forKey:@"appVersion"];
        [defaults synchronize];
    }



    return YES;
}

Swift-2 バージョンは次のようになります。

let defaults = NSUserDefaults.standardUserDefaults()

let currentAppVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") as! String
let previousVersion = defaults.stringForKey("appVersion")
if previousVersion == nil {
    // first launch
    defaults.setObject(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
} else if previousVersion == currentAppVersion {
    // same version
} else {
    // other version
    defaults.setObject(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
}

Swift- バージョンは次のようになります。

let defaults = UserDefaults.standard

let currentAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
let previousVersion = defaults.string(forKey: "appVersion")
if previousVersion == nil {
    // first launch
    defaults.set(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
} else if previousVersion == currentAppVersion {
    // same version
} else {
    // other version
    defaults.set(currentAppVersion, forKey: "appVersion")
    defaults.synchronize()
}
46
tilo

アプリのバージョン番号をNSUserDefaultsに保存し、アプリを起動するたびに確認できます。番号が利用できない場合は、新規インストールです。変更された場合はアップグレードです。

6
Vignesh

Swift 受け入れられた回答よりも重要な改善が加えられたバージョン:

  • infoDictionaryの代わりにobjectForInfoDictionaryKeyを使用すると、結果がデバイス言語から独立していることが保証されます。そうしないと、実際にはデバイス言語の変更であるにもかかわらず、アップグレードがあると信じてしまうことがまれにあります。
  • 正確に何が保存されているかを明確にするために、メインのバンドルinfoDictionaryと同じUserDefaultsキーを使用する
  • 因数分解設定currentVersionコード
  • Swift3構文

コード:

    let standardUserDefaults = UserDefaults.standard
    let shortVersionKey = "CFBundleShortVersionString"
    let currentVersion = Bundle.main.infoDictionary![shortVersionKey] as! String
    let previousVersion = standardUserDefaults.object(forKey: shortVersionKey) as? String
    if previousVersion == currentVersion {
        // same version
    } else {
        // replace with `if let previousVersion = previousVersion {` if you need the exact value
        if previousVersion != nil {
            // new version
        } else {
            // first launch
        }
        standardUserDefaults.set(currentVersion, forKey: shortVersionKey)
        standardUserDefaults.synchronize()
    }
3
Cœur

Swift 3.x

アプリの起動時にAppVersionUpdateNotifierを初期化し、AppUpdateNotifierプロトコルに準拠するだけです。お楽しみください。

使用: Swift 3.x

extension AppDelegate: AppUpdateNotifier {
    func onVersionUpdate(newVersion: Int, oldVersion: Int) {
        // do something
    }

    func onFirstLaunch() {
        //do something
    }
}
    class AppVersionUpdateNotifier {
        static let KEY_APP_VERSION = "key_app_version"
        static let shared = AppVersionUpdateNotifier()

        private let userDefault:UserDefaults
        private var delegate:AppUpdateNotifier?

        private init() {
            self.userDefault = UserDefaults.standard
        }

        func initNotifier(_ delegate:AppUpdateNotifier) {
            self.delegate = delegate
            checkVersionAndNotify()
        }

        private func checkVersionAndNotify() {
            let versionOfLastRun = userDefault.object(forKey: AppVersionUpdateNotifier.KEY_APP_VERSION) as? Int
            let currentVersion = Int(Bundle.main.buildVersion)!

            if versionOfLastRun == nil {
                // First start after installing the app
                delegate?.onFirstLaunch()
            } else if versionOfLastRun != currentVersion {
                // App was updated since last run
                delegate?.onVersionUpdate(newVersion: currentVersion, oldVersion: versionOfLastRun!)
            } else {
                // nothing changed

            }
            userDefault.set(currentVersion, forKey: AppVersionUpdateNotifier.KEY_APP_VERSION)
        }
    }

    protocol AppUpdateNotifier {
        func onFirstLaunch()
        func onVersionUpdate(newVersion:Int, oldVersion:Int)
    }
    extension Bundle {
        var shortVersion: String {
            return infoDictionary!["CFBundleShortVersionString"] as! String
        }
        var buildVersion: String {
            return infoDictionary!["CFBundleVersion"] as! String
        }
    }
3
SPatel

これは、現在のバージョンが異なるかどうかを知るための簡単なコードです(このコードはシミュレーターでも機能します)。

-(BOOL) needsUpdate
{
    NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
    NSString* appID = infoDictionary[@"CFBundleIdentifier"];
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://iTunes.Apple.com/lookup?bundleId=%@", appID]];
    NSData* data = [NSData dataWithContentsOfURL:url];
    NSDictionary* lookup = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

   if ([lookup[@"resultCount"] integerValue] == 1)
   {
       NSString* appStoreVersion = lookup[@"results"][0][@"version"];
       NSString* currentVersion = infoDictionary[@"CFBundleShortVersionString"];
       if (![appStoreVersion isEqualToString:currentVersion])
       {
           NSLog(@"Need to update [%@ != %@]", appStoreVersion, currentVersion);
           return YES;
       }
    }
    return NO;
}

注:iTunesに新しいバージョンを入力するときは、リリースするアプリのバージョンと一致していることを確認してください。そうでない場合、上記のコードは、ユーザーが更新したかどうかに関係なく、常にYESを返します。

1
Pramod

小規模なアプリケーションの場合は答えが良いと思いますが、ロードマップが長い大規模なiOSアプリで作業する場合は、次のような利点を備えた強力で未来的なソリューションが間違いなく必要です。

  1. すべての可能性(2.0/2.0.0など)で正常に機能するロジックをより適切に比較します。
  2. 移行中に特定のアクションを実行します。ユーザーがバージョン1.0から2.0に移行する場合と1.1から2.0に移行する場合を想定します。
  3. ユーザーがアプリをリセットしたときに、キャッシュされたバージョンをリセットします(ログアウト)。

以下は、iOSアプリの1つで使用したコードスニペットです。

public enum VersionConfigResponse {
    case freshInstalled
    case versionGreater
    case versionEqualOrLesser
    case currentVersionEmpty
}


/*
 Config manager responsible to handle the change needs to be done when user migrate from one Version to another Version.
 */
public class VersionConfig {

    public static let shared = VersionConfig()
    private init() { }
    private let versionKey = "SAVED_SHORT_VERSION_STRING"

    /*
     Cache the existing version for compare during next app launch.
     */
    private var storedVersion : String?  {
        get {
            return UserDefaults.standard.object(forKey: versionKey) as? String
        } set {
            UserDefaults.standard.set(newValue, forKey: versionKey)
            UserDefaults.standard.synchronize()
        }
    }

    /*
     Validate the current version with saved version, if greater do clean.
     */
    public func validate(currentVersion: String?) -> VersionConfigResponse  {
        guard let currentVersion = currentVersion else {
            return .currentVersionEmpty
        }

        guard let sVersion = storedVersion else {
            self.storedVersion = currentVersion
            self.freshInstalled()
            return .freshInstalled
        }

        if currentVersion.compare(sVersion, options: .numeric, range: nil, locale: nil) == .orderedDescending    {
            self.storedVersion = currentVersion
            self.userMigrated(fromVersion: sVersion, toVersion:currentVersion)
            return .versionGreater
        } else {
            return .versionEqualOrLesser
        }
    }

    private func userMigrated(fromVersion: String, toVersion: String)   {
        //take your action here...
    }

    private func freshInstalled()   {
        //take your action here...
    }

    /*
     Remove saved version if user reset(logout) the app.
     */
    public func reset() {
        self.storedVersion = nil
    }
}


//trigger version config with current version
VersionConfig.shared.validate(currentVersion: "1.0.0")

//reset when user logsout
VersionConfig.shared.reset()
0
Buntylm

この問題の解決に役立つパッケージを作成しました BundleInfoVersioning Swift.

CFBundleVersionCFBundleShortVersionStringなどの情報ディクショナリ内のすべてのキー、およびNSAgora/DatabaseVersionなどのカスタムキーパスで機能します。

例:

let bundleInfoVersioning = BundleInfoVersioning(bundle: .main)

bundleInfoVersioning.check(forKeyPath: "CFBundleVersion") { (old: String?, new: String?) in
    if old == nil {
        Analytics.install(version: new)
    }
    else {
        Analytics.update(from: old, to: new)
    }
}

bundleInfoVersioning.check(forKeyPath: "CFBundleShortVersionString") { _ , newVersion in
    self.showWhatsNew(in: newVersion)
}

bundleInfoVersioning.check(forKeyPath: "NSAgora/DatabaseVersion") { (old: Int?, new: Int?) in
    self.resetDataBase()
}

Githubの https://github.com/nsagora/bundle-info-versioning で確認できます。

0
alexcristea