D15:网络下载(NSURLConnection实现下载, 结合UITableView显示)

网络请求:

  1. http协议了解

  2. 客户端发送请求信息(GET)

  3. 服务器根据网络链接, 找到对应的相应方法, 去服务器的数据库查找数据

  4. 客户端就可以接收到返回的数据,就可以处理数据

  5. JSON/XML处理数据

JSON/XML技术: 手机开发 web开发 服务器开发

  1. http参数怎么传递(GET)

http://open.qyer.com/lastminute/get_lastminute_list?client_id=qyer_ios&client_secret=cd254439208ab658ddf9&v=1&track_user_id=&track_deviceid=E57D6014-1D9F-437C-B9E5-17CF697370FA&track_app_version=5.4.4&track_app_channel=App%20Store&track_device_info=iPhone7,1&track_os=ios%208.1&lat=40.033568&lon=116.358971&app_installtime=1421832230&page_size=20&is_show_pay=1&country_id=0&continent_id=0&max_id=0&times=&product_type=0

1. http -> http协议  
2. open.qyer.com ->公司的服务器域名  
3. lastminute/get_lastminute_list -> 服务器程序唯一对应一个方法  
4. ?是来分隔前面的请求方法和后面的参数的  
5. ?后面的内容都是GET请求的参数信息  
6. client_id=qyer_ios:键值对的方式, client_id是参数名, 类似于函数的形参, qyer_ios是参数值,类似于函数的实参      

同步: 所有事情都是按照先后顺序来做(效率比较低, 阻塞主线程)
异步: 所有事情都是同时进行(效率比较高)


目录

一. NSURLConnection实现网络下载

二. 根据城觅首页的接口, 实现下载, 显示数据

  1. 创建导航视图控制器, 创建表格视图TabelView
  2. 网络下载数据, 遵守协议NSURLConnectionDelegate, NSURLConnectionDataDelegate
  3. 用下载并解析好的数据创建数据源(使用KVC设置属性值, 所以模型中要重写- (void)setValue:(id)value forUndefinedKey:(NSString *)key)
  4. 自定义Cell(如果使用Xib的方式的话, 一定要在在.xib文件中设置重用标签), 注册Cell, 实现UITableView的相关协议方法返回Cell等
  5. 因为网络数据是异步下载的, 因此在成功下载数据创建数据源后需要刷新表格

三. 爱限免的首页

  1. 新建UITabBarController的子类和5个视图控制器的类
  2. 在新建的UITabBarController的子类中创建需要其管理的5个视图控制器
  3. 设置LimitFreeController的导航条
  4. 下载数据创建表格视图UITableView对象, 实现下载数据的代理方法(表格视图的代理方法略)
  5. 创建模型类, 完成自定义Cell
  6. 处理下载数据创建数据源
  7. 实现UITableView的相关代理方法, 返回行数, 设置cell高度, 返回cell

一. NSURLConnection实现网络下载

二. 根据城觅首页的接口, 实现下载, 显示数据

NSURLConnection是系统实现网络请求的方式

目标: 实现下图效果

实现如图效果
  1. 创建导航视图控制器, 创建表格视图TabelView
  2. 网络下载数据, 遵守协议NSURLConnectionDelegate, NSURLConnectionDataDelegate

NSURLConnectionDelegate 下载是否成功等信息
NSURLConnectionDataDelegate 处理返回的数据

1. 定义属性: 网络请求  

