如何在iOS上展现Web Service数据
在iOS开发中,需要和WEB服务器进行交互,如将一批来自WEB SERVICE的数据展现在表格上。数据交互格式是XML,使用的协议是SOAP。请求的数据中有图片,通常图片都会是一个URL重连接,需要再得到这个URL后下载到终端才展现出来。
如果你使用的是浏览器,那么这一切它都做好了。但如果你要更灵活的展现和处理这些数据,这需要开发一个应用。
1.实现过程
我建立一个简单的基于视图控制器的应用。新建的视图控制器类XYViewController。
在该类中手工添加UITableView对象resultTableView,用于展现WEB Service中请求来的数据。WEB SERVICE使用SOAP协议交互。建一个数据请求类XYQueryHotel,使用它的delegate将数据以数组的形式回调回来。
在这个数据请求类中,使用异步请求数据,将收到的XML格式的数据使用NSXMLParser类进行分析。
在视图控制器类XYViewController请求数据过程中,不可避免地会有一个等待出现,但UI可以继续,因为是异步请求操作。这个上面可以设置一些用于杀时间的有趣味的小图片,避免枯燥的等待,提升UI友好度。
在数据请求类操作完成后,通过delegate方式返回了数据给视图控制器类XYViewController中一个属性resultHotels。视图控制器类XYViewController将该属性的数据展现在UITableView对象resultTableView中。
对于resultTableView,通过的datasource方法(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath,将能显示在屏幕上的cell设置好数据。
在resultTableView中,还有一个图片信息需要展现,这个需要通过resultHotels中图片URL去二次请求web service。
这个过程也需要异步去实现,包括请求到图片uiimage数据,请求到的数据的优化,请求到的数据展现等操作,反正不能影响到UI。这是整个实现过程中的关键点,也是难点。
这个请求操作是数据一开始加载时就发出。(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath,这个方法中在cell填充时使用多线程发出请求。它的实现代码如下:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier =@"resultCell";
//初始化cell并指定其类型,也可自定义cell
hotelCell = (XYHotelCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(hotelCell == nil)
{
//将Custom.xib中的所有对象载入
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:@"KaiFangTableViewCell" owner:nil options:nil];
//第一个对象就是CustomCell了
hotelCell = [nib objectAtIndex:0];
}
switch (indexPath.section) {
case 0://对应各自的分区
//修改CustomCell的控件
hotelInfo=[resultHotelsobjectAtIndex:indexPath.row];
hotelCell.name.text = [hotelInfoname];
hotelCell.addr.text = [hotelInfoaddr];
hotelCell.distance.text = [NSStringstringWithFormat:@"%@,%@",[hotelInfo lat],[hotelInfo lng]];
if(hotelInfo.hasLogoImage)
{
hotelCell.logo.image=hotelInfo.logo;
}
else
{
hotelCell.logo.image = [UIImageimageNamed:@"Placeholder.png"];
if (!resultTableView.dragging&& !resultTableView.decelerating) {
[selfstartOperationsForHotelLogo:hotelInfo atIndexPath:indexPath];
}
}
//返回CustomCell
return hotelCell;
break;
}
return hotelCell;//返回cell
}
数组resultHotels中保存类HotelInfo的对象的记录。类HotelInfo是一个单独定义的数据类,属于MVC中MODE范畴。
方法tableView:cellForRowAtIndexPath:,根据在屏幕上显示的cell行号,得到该数组中去动态取对应行的记录。然后将得到的记录信息填写到cell中,用于展现,并将得到的记录,通过一个方法 [self startOperationsForHotelLogo:hotelInfoatIndexPath:indexPath];去多线程请求展现图片。
这个方法 [self startOperationsForHotelLogo:hotelInfoatIndexPath:indexPath]中包括了图片从WEB SERVICE上下载操作,图片美化操作,图片展示到对应的CELL中的操作,并修改提交的记录中信息,再二次展现时如上下滚动时不需要再二次请求该方法了。
如果用户退出这个视图控制器类,那么该数组resultHotels如何缓存,怎不能再将WEB SERVICE交互再做一次把。
继续实现[selfstartOperationsForHotelLogo:hotelInfo atIndexPath:indexPath]方法,
-(void)startOperationsForHotelLogo:(HotelInfo *)hotel atIndexPath:(NSIndexPath*)indexPath {
if (!hotel.hasLogoImage) {
[selfstartImageDownloadingForHotelLogo:hotel atIndexPath:indexPath];
}
if (!record.isFiltered) {
[self startImageFiltrationForRecord:recordatIndexPath:indexPath];
}
}
根据传入的hotel对象中hasLogoImage来决定是否下载,再根据isFiltered来决定是否美化它。
继续实现(void)startImageDownloadingForHotelLogo:(HotelInfo*)hotel atIndexPath:(NSIndexPath *)indexPathWithLogo方法。
-(void)startImageDownloadingForHotelLogo:(HotelInfo *)hotelatIndexPath:(NSIndexPath *)indexPathWithLogo {
if (self.pendingOperations==nil)
{
self.pendingOperations=[[PendingOperationsalloc] init];
NSLog(@"pendingOperationsinitial");
}
if(![self.pendingOperations.downloadsInProgress.allKeys containsObject:indexPathWithLogo]){
HotelImageDownloader *imageDownloader = [[HotelImageDownloader alloc]initWithHotel:hotel atIndexPath:indexPathWithLogo delegate:self];
[self.pendingOperations.downloadsInProgress setObject:imageDownloaderforKey:indexPathWithLogo];
[self.pendingOperations.downloadQueueaddOperation:imageDownloader];
NSLog(@"operation count is%d",[self.pendingOperations.downloadQueue operationCount]);
}
}
&nbs
补充:移动开发 , IOS ,