1. 程式人生 > >iOS中GET 和 POST 資料請求

iOS中GET 和 POST 資料請求

 iOS中GET 和 POST 網路資料請求

同步請求和非同步請求的差別:

 1.同步請求,有主執行緒完成網路請求任務,在資料沒有請求之前,使用者的所有的互動事件應用都無法處理,會造成一種卡頓現象,影響使用者體驗

 2.非同步同步,系統預設開闢子執行緒完成網路請求任務,主執行緒依然會處理使用者的互動事件,此時不會出現卡頓,一旦開闢子執行緒就會消耗資源(記憶體),此時就是拿空間換時間

先分析下整體思路:


1.下面準備一個公用的model資料資料模型:

Business.h

#import <Foundation/Foundation.h>
@interface Business : NSObject
@property(nonatomic,copy)NSString *name;//商戶名
@property(nonatomic,copy)NSString *address;//商戶地址
@property(nonatomic,copy)NSString *telephone;//電話號碼
@property(nonatomic,copy)NSString *title;
@property(nonatomic,copy)NSString *summary;
@end
Business.m
#import "Business.h"
@implementation Business
- (void)dealloc{
    self.name = nil;
    self.telephone = nil;
    self.address = nil;
    self.title = nil;
    self.summary = nil;
    [super dealloc];
}
//防止Crash
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
 
}
@end

2.下面準備兩個自定義的cell用於兩種資料請求的自定義cell


第一個自定義cell:

BusinessCell.h

#import <UIKit/UIKit.h>
@class Business;
@interface BusinessCell : UITableViewCell
@property (retain, nonatomic) IBOutlet UILabel *nameLabel;
@property (retain, nonatomic) IBOutlet UILabel *adressLabel;
@property (retain, nonatomic) IBOutlet UILabel *telephoneLabel;
//寫一個介面給cell上的子控制元件賦值
- (void)assignValueByBusiness : (Business *)business;
@end

BusinessCell.m

#import "BusinessCell.h"
#import "Business.h"
@implementation BusinessCell

- (void)awakeFromNib {
    // Initialization code
}

//寫一個介面給cell上的子控制元件賦值
- (void)assignValueByBusiness : (Business *)business{
    
    self.nameLabel.text = business.name;
    self.telephoneLabel.text = business.telephone;
    self.adressLabel.text = business.address;
   
    
}
- (void)dealloc {
    [_nameLabel release];
    [_adressLabel release];
    [_telephoneLabel release];
    [super dealloc];
}@end
第二個自定義cell:

CustomCell.h

#import <UIKit/UIKit.h>
@class Business;
@interface CustomCell : UITableViewCell
@property (retain, nonatomic) IBOutlet UILabel *titleLabel;
@property (retain, nonatomic) IBOutlet UILabel *summaryLabel;
//寫一個方法給cell上的控制元件賦值
- (void)setValueByName : (Business *)business;
@end
CustomCell.m
#import "CustomCell.h"
#import "Business.h"
@implementation CustomCell
- (void)dealloc {
    
    [_titleLabel release];
    [_summaryLabel release];
    [super dealloc];
}
//寫一個方法給cell上的控制元件賦值
- (void)setValueByName : (Business *)business{
    
    self.titleLabel.text = business.title;
    self.summaryLabel.text = business.summary;
}@end

——————————————開始介紹資料請求:————————————————

GET資料請求(同步請求):
<span style="color:#3333ff;">#import "GETViewController.h"
#import "Business.h"
#import "CustomCell.h"
#import "BusinessCell.h"
@interface GETViewController ()<NSURLConnectionDataDelegate>
@property(nonatomic,retain)NSMutableArray *dataSource;
@property(nonatomic,retain)NSMutableData *data;//拼接多次請求下來的資料
@end

@implementation GETViewController
- (void)dealloc{
    self.dataSource = nil;
    self.data = nil;
    [super dealloc];
}

//懶載入
- (NSMutableArray *)dataSource{
    if (_dataSource == nil) {
        self.dataSource = [NSMutableArray arrayWithCapacity:0];
    }
    return [[_dataSource retain]autorelease];
}

