用远程.plist覆盖本地.plist文件

时间:2012-06-08 19:43:10

标签: objective-c plist

我的应用程序在启动时加载本地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的本地数组,并用远程数组填充它,我这样做了:

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

 //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

2 个答案:

答案 0 :(得分: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];

答案 1 :(得分:2)

我在我的应用程序中几乎完成了你正在寻找的东西。你不能写入NSBundle所以步骤是这样的:

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

  2. 从捆绑

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

  5. 下载新的plist

  6. 保存到缓存目录

  7. 代码看起来像这样:

    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发送通知)