Как определить дату, когда приложение установлено или используется в первый раз?

Я планирую открыть в магазине приложений, и я хотел бы предоставить существующим пользователям некоторые из предметов бесплатно.

Я подумал о выпуске обновления, которое будет хранить некоторую информацию при первом использовании приложения, а затем выпустить "реальное" обновление, которое будет выглядеть, если приложение было куплено ранее, однако, скорее всего, не все будут выбирать первое обновление.

Итак, есть ли способ узнать, когда именно пользователь впервые установил (или использовал) приложение?

Обновление:

Спасибо за ответы, но я должен сделать это менее двусмысленным:

Я ищу родной звонок/что-то похожее на это. Поскольку приложение уже находится в хранилище, и я не настроил ничего для хранения данных в первой версии, обновление поможет мне сделать то, что я хочу, если все пользователи возьмут его перед вторым обновлением: невозможно отличить нового пользователя от существующего, который пропустил обновление промежуточного уровня и только что обновился до самого последнего.

Ответ 1

Моим решением было бы проверить последнюю измененную дату одного из файлов в комплекте приложения.

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

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

Ответ 2

Чтобы получить дату установки, проверьте дату создания папки "Документы".

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);

Ответ 3

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.
}

Ответ 4

Я бы рекомендовал просто установить дату при первом запуске и сохранить его в NSUserDefaults. Найдите дату запуска, если она там не установлена, установите ее. Если да, сделайте некоторое сравнение даты и обработайте остальные в соответствии с вашим планом.

Ответ 5

Отвечая на вопрос, могут ли люди в этом ошибиться. Он казался длиннее других, которые я нашел здесь, но он говорит вам, что приложение работает в первый раз с момента обновления (для этого вам нужно изменить свой 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];
}

Ответ 6

Дата сборки приложения:

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
}

Дата установки приложения:

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
}

Ответ 7

Вы всегда можете проверить сервер. Это было просто с UDID, но поскольку они устарели, вы создали UUID (CFUUIDCreate() или что-то в этом роде:)) и сохраните его в цепочке ключей, каждая информация, хранящаяся в цепочке ключей, останется постоянной, даже если пользователь удалит приложение и устанавливает снова через год или около того... Я нашел, что этот articke очень полезен при обработке значений keychain в первый раз: http://useyourloaf.com/blog/2010/3/29/simple-iphone-keychain-access.html

Ответ 8

Решение Swift:

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)")

Ответ 9

Использование даты создания каталога документов является лучшим решением на данный момент. Воспроизведение его в Swift 4.2

var inferredDateInstalledOn: Date? {
    guard
        let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last,
        let attributes = try? FileManager.default.attributesOfItem(atPath: documentsURL.path),
        else { return nil }
    return attributes[.creationDate] as? Date
}