第一篇文章。现在已经是iPhone开发人员实习生大约五周了。我已经阅读了很多介绍性的Apress材料,但如果我犯了一些词汇侵犯,请放轻松。到目前为止,我已经能够通过搜索和潜伏找到答案。但是我现在有一项任务,我可以找到很少的相关信息。
我的iPhone应用程序目前使用刚性视图层次结构来选择项目。 MainViewController链接到(错误,Subviews?)一个TableView,用于从工厂列表中选择任何一个。选择工厂然后加载TableView以获取有关该工厂的各种统计信息。填充这些表的数据由http。
从远程JSON服务器加载我希望在远程服务器上有一个视图层次结构的XML定义,应用程序可以动态地构建视图结构。通过这种方式,视图结构不会硬编码到客户端(iPhone ViewControllers / nibs)中,并为重新组织内容服务器端提供了更大的灵活性。
这可能吗,有没有人完成这个?最相关的答案是Dynamic UI in iphone,但是在阅读时我觉得Apple的序列化/存档指南很快就会脱离我想要做的事情。有人可以解释其相关性或指向另一种资源吗?
答案 0 :(得分:1)
是的,这完全有可能,而且我(以及其他人)做过类似的事情。基本上,你必须写几个类:
一个是一个Controller类,用于解析XML,以便在下载到您可以在Model类中使用的格式时获取所需的内容。有很多OSS库,但不要在iPhone上使用Cocoa的XML类,因为它们在解析时速度太慢。请务必仔细检查OSS库附带的许可证,以免与GPL等发生冲突。
您需要的第二个类是将您的模型转换为视图层次结构,并在用户浏览内容时将其立即放置在屏幕上。这是作为单独的步骤实现的,但挑战在于管理内容放置工作流程。
您的问题中提到的内容确实偏离了手头的核心任务,但它仍然与您的兴趣相关。至少它可以让您了解如何处理项目的某些方面。
答案 1 :(得分:0)
这是一个后续行动。我已经完成了我想做的事。
我有一个ListViewController类和一个Repository模型/对象。为了解析XML,我使用了XPathQuery,Matt Gallagher为Cocoa改编了libxml2(http://cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html)。
ListViewController跟踪当前的XML路径。选择表视图中的单元格时,相应的路径将连接到现有路径。 ListViewController创建并推送其自身的另一个实例,PerformXMLPathQuery()返回一个数组来填充表视图单元格。存储库包含NSMutableData对象和具有当前路径的NSString。 XPath Query都需要这两个:
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的每个实例都保留自己的路径字符串和内容数组。不要愚弄嵌套的树对象或指针。
基本上我有一个灵活的iPhone XML树浏览器。谢谢Stack Overflow。