у нас была та же проблема в нашем текущем приложении. наш последний подход таков:
1) ресурсы, которые мы хотим доставить вместе с приложением, хранятся в папке под Resources
.
![screenshot xcode](https://i.stack.imgur.com/yFgty.png)
2) Плюс есть файл XML, сообщающий нам, какой актив принадлежит, где и сколько ему лет (временная метка).
![xml snippet](https://i.stack.imgur.com/dnvTV.png)
3) Когда приложение запускается в первый раз, мы копируем все файлы (кроме xml) из Rescources
в папку Cache
приложения:
// get the app's cache folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_cachesDirectory = [paths objectAtIndex:0];
_assetDirectory = [NSString stringWithFormat:@"%@/assets", _cachesDirectory];
// copy everything
_fmngr = [NSFileManager defaultManager];
- (void) copyAllFilesFromInitialFolder:(NSString*)path
{
NSArray *files = [_fmngr contentsOfDirectoryAtPath:path error:nil];
for (NSString *file in files)
{
if ([file isEqualToString:[NSString stringWithFormat:@"%@.xml", kDefaultXMLFileName]])
{
continue;
}
NSString *fpath = [NSString stringWithFormat:@"%@/%@", path, file];
BOOL isDir;
if ([_fmngr fileExistsAtPath:fpath isDirectory:&isDir])
{
if (isDir)
{
[self copyAllFilesFromInitialFolder:fpath];
}
else
{
NSString *relPath = [fpath substringFromIndex:[_initialLangDeviceContentPath length]+1];
NSString *fileName = [self convertFilePathToName:relPath];
NSString *tpath = [NSString stringWithFormat:@"%@/%@", _assetDirectory, fileName];
NSError *error;
BOOL success = [_fmngr copyItemAtPath:fpath toPath:tpath error:&error];
if (!success || error)
{
NSLog(@"INFO: copy %@ to CACHES failed ... file may already be there.", file);
}
}
}
}
}
4) При следующем запуске приложения мы проверяем, есть ли на нашем сервере обновлений новые файлы. XML из шага 2) также находится на сервере и должен обновляться при обновлении / замене файлов JPG / PNG / ... на сервере.
Если ничего не изменилось, наш PHP-скрипт возвращает 304 "not modfied" - иначе он выведет обновленную версию XML.
PHP-скрипт выглядит примерно так:
$doc = new DOMDocument();
@$doc->load($filename);
$xpath = new DOMXPath($doc);
$assets = $xpath->query('//asset');
if ($assets->length > 0)
{
foreach ($assets as $asset)
{
$assetPath = $asset->getAttribute('path');
if (file_exists($assetPath))
{
$atime = filemtime($assetPath);
$asset->setAttribute('modified', $atime);
}
else
{
// file not found - link broken
$asset->setAttribute('modified', '0');
}
}
}
$output = $doc->saveXML();
header('Content-type: text/xml');
echo $output;
Приложение загружает и анализирует сгенерированный XML, сравнивая все значения modified
.
Когда есть актив с более новой измененной временной меткой, он удаляется локально и перезагружается. только после завершения этой проверки приложение запускается - и вы получаете новые активы на устройстве.
Надеюсь, это поможет. У нас были некоторые проблемы с атрибутом last modified
файлов, которые мы поставляем вместе с приложением. При включении файлов в комплект приложения и копировании их во время выполнения файлы last modified
всегда являются временем первого запуска приложения. иногда вы уже обновили некоторые файлы на сервере - но поскольку приложение считает, что файлы на устройстве более новые (поскольку они были скопированы только сейчас), они не перезагружаются с сервера: (
поэтому вы не можете работать с настоящими атрибутами файла, но должны включать фактическую дату файла внутри файла XML.