</span><span style="color:#ff0000;">//同步get請求</span><span style="color:#3333ff;">
- (IBAction)handleGetSyncRequst:(UIBarButtonItem *)sender {
    
    //清空陣列
    [self.dataSource  removeAllObjects];
    
    //1.準備網址字串
    NSString *urlStr = @"http://api.map.baidu.com/place/v2/search?query=大保健&region=上海&output=json&ak=6E823f587c95f0148c19993539b99295";
    //2.檢視網址字串中是否含有中文,有中文的話要對urlStr進行轉碼
    NSString *changeUrlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //3.建立NSURL物件,不能能夠儲存本地的檔案地址,也能儲存網路地址
    NSURL *url = [NSURL URLWithString:changeUrlStr];
    
    //4.建立網路請求物件(NSURLRequest )
    // NSURLRequest 預設請求方式就是GET請求
    // NSMutableURLRequest  可以設定網路的請求方式
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
   
    //5.建立同步連結
    //5.1 建立伺服器響應物件
    NSURLResponse *response = nil;
    //5.2 建立請求失敗錯誤資訊物件
    //以上兩個引數都是方法的內部對其賦值
    NSError *error = nil;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//    NSLog(@"%@",data); 驗證!
    
    //呼叫解析方法
    [self parserData:data];
    
    }
//封裝一個解析的方法
- (void)parserData : (NSData *)data{
    
    //解析:
    NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    //    NSLog(@"%@",dataDic); 驗證!
    //取出results key值對應的陣列
    NSArray *array = dataDic[@"results"];
    //遍歷陣列的字典,並使用給Business物件賦值
    for (NSDictionary *dic in array) {
        //建立資料模型物件
        Business *bus = [[Business alloc]init];
        
        //使用kvc給bus賦值
        [bus setValuesForKeysWithDictionary:dic];
        
        //新增到儲存所有商戶資訊的陣列
        [self.dataSource addObject:bus];
        //釋放
        [bus release];
        //        NSLog(@"%@",self.dataSource); 驗證!
        
        
    }
    //重新整理ui介面
    [self.tableView reloadData];
}</span>
GET資料請求(非同步請求):
<span style="color:#ff0000;">//非同步get請求</span>
- (IBAction)handleGetAsyncRequst:(UIBarButtonItem *)sender {
    
    //清空陣列
    self.dataSource = nil;
    
    //1.建立網址字串
    NSString *urlStr = @"http://api.map.baidu.com/place/v2/search?query=大保健&region=上海&output=json&ak=6E823f587c95f0148c19993539b99295";
    //2.判斷是否含有中文
    NSString *change = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //3.建立NSURL物件
    NSURL *url = [NSURL URLWithString:change];
    //4.建立網路請求
    NSURLRequest *requst = [NSURLRequest requestWithURL:url];
    //5.建立非同步網路連線
//    NSOperationQueue  佇列類
//    [NSOperationQueue mainQueue]   獲取主隊類
    
    
    /*
    //讓當前的self 物件處於引用狀態
    __block typeof(self) weakSelf = self;
    [NSURLConnection sendAsynchronousRequest:requst queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        //data 就是請求下來的資料
        //response 就是響應物件
        //connectionError 就是存放連線時報錯資訊的物件
        //呼叫解析方法
        [weakSelf parserData:data];
    }];
    */
    
   <span style="color:#ff0000;"> //代理完成非同步解析</span>
    [NSURLConnection connectionWithRequest:requst delegate:self];
  
}

代理完成非同步解析:

#pragma mark NSURLConnection 代理方法
//當接收到伺服器響應的時候觸發
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    //一旦接收到伺服器的響應,就建立拼接的data物件
    self.data = [NSMutableData data];
}
//當接收到伺服器資料的時候觸發
//此方法有可能觸發多次,原因:1.網路環境比較差時 2.請求的資料量比較大的時候,此時伺服器會分多次把資料傳輸過來
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    //拼接伺服器傳輸的資料
    [self.data appendData:data];
}
//當接收到伺服器傳輸資料結束的時候觸發
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    //此時資料已經接收完畢,可以解析了
    [self parserData:self.data];
}
顯示在控制元件上:
- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        BusinessCell *cell = [tableView dequeueReusableCellWithIdentifier:@"getcell" forIndexPath:indexPath];
    //呼叫cell的控制元件的賦值方法
    [cell assignValueByBusiness:self.dataSource[indexPath.row]];
    return cell;
}
GET兩種資料請求完成!

檢視效果:

GET同步和非同步資料請求效果:

     ——————————    

————————————————POST資料請求——————————————————————
定義相關屬性:

#import "POSTViewController.h"
#import "Business.h"
#import "CustomCell.h"

