2010-10-11 89 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。感谢堆栈溢出。

相关问题