我可以从服务器下载更新文件并替换支持文件夹中的文件吗?

时间:2012-03-31 06:18:24

标签: iphone objective-c ios

我在做iPhone应用程序开发。通常,我将图像(照片)文件和一些其他配置文件放入支持文件夹。

  1. 我可以从服务器更新支持文件夹中的那些文件吗?如果可以,该怎么做?

  2. 如果没有,我可以预先存储需要上传到文件夹的文件,并下载文件夹中较新的文件来替换旧文件吗?

1 个答案:

答案 0 :(得分:3)

我们当前的应用程序遇到了同样的问题。我们的最终方法是:

1)我们希望通过应用程序提供的资产存储在Resources下的文件夹中。 screenshot xcode

2)另外还有一个XML文件告诉我们,哪个资产属于哪里和多久(时间戳)。 xml snippet

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文件中包含实际的文件日期。