Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 用远程.plist覆盖本地.plist文件_Objective C_Plist - Fatal编程技术网

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

Objective c 用远程.plist覆盖本地.plist文件,objective-c,plist,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 unti

我的应用程序在启动时加载本地
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];

它可以工作,但是如何用
list
的内容重写
localList

在我的一个应用程序中,我几乎做了你想要的事情。您无法写入NSBundle,因此步骤如下:

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];
}
  • 尝试从缓存目录加载plist,如果成功,请转到3

  • 从捆绑中加载plist

  • 检查加载的plist是否最新(或按下按钮触发进一步步骤)

  • 下载新plist

  • 保存到缓存目录

  • 代码如下所示:

    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];
    }
    
    然后在downloader中保存,如下所示:

    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。(我还用新的plist发送了一个通知)

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

    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];
    }
    
  • 尝试从缓存目录加载plist,如果成功,请转到3

  • 从捆绑中加载plist

  • 检查加载的plist是否最新(或按下按钮触发进一步步骤)

  • 下载新plist

  • 保存到缓存目录

  • 代码如下所示:

    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];
    }
    
    然后在downloader中保存,如下所示:

    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。(我还用新的plist发送了一个通知)

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

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

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

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

    好吧,让我明白一件事。你能解释一下代码中的那些元素是什么吗?而且,您最初是否将plist保存到文档中?我在最后添加了一些解释。我不会从包中复制plist;plist的唯一保存时间是下载新plist时。(但我提供的是应用程序包中最新的plist)让我了解一件事。你能解释一下代码中的那些元素是什么吗?而且,您最初是否将plist保存到文档中?我在最后添加了一些解释。我不会从包中复制plist;plist的唯一保存时间是下载新plist时。(但我提供的是应用程序包中最新的plist)