我在做iPhone应用程序开发。通常,我将图像(照片)文件和一些其他配置文件放入支持文件夹。
我可以从服务器更新支持文件夹中的那些文件吗?如果可以,该怎么做?
如果没有,我可以预先存储需要上传到文件夹的文件,并下载文件夹中较新的文件来替换旧文件吗?
答案 0 :(得分:3)
我们当前的应用程序遇到了同样的问题。我们的最终方法是:
1)我们希望通过应用程序提供的资产存储在Resources
下的文件夹中。
2)另外还有一个XML文件告诉我们,哪个资产属于哪里和多久(时间戳)。
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)在下一次启动应用程序时,我们会在线检查我们的更新服务器上是否有更新的文件。步骤2)中的XML也驻留在服务器上,并且必须在服务器上更新/替换JPG / PNG / ...时进行更新。 如果没有改变我们的PHP脚本返回304“未修改” - 否则它将输出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文件中包含实际的文件日期。