Файлы в iOS, скопированные из папки пучка в кеш, содержат CreationDate и ModifiedDate компиляции

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

Мое приложение в основном является устройством для чтения документов. Куча PDF-файлов втягивается и в комплекте с приложением для компиляции. Когда приложение запускается, они копируются (для пользователей добавлять аннотации, а что нет), и я генерирую Dict для UITableView (используя метаданные PDF для заполнения таких вещей, как заголовок). Когда будет выпущена новая версия приложения, я хотел бы быть немного умнее о копировании файлов во время процесса обновления. В настоящее время лучшее, что я могу сделать, это стереть все и скопировать заново.

Проблема заключается в том, что, когда Xcode копирует файлы в пакет, при компиляции NSFileCreationDate и NSFileModificationDate сбрасываются, когда приложение скомпилировано. Это в основном делает всю дату проверки бесполезной.

2012-10-11 15:19:29.254 handouts[5131:707] File attributes of source: { NSFileCreationDate = "2012-10-11 19:19:10 +0000"; NSFileExtensionHidden = 0; NSFileGroupOwnerAccountID = 501; NSFileGroupOwnerAccountName = mobile; NSFileModificationDate = "2012-10-11 19:19:10 +0000"; NSFileOwnerAccountID = 501; NSFileOwnerAccountName = mobile; NSFilePosixPermissions = 420; NSFileProtectionKey = NSFileProtectionNone; NSFileReferenceCount = 1; NSFileSize = 466028; NSFileSystemFileNumber = 2754117; NSFileSystemNumber = 234881027; NSFileType = NSFileTypeRegular; 

}

В настоящее время я планирую использовать размеры файлов и даты в конъюнктуре, но я представляю, что он становится очень грязным, очень быстрым. И мне придется следить за кучей метаданных самостоятельно. Я делаю что-то неправильно? Есть ли способ сделать Xcode почерком отмеченные временные метки файлов, которые он копирует?

Я думал, что проверю, прежде чем зайти слишком глубоко в то, if...then суп с кодом, который я, скорее всего, буду писать. Благодаря!

AFAIK Невозможно заставить XCode сохранить даты. Я столкнулся с аналогичной проблемой и придумал сценарий оболочки, чтобы создать файл plist, содержащий измененные даты файлов в каталоге (рекурсивно). Затем я включаю это в свой пакет и читаю его, когда я копирую файлы, чтобы установить измененные даты. Вы можете изменить это, чтобы обрабатывать даты создания или доступа или с некоторой комбинацией работы.

Вот сценарий bash: (Я все еще новичок в bash, поэтому, пожалуйста, любые комментарии о том, как сделать его лучше, приветствуются)

 #!/bin/bash #First parameter is the folder to recurse into, defaults to current directory #Second parameter is the full path to a pList file without the extension, defaults to #<CURRENT DIRECTORY>/fileInfo #if you don't specify /'s in the parameter it will be treated as a domain instead and #the pList will be elsewhere... pinfoLoc=${2:-`pwd`/fileInfo} #Useful for debugging #echo Source: ${1:-.} #echo Destination: $pinfoLoc for i in ${1:-.}/*; do #Format: %Sa = last access, %Sm = last modified, %Sc = created date=`stat -f "%Sm" $i` #Uncomment below to see each file and date used #echo $i - $date #Write the data to the pList defaults write $pinfoLoc "$i" -date "$date" #Recurse into directories, not sure if there's a better way to do this if [ -d "$i" ]; then bash $0 $i $pinfoLoc fi done 

