2012-06-08 33 views
1

我的应用程序在启动时加载本地list.plist文件。用远程.plist覆盖本地.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]; 

它作品,但我怎么能写localListlist的内容?

回答

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]; 
} 

初始化伊娃:

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]; 
+0

如果没有您的帮助,我会迷失方向的,谢谢! – Phillip

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]; 

几点说明:

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

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

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

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

+0

好让我明白了一件事。你能解释一下代码中的元素是什么吗? 而且,你最初是否将plist保存到文档中? – Phillip

+0

我在最后添加了更多解释。我不会把这个plist复制出来,唯一一次保存plist的时候是下载一个新的。 (但是我确实附带了应用程序包中最新的plist) – Jonathon