2010-11-03 47 views
11

我打算在应用程序商店开放一个应用程序商店,我想为现有用户免费提供一些商品。如何确定第一次安装或使用应用程序的日期?

我想发布一个更新,它会在第一次使用该应用程序时存储一些信息,然后发布看看该应用程序是否曾被购买过的“真实”更新,但是,可能不是每个人都会选择第一次更新。

那么,有没有办法找出用户刚刚安装 (或使用过) 应用程序的时间?

更新:

感谢您的答案,但我应该做的不那么暧昧:

我在寻找类似办呢本地呼叫/任何东西。由于该应用程序已在商店中,并且我没有设置任何信息来将数据存储在第一个版本上,所以如果在第二次更新发布之前所有用户都抓住它,则更新将帮助我做我想做的事情:不可能将新用户与已经错过了中间更新并刚更新到最新用户的现有用户区分开来。

+0

你是怎么解决这个问题的?如何检查最后修改日期? – Brandon 2010-11-11 12:47:38

+0

它似乎还没有解决,因为我的程序中有一些其他的错误,它现在工作的很好。我不知道如果用户删除应用程序然后在未来恢复它,会发生什么,但我找不到更好的方法。 – felace 2010-11-17 14:03:40

+0

你看看@medTechy的答案,我认为检查用户应用程序文档目录的创建日期似乎是正确的解决方案!? – 2013-10-28 19:08:04

回答

9

我的解决方案是检查应用程序包中某个文件的最后修改日期。

NSString *sourceFile = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Icon.png"]; 

NSDate *lastModif = [[[NSFileManager defaultManager] attributesOfItemAtPath:sourceFile error:&err] objectForKey:NSFileModificationDate]; 
+1

看起来像你应该检查创建日期看到,因为你可能会更新图标,然后提交一个新的构建,而不是想这个检查。 – mxcl 2011-05-20 13:40:25

+2

不幸的是,如果你不得不这样做的更新,它会显示更新后的新日期:( – Ondrej 2011-12-19 14:56:51

+0

任何人都有线索如何在Android上做到这一点? – 2015-09-21 16:43:41

1

我建议在首次启动时设置一个日期并将其存储在NSUserDefaults中。找到启动日期,如果它不在那里,请设置它。如果是,请根据您的计划进行一些日期比较并处理其他日期。

10
NSDate *installDate = [[NSUserDefaults standardUserDefaults]objectForKey:@"installDate"]; 

if (!installDate) { 
    //no date is present 
    //this app has not run before 
    NSDate *todaysDate = [NSDate date]; 
    [[NSUserDefaults standardUserDefaults]setObject:todaysDate forKey:@"installDate"]; 
    [[NSUserDefaults standardUserDefaults]synchronize]; 

    //nothing more to do? 
} else { 
    //date is found 
    NSDate *todaysDate = [NSDate date]; 
    //compare todaysDate with installDate 
    //if enough time has passed, yada yada, 
    //apply updates, etc. 
} 
+0

甜解决,贾斯汀!偶然发现它从谷歌和它正是我一直在寻找。:) – Eric 2011-01-05 16:54:25

+0

的问题与此是,用户可能不会在安装它的同一天运行应用程序。 例如,在技术上,他可以在一月份安装该应用程序并在三月运行该应用程序,在这种情况下,'NSUserDefault'键将存储错误的日期(3月)。 – 2014-02-20 12:57:05

+0

确实如此,但从语义上讲,我们可以将installDate布尔更改为“firstRun”。没有办法知道绝对安装日期。除了我下面的人之外,说明docs目录的创建日期对于安装是正确的。整洁 – Justin 2014-02-20 15:23:23

0

您可以随时检查服务器。它过去使用UDID很简单,但由于这些已被弃用,所以你已经创建了一个UUID(CFUUIDCreate()或类似的:))并将其存储在钥匙串中,即使用户将删除应用程序,并在一年后再次安装...我发现这种形式第一次处理钥匙串值时非常有帮助: http://useyourloaf.com/blog/2010/3/29/simple-iphone-keychain-access.html

