2012-06-08 52 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