我將用新的數據結構向我的應用程序發送更新,因此如果用戶正在更新我的應用程序,我需要更新其當前數據。所以我想知道如何以編程方式告訴用戶是否更新了我的應用程序或安裝了新的副本(如果安裝了新副本,我不需要更新任何內容)?如何知道用戶是否已更新應用程序或安裝了新的副本?
12
A
回答
7
這取決於您使用的數據結構的類型。
一般來說,我建議你不要依靠檢查你的應用程序版本:使用2.0的用戶可能剛剛升級或它可能是一個新用戶。
我寧願檢查是否已經有數據結構,並採取相應的行動。假設您使用的是Sqlite支持的Core Data存儲,您可以檢查.sqlite文件是否存在,或者檢查存儲中是否有對象。
3
只是保存在某個地方的捆綁版本,並檢查它是否從
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]
不同,每個應用程序的啓動。
7
檢查數據結構是一個可靠的解決方案。我開始擔心在我自己的應用程序中關於不升級幾個版本的人。我覺得這會導致無數的結構檢查。我在下面顯示的代碼確定並存儲NSUserDefaults
中的版本和以前的版本。如果需要,您可以編寫這些不同版本的差異方案。
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
BOOL versionUpgraded;
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
NSString *preVersion = [prefs stringForKey:@"appVersion"];
if ([prefs stringForKey:@"appVersion"] != nil) {
//see if version is the same as prior
//if not it is an Upgraded
versionUpgraded = !([preVersion isEqualToString: version]);
} else {
//nil means new install
//This needs to be YES for the case that
//"appVersion" is not set anywhere else.
versionUpgraded = YES;
}
if (versionUpgraded) {
[prefs setObject:version forKey:@"appVersion"];
[prefs setObject:preVersion forKey:@"prevAppVersion"];
[prefs synchronize];
}
0
我爲此創建了一個類別。只需實現標題中找到的兩個新的委託調用即可。它非常依賴obj-c運行時庫,所以在使用它之前確保你對它們有信心。
.H
#import <UIKit/UIKit.h>
@protocol UIApplicationDelegate <UIApplicationDelegate>
@optional
- (void) application:(UIApplication *)application willUpdateToVersion: (NSString*) newVersion fromVersion: (NSString*) previousVersion;
- (void) application:(UIApplication *)application didUpdateToVersion: (NSString*) newVersion fromVersion: (NSString*) previousVersion;
@end
@interface UIApplication (Versioning)
@end
.M
#import "UIApplication+Versioning.h"
#import <objc/message.h>
#import <objc/runtime.h>
static NSString* UIApplicationVersionFileName = @"app.ver";
@implementation UIApplication (Versioning)
+ (void) load {
Method original, swizzled;
original = class_getInstanceMethod(self, @selector(setDelegate:));
swizzled = class_getInstanceMethod(self, @selector(swizzled_setDelegate:));
method_exchangeImplementations(original, swizzled);
}
- (void) swizzled_setDelegate: (id<UIApplicationDelegate>) delegate {
IMP implementation = class_getMethodImplementation([self class], @selector(swizzled_application:didFinishLaunchingWithOptions:));
class_addMethod([delegate class], @selector(swizzled_application:didFinishLaunchingWithOptions:), implementation, "[email protected]:@@");
Method original, swizzled;
original = class_getInstanceMethod([delegate class], @selector(application:didFinishLaunchingWithOptions:));
swizzled = class_getInstanceMethod([delegate class], @selector(swizzled_application:didFinishLaunchingWithOptions:));
method_exchangeImplementations(original, swizzled);
[self swizzled_setDelegate: delegate];
}
- (BOOL)swizzled_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Check for a version change
NSError* error;
NSArray* directories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* versionFilePath = [[directories objectAtIndex: 0] stringByAppendingPathComponent: UIApplicationVersionFileName];
NSString* oldVersion = [NSString stringWithContentsOfFile: versionFilePath
encoding: NSUTF8StringEncoding
error: &error];
NSString* currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleVersion"];
switch (error.code) {
case NSFileReadNoSuchFileError:
{
//Delegate methods will not be called first time
oldVersion = [currentVersion copy];
[currentVersion writeToFile: versionFilePath
atomically: YES
encoding: NSUTF8StringEncoding
error: &error];
break;
}
default:
{
NSLog(@"Warning: An error occured will loading the application version file -> Recreating file");
[[NSFileManager defaultManager] removeItemAtPath: versionFilePath
error: nil];
oldVersion = [currentVersion copy];
[currentVersion writeToFile: versionFilePath
atomically: YES
encoding: NSUTF8StringEncoding
error: &error];
break;
}
}
if(![oldVersion isEqualToString: currentVersion]) {
if ([[application delegate] respondsToSelector: @selector(application:willUpdateToVersion:fromVersion:)]) {
objc_msgSend([application delegate], @selector(application:willUpdateToVersion:fromVersion:), currentVersion, oldVersion);
}
[currentVersion writeToFile: versionFilePath
atomically: YES
encoding: NSUTF8StringEncoding
error: &error];
if ([[application delegate] respondsToSelector: @selector(application:didUpdateToVersion:fromVersion:)]) {
objc_msgSend([application delegate], @selector(application:willUpdateToVersion:fromVersion:), currentVersion, oldVersion);
}
}
SEL realSelector = @selector(swizzled_application:didFinishLaunchingWithOptions:);
return (BOOL) objc_msgSend([application delegate], realSelector, application, launchOptions);
}
@end
相關問題
- 1. 檢查應用程序是否已更新或新安裝
- 2. 您知道用戶是否第一次安裝您的應用程序,或者他是否進行了更新?
- 3. 如何知道應用程序已安裝或重新安裝在設備中
- 4. 知道是否爲「所有用戶」安裝了應用程序
- 5. 如何判斷iOS應用程序是否已新安裝或更新?
- 6. android:檢查應用程序是否已更新或新用戶
- 7. Android:您可以檢查應用程序安裝是否新鮮或已安裝應用程序的舊版本?
- 8. 如何知道行是否已更新
- 9. 我如何知道我的最新版本的Android應用已更新爲所有安裝的用戶?
- 10. android知道是否安裝了應用程序
- 11. Android/Google +如何知道用戶的朋友是否已經安裝了應用程序
- 12. 當應用程序更新或重新安裝時,user_dim.first_open_timestamp_micros是否更改?
- 13. 如何確定用戶是否安裝了iOS應用程序?
- 14. 如何檢查用戶是否安裝了應用程序?
- 15. 我如何知道應用程序是否已經安裝在iPhone上從Safari
- 16. 如何知道應用程序是否已成功安裝在Android中
- 17. 如何檢查應用程序是否已更新或全新安裝在Windows Phone 8中?
- 18. 如何知道用戶是否安裝了我的.apk失敗或成功?
- 19. 如何從客戶端知道表是否已更新
- 20. 如何知道Android應用程序是否被重新部署?
- 21. 如何檢查應用程序是否已安裝或正在首次安裝
- 22. Android應用程序 - 用戶是否自動通知新版本
- 23. 確定是否新安裝或更新
- 24. 如何知道我的Ubuntu是否安裝了LAMP或XAMPP?
- 25. 檢查用戶是否已安裝我的Facebook應用程序
- 26. 如何區分應用程序是已更新還是首次安裝?
- 27. 知道用戶是否啓動了應用程序
- 28. 如何知道應用程序池是否已遠程啓動?
- 29. 我如何知道用戶是「升級」還是「安裝」android應用程序?
- 30. BizTalk應用程序未能安裝:「已安裝的應用程序的更新版本」
什麼 '數據結構' 您使用的?核心數據? – magma 2011-05-17 17:31:54