@property (nonatomic, strong) NSURLConnection *conn;
2. 下载数据
- (void)downloadData
{
// 1.创建NSURL对象
NSURL *url = [NSURL URLWithString:kHomeUrl];
// 2.创建NSURLRequest类型的对象
NSURLRequest request = [NSURLRequest requestWithURL:url];
// 3.创建NSURLConnection类型的对象, 会自动发送网络请求
/

第一个参数: 请求对象
第二个参数: 代理
*/
_conn = [NSURLConnection connectionWithRequest:request delegate:self];
}
3. 接收下载数据并解析下载数据
* 定义属性来接收下载的数据
@property (nonatomic, strong) NSMutableData *receiveData;
* 判断是否下载成功, 如果服务器响应, 对下载数据进行接收解析

        1. 如果下载失败执行此方法

                - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
                {
                    NSLog(@"%@", error);
                }
            
        2.  网络成功被服务器处理  

                // 返回响应信息
                - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
                {
                    // 返回的响应体
                    NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
                    
                    NSDictionary *dict = res.allHeaderFields;
                    NSLog(@"%@", dict);
                    
                    // 响应的状态码
                    // 200: 正常返回
                    // 404: 客户端程序错误
                    // 400: 客户端的其它错误
                    // 500: 服务器的错误
                    NSInteger code = res.statusCode;
                    NSLog(@"%ld", code);
                    
                    // 清空下载回来的数据
                    [self.receiveData setLength:0];
                }
            
        3. 接收下载数据  

                // 通常下载的数据量会比较大, 会将数据分批下载
                // 每一次下载回来都会调用这个方法
                - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
                {
                    // 存储下载回来的数据
                    // 每次下载的数据都在data这个形参中
                    [_receiveData appendData:data];
                }
            
        4. 下载结束时调用的代理方法  

                // 前面的代理方法都是异步调用的, 这个代理方法会将程序返回主线程
                - (void)connectionDidFinishLoading:(NSURLConnection *)connection
                {
                    // 下载结束, 处理数据
                    
                    // JSON解析
                    id result = [NSJSONSerialization JSONObjectWithData:self.receiveData options:NSJSONReadingMutableContainers error:nil];
                    
                    if ([result isKindOfClass:[NSDictionary class]]) {
                        NSDictionary *dict = result;
                        NSLog(@"%@", dict);
                    }
                }  
  1. 用下载并解析好的数据创建数据源(使用KVC设置属性值, 所以模型中要重写- (void)setValue:(id)value forUndefinedKey:(NSString *)key)
     // 下载结束时调用的代理方法
     // 前面的代理方法都是异步调用的, 这个代理方法会将程序返回主线程
     - (void)connectionDidFinishLoading:(NSURLConnection *)connection
     {
         // 下载结束, 处理数据
         
         // JSON解析
         id result = [NSJSONSerialization JSONObjectWithData:self.receiveData options:NSJSONReadingMutableContainers error:nil];
         
         if ([result isKindOfClass:[NSDictionary class]]) {
             NSDictionary *dict = result;
             NSArray *sectionArray = dict[@"sectioninfo"];
             
             for (NSDictionary *sectionDict in sectionArray) {
                 DataModel *model = [[DataModel alloc] init];
                 // KVC设置属性值
                 [model setValuesForKeysWithDictionary:sectionDict];
                 [self.dataArray addObject:model];
             }
         }
     }
    
  2. 自定义Cell(如果使用Xib的方式的话, 一定要在在.xib文件中设置重用标签), 注册Cell, 实现UITableView的相关协议方法返回Cell等
重用标签
  1. 因为网络数据是异步下载的, 因此在成功下载数据创建数据源后需要刷新表格
     // 下载结束时调用的代理方法
     // 前面的代理方法都是异步调用的, 这个代理方法会将程序返回主线程
     - (void)connectionDidFinishLoading:(NSURLConnection *)connection
     {
         // 下载结束, 处理数据
         ……………………………………………………………………………………
         [self.tbView reloadData];
     }
    

三. 爱限免的首页

最终效果图
  1. 新建UITabBarController的子类和5个视图控制器的类
