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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • iOS開發系列--網絡開發 概覽 大部分應用程序都或多或少會牽扯到網絡開發,例如說新浪微博、微信等,這些應用本身可...
    lichengjin閱讀 3,721評論 2 7
  • 1.自定義控件 a.繼承某個控件 b.重寫initWithFrame方法可以設置一些它的屬性 c.在layouts...
    圍繞的城閱讀 3,484評論 2 4
  • *7月8日上午 N:Block :跟一個函數塊差不多,會對里面所有的內容的引用計數+1,想要解決就用__block...
    炙冰閱讀 2,553評論 1 14
  • 為什么要談紀錄片, 因為紀錄片是非虛構寫作的親戚。 在上個世紀六十年代, 美國有一個“新新聞主義”, NewJou...
    王佩閱讀 3,320評論 11 80
  • 誰比我清楚 窗外的彎月變成了怪叔叔 尖尖地下巴戳破了夜幕 半開的窗簾布 你是待翻頁的書 世界多安靜,能聽見鼾呼 似...
    小小文閱讀 214評論 0 0