当前位置:编程学习 > wap >>

如何在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 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,