如图
  1. 在新建的UITabBarController的子类中创建需要其管理的5个视图控制器
     - (void)createViewControllers
     {
         // 视图控制器
         NSArray *ctrlArray = @[@"LimitFreeController", @"ReduceController", @"FreeController", @"SubjectController", @"HotController"];
         // 文字
         NSArray *titleArray = @[@"限免", @"降价", @"免费", @"专题", @"热榜"];
         // 图片
         NSArray *imageArray = @[@"tabbar_limitfree", @"tabbar_reduceprice", @"tabbar_appfree", @"tabbar_subject", @"tabbar_rank"];
         // 选中时的图片
         NSArray *selectImageArray = @[@"tabbar_limitfree_press", @"tabbar_reduceprice_press", @"tabbar_appfree_press", @"tabbar_subject_press", @"tabbar_rank_press"];
     
         NSMutableArray *array = [NSMutableArray array];
         for (int i = 0; i < ctrlArray.count; i++) {
             // 类名
             NSString *name = ctrlArray[i];
             Class cls = NSClassFromString(name);
             UIViewController *ctrl = [[cls alloc] init];
             
             // 文字
             ctrl.tabBarItem.title = titleArray[i];
             // 图片
             ctrl.tabBarItem.image = [UIImage imageNamed:imageArray[i]];
             // 选中时的图片
             ctrl.tabBarItem.selectedImage = [UIImage imageNamed:selectImageArray[i]];
             
             // 添加导航
             UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:ctrl];
             // 添加到数组中
             [array addObject:navCtrl];
         }
         self.viewControllers = array;
     }
    
    • 快速新建不同类名的对象

      NSArray **ctrlArray = @[@"LimitFreeController", @"ReduceController", @"FreeController", @"SubjectController", @"HotController"];
      for (int i = 0; i < ctrlArray.count; i++) {
      // 类名
      NSString *name = ctrlArray[i];
      Class cls = NSClassFromString(name);
      UIViewController *ctrl = [[cls alloc] init];
      }

  2. 设置LimitFreeController的导航条
     - (void)configNavBar
     {
         // 设置导航栏背景图片
         // 图片拉伸 上下不拉伸 左边5个点不拉伸
         [self.navigationController.navigationBar setBackgroundImage:[[UIImage imageNamed:@"navigationbar"] stretchableImageWithLeftCapWidth:5 topCapHeight:0] forBarMetrics:UIBarMetricsDefault];
         
         // 导航栏中间文字
         self.title = @"限免";
         // 导航条标题文字颜色
         // 6个十六进制位表示颜色
         // #000000 ~ #FFFFFF
         [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:30.0f/255.0f green:60.0f/255.0f blue:113.0f/255.0f alpha:1.0f], NSFontAttributeName:[UIFont systemFontOfSize:24]}];
         
         // 左右按钮
         UIButton *leftBtn = [UIButton buttonWithType:UIButtonTypeCustom];
         leftBtn.frame = CGRectMake(0, 0, 60, 36);
         [leftBtn setBackgroundImage:[UIImage imageNamed:@"buttonbar_action"] forState:UIControlStateNormal];
         [leftBtn setTitle:@"分类" forState:UIControlStateNormal];
         [leftBtn setTitleColor:[UIColor cyanColor] forState:UIControlStateNormal];
         [leftBtn addTarget:self action:@selector(gotoCategory:) forControlEvents:UIControlEventTouchUpInside];
         self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftBtn];
         
         UIButton *rightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
         /*
         ………………………………………………………………………………………………………………………………………………………………………………
          */
     }
    
    • 图片拉伸 上下不拉伸 左边5个点不拉伸

    UIImage *image = [imageTemp stretchableImageWithLeftCapWidth:5 topCapHeight:0];

    • 设置导航条中间标题文字颜色和字体

    [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:30.0f/255.0f green:60.0f/255.0f blue:113.0f/255.0f alpha:1.0f], NSFontAttributeName:[UIFont systemFontOfSize:24]}];`
    * 正确显示TabBar上的小图标

     > // 图片  
     ctrl.tabBarItem.image = [[UIImage imageNamed:imageArray[i]] **imageWithRenderingMode:**UIImageRenderingModeAlwaysOriginal];  
     // 选中时的图片  
     ctrl.tabBarItem.selectedImage = [[UIImage imageNamed:selectImageArray[i]] **imageWithRenderingMode:**UIImageRenderingModeAlwaysOriginal];
    
  3. 下载数据创建表格视图UITableView对象, 实现下载数据的代理方法(表格视图的代理方法略)
    1. 新建属性

       @property (nonatomic, strong) UITableView *tbView;
       @property (nonatomic, strong) NSMutableArray *dataArray;
       // 下载的数据
       @property (nonatomic, strong) NSMutableData *receiveData;  
      
    2. 下载数据
      - (void)downloadData
      {
      NSURLConnection *conn = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:kUrl]] delegate:self];
      // 遵守协议, 实现方法
      }

    3. 创建表格视图, 代理方法略
      - (void)createTableView
      {
      // 导航下面
      self.automaticallyAdjustsScrollViewInsets = NO;

           _tbView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 375, 667-64-49) style:UITableViewStylePlain];
           _tbView.delegate = self;
           _tbView.dataSource = self;
           [self.view addSubview:_tbView];
       }
      
    4. NSURLConnection协议方法

       // 下载失败 
       - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
       {
           NSLog(@"%@", error);
       }
       
       // 网络请求返回
       - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
       {
           // 清空以前的数据
           [self.receiveData setLength:0];
       }
       
       // 每次下载数据返回
       - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
       {
           [self.receiveData appendData:data];
       }
       
       // 下载结束调用
       - (void)connectionDidFinishLoading:(NSURLConnection *)connection
       {
           
       }
      
  4. 创建模型类, 完成自定义Cell
    • Cell中的- (void)showData:(LimitFreeModel *)model row:(NSInteger)row方法
      - (void)showData:(LimitFreeModel *)model row:(NSInteger)row
      {
      // 背景图片
      if (row % 2 == 0) {
      self.bgImageView.image = [UIImage imageNamed:@"cate_list_bg1"];
      } else {
      self.bgImageView.image = [UIImage imageNamed:@"cate_list_bg2"];
      }

            // 左边图片
            [self.leftImageView sd_setImageWithURL:[NSURL URLWithString:model.iconUrl]];
            // 名称
            self.nameLabel.text = model.name;
            // 时间
            self.timeLabel.text = model.releaseDate;
            
            // 星级
            CGRect frame = self.starImageView.frame;
            frame.size.width = (model.starCurrent.floatValue / 5) * frame.size.width;
            self.starImageView.frame = frame;
            // 停靠模式
            self.starImageView.contentMode = UIViewContentModeLeft;
            self.starImageView.clipsToBounds = YES;
            
            // 价格
            self.priceLabel.text = model.lastPrice;
            // 类型
            self.typeLabel.text = model.categoryName;
            // 分享
            self.shareLabel.text = [NSString stringWithFormat:@"分享:%@", model.shares];
            // 收藏
            self.favouritesLabel.text = [NSString stringWithFormat:@"收藏:%@",model.favorites];
            // 下载
            self.downloadLabel.text = [NSString stringWithFormat:@"下载:%@",model.downloads];
        }  
      
    • .xib中除了连线以外, 勿忘设置cell的重用标签

      cell的重用标签
  5. 处理下载数据创建数据源
    • 在NSURLConnectionDataDelegate协议的- (void)connectionDidFinishLoading:(NSURLConnection *)connection方法中用下载数据创建数据源
      - (void)connectionDidFinishLoading:(NSURLConnection *)connection
      {
      // 处理下载数据
      // JSON解析
      id result = [NSJSONSerialization JSONObjectWithData:self.receiveData options:NSJSONReadingMutableContainers error:nil];
      if ([result isKindOfClass:[NSDictionary class]]) {
      NSDictionary *dict = result;

                NSArray *appArray = dict[@"applications"];
                for (NSDictionary *appDict in appArray) {
                    // 创建模型对象
                    LimitFreeModel *model = [[LimitFreeModel alloc] init];
                    // kvc
                    [model setValuesForKeysWithDictionary:appDict];
                    // 添加到数组
                    [self.dataArray addObject:model];
                }
                // 刷新表格
                [self.tbView reloadData];
            }
        }
      
  6. 实现UITableView的相关代理方法, 返回行数, 设置cell高度, 返回cell
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 3,617评论 2 7
  • 1.自定义控件 a.继承某个控件 b.重写initWithFrame方法可以设置一些它的属性 c.在layouts...
    圍繞的城阅读 3,321评论 2 4
  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,460评论 1 14
  • 为什么要谈纪录片, 因为纪录片是非虚构写作的亲戚。 在上个世纪六十年代, 美国有一个“新新闻主义”, NewJou...
    王佩阅读 3,265评论 11 80
  • 谁比我清楚 窗外的弯月变成了怪叔叔 尖尖地下巴戳破了夜幕 半开的窗帘布 你是待翻页的书 世界多安静,能听见鼾呼 似...
    小小文阅读 195评论 0 0