1

我的应用程序在启动时加载本地list.plist文件。

然后它有一个 refreshTable 按钮,可以从我的网站获取远程版本的 .plist 文件。

App Launch
    local list.plist loads
       user hits refreshList button
          local list.plist is overwritten by remote list.plist
             local list.plist updated until remote list.plist updates again

初始化数据的方法:

    //Remote data 
    list = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://mywebsite.com/list.plist"]];
    NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
    sortedList = [[list sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];

    //Local data
    NSString *localPath = [[NSBundle mainBundle] pathForResource:@"list" ofType:@"plist"];
   localList = [[NSMutableArray alloc] initWithContentsOfFile:localPath];
    NSSortDescriptor *localDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
    localSortedList = [[localList sortedArrayUsingDescriptors:[NSArray arrayWithObject:localDescriptor]] retain];

这是刷新的方法:

- (void) refreshTable:(id)sender

{  
   //Remote .plist 
   list = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://mywebsite.com/list.plist"]];
    NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
   sortedList = [[list sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];
    [self.tableView reloadData];
    //now write remote plist to local plist
}

下载远程 plist 后,如何覆盖本地 plist?

我正在考虑清空包含本地 plist 的本地数组并用远程数组填充它,我这样做了:

我按照我想的方式解决了:

 //Remote .plist 
    list = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://phillipapps.com/mntlion/list.plist"]];
    NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
    sortedList = [[list sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];

    NSLog(@"list: %@",list);
    [localList removeAllObjects];
    [localList addObjectsFromArray:list];
    localSortedList = [[localList sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];
    NSLog(@"locallist: %@",localList);
    [self.tableView reloadData];

它可以工作,但是我怎样才能localList用 的内容来写list呢?

4

2 回答 2

4

所以......在聊天中查看了几个小时后,我们解决了问题。

- (NSArray*)readPlist
{
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *plistPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"localFile.plist"];

    NSFileManager *fMgr = [NSFileManager defaultManager];
    if (![fMgr fileExistsAtPath:plistPath]) {
        plistPath = [[NSBundle mainBundle] pathForResource:@"template" ofType:@"plist"];
    }
    return [NSArray arrayWithContentsOfFile:plistPath];
}

- (void)writePlist:(NSArray*)arr
{
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *plistPath = [[documentPaths lastObject] stringByAppendingPathComponent:@"localFile.plist"];

    NSFileManager *fMgr = [NSFileManager defaultManager];
    if (![fMgr fileExistsAtPath:plistPath])
        [fMgr removeItemAtPath:plistPath error:nil];

    [arr writeToFile:plistPath atomically:YES];
}

初始化 ivar:

self.plistArray = [self readPlist];

从服务器加载新的后plist,您必须调用此代码:

self.plistArray = [NSArray arrayWithContentsOfURL:[NSURL URLWithString:@"http://mywebsite.com/list.plist"]];
[self writePlist:plistArray]; // e.g. for caching
[self.tableView reloadData];
于 2012-06-10T23:41:18.190 回答
2

在我的应用程序中,我所做的几乎与您正在寻找的完全一样。您无法写入 NSBundle,因此步骤如下:

  1. 尝试从缓存目录加载plist,如果成功则转到3。

  2. 从包中加载 plist

  3. 检查加载的 plist 是否是最新的(或者,通过按下按钮触发进一步的步骤)

  4. 下载新的 plist

  5. 保存到缓存目录

代码看起来像这样:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cache = [paths objectAtIndex:0];

ratios = [NSDictionary dictionaryWithContentsOfFile:[cache stringByAppendingPathComponent:@"devices.plist"]];
if (ratios == nil) {
    ratios = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"devices" ofType:@"plist"]];
}

NSString *device = [[UIDevice currentDevice] machine];
NSDictionary *d = [ratios objectForKey:device];
if (d!=nil) {
    pixelInchRatio = [[d objectForKey:@"pixelInchRatio"] doubleValue];
    bezelWidth = [[d objectForKey:@"bezelWidth"] doubleValue];
    bezelHeight = [[d objectForKey:@"bezelHeight"] doubleValue];
} else if (fetch) {
    [[[[RulerDimensionDownload alloc] init] autorelease] startDownload];
}

然后在下载器中保存如下:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cache = [paths objectAtIndex:0];

[[NSFileManager defaultManager] createDirectoryAtPath:cache withIntermediateDirectories:YES attributes:nil error:nil];
[ratios writeToFile:[cache stringByAppendingPathComponent:@"devices.plist"] atomically:YES];

一些解释:

每个示例中的前几行,路径和缓存定义,只是获取应用程序缓存目录的位置。我用它来存储我是我的 plist 的最新版本。

因此,在加载代码中,我首先尝试从缓存目录加载 plist。如果失败(比率为空),我会从我的应用程序包中加载它(这是我随应用程序提供的 plist 版本)。

之后,我检查 plist 是否包含所需的信息。(plist 对每种设备类型都有一个定义。如果设备不在 plist 中,那么我知道我需要尝试更新 plist)

如果 plist 已过期,我将使用我编写的类开始下载:RulerDimensionDownload。完成下载后,我将文件保存到缓存目录中。然后,下次需要加载 plist 时,它将首先加载,并且永远不会查看已发送的 plist。(我还用新的 plist 发送通知)

于 2012-06-08T23:38:57.267 回答