@interface POSTViewController ()
@property(nonatomic,retain)NSMutableArray *dataSource;
@end

@implementation POSTViewController
- (void)dealloc{
    self.dataSource = nil;
    [super dealloc];
}
- (NSMutableArray *)dataSource{
    if (_dataSource == nil) {
        self.dataSource = [NSMutableArray arrayWithCapacity:0];
    }
    return [[_dataSource retain]autorelease];
}
POST同步資料請求:
//Post同步
//http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/
//date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213
- (IBAction)handlePostSyncRequst:(UIBarButtonItem *)sender {


    [self.dataSource removeAllObjects];
    
    //1.準備網址字串
    NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/";
    //2.建立NSURL物件
    NSURL *url = [NSURL URLWithString:urlStr];
    //3.建立網路請求物件
    NSMutableURLRequest *requst = [NSMutableURLRequest requestWithURL:url];
    //3.1配置請求方式
    requst.HTTPMethod = @"POST";
    //4.建立引數字串
    NSString *bodyString = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    //將字串轉換為NSDate獨享
    NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
    //配置網路請求的方式
    requst.HTTPBody = data;
    
    //5.建立網路連結
    NSURLResponse *response = nil;
    NSError *error = nil;
  NSData *data1 =  [NSURLConnection sendSynchronousRequest:requst returningResponse:&response error:&error];
    
//    NSLog(@"%@",data1);
    
    [self parserData: data1];

    
}
POST同步資料請求:
//post非同步
- (IBAction)handlePostAsyncRequest:(UIBarButtonItem *)sender {

    [self.dataSource removeAllObjects];
    
    //1.建立網址字串
    NSString *urlStr =  @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx/";
    //2.建立NSURL物件
    NSURL *url = [NSURL URLWithString:urlStr];
    //3.建立網路請求物件
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    //3.1建立請求方式
 request.HTTPMethod = @"POST";
    //4.建立引數物件
    NSString *bodyString = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
    NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
    //設定請求物件的body
    request.HTTPBody = data;
    
    //5.建立網路連結
    __block typeof(self) weakself = self;
    
  [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//      NSLog(@"%@",data);
      
      [weakself parserData:data];
     
  }];
   
}

封裝一個解析的方法

- (void)parserData : (NSData *)data{
    
    //解析:
    NSMutableDictionary *dataDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//        NSLog(@"%@",dataDic); //驗證!
    //取出results key值對應的陣列
    NSArray *array = dataDic[@"news"];
//    NSLog(@"%@",array);
    //遍歷陣列的字典,並使用給Business物件賦值
    for (NSDictionary *dic in array) {
        //建立資料模型物件
        Business *bus = [[Business alloc]init];
        
        //使用kvc給bus賦值
        [bus setValuesForKeysWithDictionary:dic];
//        NSLog(@"%@",bus);
        //新增到儲存所有商戶資訊的陣列
        [self.dataSource addObject:bus];
        //釋放
        [bus release];
//                NSLog(@"%@",self.dataSource); //驗證!
        
        
    }
    //重新整理ui介面
    [self.tableView reloadData];
}
顯示在控制元件上:
- (void)viewDidLoad {
    [super viewDidLoad];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // Return the number of rows in the section.
    return self.dataSource.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"post" forIndexPath:indexPath];
    
    [cell setValueByName:self.dataSource[indexPath.row]];
    
    return cell;
}

POST兩種資料請求完成!

檢視兩種效果效果:
————————————



————————————————————————————————————————————

——————————————介紹同步卡頓現象——————————————————————

BigImageViewController.m

@interface BigImageViewController ()
@property (retain, nonatomic) IBOutlet UIImageView *bigImageView;
@end

@implementation BigImageViewController
- (IBAction)handleKaDun:(UIButton *)sender {
    
    //1.準備網址字串
    NSString *urlStr = @"http://f1.topit.me/1/d2/8c/11663656284128cd21o.jpg";
    
    //2.初始化NSURL物件
    NSURL *url = [NSURL URLWithString:urlStr];
    
    //3.建立請求物件
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //4.建立網路連線
    //4.1建立響應度向
    NSURLResponse  *response = nil;
    NSError *errror = nil;
 NSData *data =   [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&errror];
    
    //音樂資料,視訊資料,圖片資料不需要解析直接可以使用
    self.bigImageView.image = [UIImage imageWithData:data];
    
}
效果展示:

————————————————————————————————————————————