iOS中GET 和 POST 資料請求
阿新 • • 發佈:2019-02-16
iOS中GET 和 POST 網路資料請求
同步請求和非同步請求的差別:
1.同步請求,有主執行緒完成網路請求任務,在資料沒有請求之前,使用者的所有的互動事件應用都無法處理,會造成一種卡頓現象,影響使用者體驗
2.非同步同步,系統預設開闢子執行緒完成網路請求任務,主執行緒依然會處理使用者的互動事件,此時不會出現卡頓,一旦開闢子執行緒就會消耗資源(記憶體),此時就是拿空間換時間
先分析下整體思路:
1.下面準備一個公用的model資料資料模型:
Business.h
Business.m#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
#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=大保健®ion=上海&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=大保健®ion=上海&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];
}
效果展示:
————————————————————————————————————————————