В основном у меня есть папка под названием «активы», которая живет за пределами проекта и связана с ней, и XCode скопирует эту папку в комплект для меня. Вот код, который я придумал для обновления измененной даты каждого файла ПОСЛЕ того, как я скопировал их из пакета.

 //Update file properties NSString *file, *dstPath, *srcPath; NSDictionary *fAttribs; NSData *fInfoData = [fm contentsAtPath:[[NSBundle mainBundle] pathForResource:@"fileInfo" ofType:@"plist"]]; NSPropertyListFormat format; NSDictionary *fileInfo = (NSDictionary *)[NSPropertyListSerialization propertyListWithData:fInfoData options:NSPropertyListMutableContainersAndLeaves format:&format error:&error]; NSString * resPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"assets"]; NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath:resPath]; while (file = [dirEnum nextObject]) { NSLog(@"Directory Enum File: %@", file); dstPath = [NSString pathWithComponents:@[[appInfo appSupportPath], @"res", file ]]; srcPath = [@"assets" stringByAppendingPathComponent:file]; fAttribs = @{ NSFileModificationDate: [fileInfo valueForKey:srcPath]}; [fm setAttributes:fAttribs ofItemAtPath:dstPath error:&error]; if (error) { NSLog(@"Error setting attribute to file: %@ - %@", file, error.localizedDescription); [error release]; error = nil; } } 

Это после моего метода копирования файлов, и есть несколько переменных, которые вы не видите. А именно fm – это только менеджер по умолчанию из NSFileManager , error – неинициализированный NSError , [appInfo appSupportPath] – это статический метод, который возвращает каталог, в котором я храню вещи на устройстве (так как вы не можете изменить пакет).

Кроме того, я жестко закодировал местоположения plist, который содержит даты, и каталог, в который я скопировал свои файлы, я, вероятно, обновлю это в своем коде позже.

Следующее, что я сделал, – это настроить XCode для автоматизации запуска моего скрипта и также включить fileInfo.plist. Последнее легко, как только вы запустили скрипт, вы можете просто перетащить его в Xcode и сохранить его в качестве ссылки, сложная часть – запустить его для каждой сборки.

  1. Скопируйте / вставьте мой bash-скрипт в файл
  2. Нажмите на свой проект в Навигаторе проектов
  3. Выберите целевую (имя приложения) в разделе «Цели», если она еще не выбрана
  4. Перейдите на вкладку «Сборка фаз»
  5. В правом нижнем правом углу нажмите Добавить этап сборки -> Добавить сценарий запуска
  6. Новый этап будет последним, к сожалению, после того, как он скопировал файлы в пакет, включая тот, который мы генерируем. Поэтому перетащите фазу чуть выше «Copy Bundle Resources»
  7. Для оболочки я положил / bin / bash, / bin / sh может работать также …
  8. В строках ниже я ставлю это:

     pushd $PROJECT_DIR/.. /PATH/TO/BASH/FILE/ABOVE.sh assets popd 

    pushd $PROJECT_DIR/.. поскольку каталог ресурсов находится на один уровень выше моего проекта, я мог бы жестко закодировать каталог, куда нужно перейти, и, вероятно, будет более понятным.

  9. Если вы попытаетесь построить прямо сейчас, вы, вероятно, получите ошибку разрешения, так как файл сценария не имеет разрешений на выполнение. Я не знаю, как проще на Mac установить это, чем открыть терминал и запустить chmod +x <BASH FILE NAME> Да, я понимаю, что это позволяет каждому выполнить его, если вы беспокоитесь об этом, тогда играйте с разрешения, я не уверен, что XCode собирается как другой пользователь или что.

Надеюсь, по крайней мере, некоторые из этого помогут. Я использую эту измененную дату, чтобы увидеть, есть ли новые файлы на веб-сервере и загружать только те, которые мне нужны.

  • NSFileManager removeItemAtPath блокирует основной поток
  • fileExistsAtPath: не возвращает правильное значение в iOS 8 SDK
  • Сохранять и извлекать документы из папки документов приложения
  • Swift 2 iOS - получить список файлов, отсортированный по дате создания - более сжатое решение?
  • создание zip-файла из строки в swift
  • Скопировать папку (с содержимым) из пакета в каталог Документы - iOS
  • Массив нескольких URL-адресов NSFileManager Swift
  • Удалить каталог, если он пустой
  • Странная ошибка при перемещении папки в temp с помощью moveItemAtPath. Ошибка какао 516
  • URL-адрес NSFileManager vs Path
  • Функция UIDocument «Сохранить как»
  • Давайте будем гением компьютера.