1

回答了解人们是否可以在此找到问题。这似乎比别人我在这里找到更长的时间,但它告诉你,如果应用程序是因为更新运行的第一次(为此,你必须改变你的info.plist)...

// called during startup, compares the current version string with the one stored on standardUserDefaults 
+ (BOOL)isFreshInstallOrUpdate 
{ 
    BOOL ret = YES; 
    NSString *cfBundleVersionStored = [[NSUserDefaults standardUserDefaults] objectForKey:@"CFBundleVersion"]; 
    NSString *cfBundleShortVersionStringStored = [[NSUserDefaults standardUserDefaults] objectForKey:@"CFBundleShortVersionString"]; 

    NSString *cfBundleVersionPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];; 
    NSString *cfBundleShortVersionStringPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey: 
               @"CFBundleShortVersionString"]; 

    ret = [cfBundleVersionPlist compare:cfBundleVersionStored] != NSOrderedSame || 
    [cfBundleShortVersionStringPlist compare:cfBundleShortVersionStringStored] != NSOrderedSame; 

    return ret; 
} 


// calling this once will necessarily cause isFreshInstall to return false 
+ (void)setStoredVersionNumber 
{ 
    NSString *cfBundleVersionPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 
    NSString *cfBundleShortVersionStringPlist = [[NSBundle mainBundle] objectForInfoDictionaryKey: 
               @"CFBundleShortVersionString"]; 

    [[NSUserDefaults standardUserDefaults] setObject:cfBundleVersionPlist forKey:@"CFBundleVersion"]; 
    [[NSUserDefaults standardUserDefaults] setObject:cfBundleShortVersionStringPlist forKey:@"CFBundleShortVersionString"]; 

    // setting now as unfresh! 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 
29

要获得安装日期,检查Documents文件夹的创建日期。

NSURL* urlToDocumentsFolder = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
__autoreleasing NSError *error; 
NSDate *installDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:urlToDocumentsFolder.path error:&error] objectForKey:NSFileCreationDate]; 

NSLog(@"This app was installed by the user on %@", installDate); 

为了得到最后的应用程序更新日期,检查应用程序的修改日期捆绑本身

NSString* pathToInfoPlist = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"]; 
NSString* pathToAppBundle = [pathToInfoPlist stringByDeletingLastPathComponent]; 
NSDate *updateDate = [[[NSFileManager defaultManager] attributesOfItemAtPath:pathToAppBundle error:&error] objectForKey:NSFileModificationDate]; 

NSLog(@"This app was updated by the user on %@", updateDate); 
+0

这似乎是正确的解决方案,任何机构知道为什么这不能工作? – 2013-10-28 19:08:27

+0

在这个轻微的错字,pathToDocumentsFolder应该是一个NSURL对象。然后,您将在attributesOfItemAtPath方法中引用它时使用.path访问器。否则,这似乎很好。 – steemcb 2014-03-14 16:07:10

+0

谢谢!修正了错字。 – 2014-03-14 21:51:54

0

迅速解决:

let urlToDocumentsFolder = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last! 
//installDate is NSDate of install 
let installDate = (try! NSFileManager.defaultManager().attributesOfItemAtPath(urlToDocumentsFolder.path!)[NSFileCreationDate]) 
print("This app was installed by the user on \(installDate)") 
1

应用程序生成日期:

public var appBuildDate: Date { 
    if let path = Bundle.main.path(forResource: "Info", ofType: "plist") { 
    if let createdDate = try! FileManager.default.attributesOfItem(atPath: path)[.creationDate] as? Date { 
     return createdDate 
    } 
    } 
    return Date() // Should never execute 
} 

应用程序安装d吃了:

public var appInstallDate: Date { 
    if let documentsFolder = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last { 
    if let installDate = try! FileManager.default.attributesOfItem(atPath: documentsFolder.path)[.creationDate] as? Date { 
     return installDate 
    } 
    } 
    return Date() // Should never execute 
} 
相关问题