2010-10-11 109 views
1

第一篇文章。現在已經是iPhone開發實習生大約五個星期了。我已經閱讀了許多介紹性的Apress材料,但如果我犯了一些詞彙違規,請儘量簡單。到目前爲止,我已經能夠通過搜索和潛伏找到答案。不過,我現在有一項任務,我可以找到很少的相關信息。Cocoa Touch:是否可以動態定義XML定義的視圖?

我的iPhone應用程序當前使用嚴格的視圖層次結構來選擇項目。 MainViewController鏈接到(err,Subviews?)TableView,用於從工廠列表中選擇任何一個。選擇一個工廠然後加載一個TableView以獲得關於該工廠的各種統計信息。通過http從遠程JSON服務器加載填充這些表的數據。

我想在應用程序動態構造視圖結構的遠程服務器上有一個視圖層次結構的XML定義。通過這種方式,視圖結構不會被硬編碼到客戶端(iPhone ViewControllers/nibs)中,併爲重新組織內容服務器端提供了更大的靈活性。

這是可能的,並有任何人做到了這一點?最相關的答案是Dynamic UI in iphone,但是在閱讀時,我感覺蘋果公司的序列化/歸檔指南很快就離開了我想要做的事情。有人可以解釋它的相關性或指向其他資源嗎?

+0

新的詞彙:鑽取http://www.iphonedevsdk.com/forum/iphone-sdk-development/53605-dynamic-navigation-xml-tables.html 我看到如何可以序列化表的數組/ unarchived,但那些意見呢? – slater 2010-10-11 14:27:54

回答

1

是的,這是完全可能的,我(以及其他人)做了類似的事情。從本質上講,你將不得不編寫幾個類:

一個是Controller類,用於解析XML,以便下載所需的內容並將其轉換爲可在Model類中使用的格式。在那裏有許多OSS庫,但是不要在iPhone上使用Cocoa的XML類,因爲它們在解析時太慢了。請務必仔細檢查OSS庫附帶的許可證,以免違反GPL等規定。

您將需要的第二個類是將您的模型轉換爲視圖層次結構並隨着用戶在內容中移動而將其置於屏幕上的類。這是作爲單獨的步驟實施的,但挑戰在於管理內容放置工作流程。

您的問題中提到的內容確實偏離了手頭的核心任務,但它仍然可能與您的興趣相關。至少它可以給你一個關於如何處理你的項目的某些方面的想法。

+0

謝謝Philip。確定的挑戰將是創建視圖層次結構。當我把東西拉到一起時,我會回來。同時,這部分的提示也受到任何人的歡迎。 – slater 2010-10-11 17:08:14

0

這是後續行動。我已經完成了我想要做的事情。

我有一個ListViewController類和一個存儲庫模型/對象。爲了解析XML,我使用了XPathQuery,Matt Gallagher將libxml2改編爲Cocoa(http://cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html)。

ListViewController跟蹤當前的XML路徑。當選擇表視圖中的單元格時,相應的路徑將連接到現有路徑。 ListViewController創建並推送自己的另一個實例,PerformXMLPathQuery()返回一個數組來填充表格視圖單元格。存儲庫包含一個NSMutableData對象和一個包含當前路徑的NSString。兩者都是XPath查詢所必需的:

NSArray *PerformXMLXPathQuery(NSData *document, NSString *query); 

PerformXMLPathQuery爲您做了很多後期工作。這是我用它來得到我從XML想:

-(NSArray*)getListFromRepositoryWithPath:(NSString *)path { 

    // Get the nodes referred to by the path 
    NSArray *nodes = PerformXMLXPathQuery(repository.data, path); 

    // Build an array with the node names 
    NSMutableArray* sublist = [[NSMutableArray alloc] init]; 

    for (NSDictionary* node in nodes) {  
     for (id key in node) { 

      if ([key isEqualToString:@"nodeChildArray"]) { 
       NSArray* subNodes = [node objectForKey:@"nodeChildArray"]; 

       for (NSDictionary* subNode in subNodes) { 
        for (id subKey in node) { 

         if ([subKey isEqualToString:@"nodeName"]) { 
          [sublist addObject:[subNode objectForKey:subKey]]; 
         } 
        } 
       } 
      } 
     } 
     // Ignore duplicate entries in the data 
     if ([sublist count] > 0) { 
      return [NSArray arrayWithArray:sublist]; 
     } 
    } 
    return [NSArray arrayWithArray:sublist]; 
} 

當選擇一排,我用didSelectRowAtIndexPath方法準備下一個路徑和視圖控制器:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    NSString *nextXpathQueryString = [self.xpathQueryString copy]; 

    // Build the path string for the next view's XML path query 
    if ([[nextXpathQueryString lastPathComponent] isEqualToString:@"*"]) { 
     nextXpathQueryString = [nextXpathQueryString stringByDeletingLastPathComponent]; 
     nextXpathQueryString = [nextXpathQueryString stringByAppendingPathComponent:@ROOTNAME]; 
    } 
    nextXpathQueryString = [nextXpathQueryString stringByAppendingPathComponent:[repository.currentListToDisplay objectAtIndex:indexPath.row]]; 

    // Navigation logic. Create and push another view controller. 
    ListViewController *detail = [[ListViewController alloc] init]; 

    // Populate the new ViewController 
    [detail setRepository:repository]; 
    [detail setTitle:nextXpathQueryString]; 
    [detail setXpathQueryString:nextXpathQueryString]; 

    [nextXpathQueryString release]; 

    UIBarButtonItem *doneButton = [[self navigationItem] rightBarButtonItem]; 
    [[detail navigationItem] setRightBarButtonItem:doneButton animated:YES]; 

    // Pass the selected object to the new view controller. 
    [self.navigationController pushViewController:detail animated:YES]; 
    [detail release]; 
} 

很酷的事情是ListViewController的每個實例保留自己的路徑字符串和內容數組。沒有混搭嵌套的樹對象或指針。

基本上我有一個靈活的XML樹瀏覽器的iPhone。感謝堆棧溢出。

相關問題