網(wǎng)絡(luò)請求:
http協(xié)議了解
客戶端發(fā)送請求信息(GET)
服務(wù)器根據(jù)網(wǎng)絡(luò)鏈接, 找到對應(yīng)的相應(yīng)方法, 去服務(wù)器的數(shù)據(jù)庫查找數(shù)據(jù)
客戶端就可以接收到返回的數(shù)據(jù),就可以處理數(shù)據(jù)
JSON/XML處理數(shù)據(jù)
JSON/XML技術(shù): 手機開發(fā) web開發(fā) 服務(wù)器開發(fā)
- http參數(shù)怎么傳遞(GET)
1. http -> http協(xié)議 2. open.qyer.com ->公司的服務(wù)器域名 3. lastminute/get_lastminute_list -> 服務(wù)器程序唯一對應(yīng)一個方法 4. ?是來分隔前面的請求方法和后面的參數(shù)的 5. ?后面的內(nèi)容都是GET請求的參數(shù)信息 6. client_id=qyer_ios:鍵值對的方式, client_id是參數(shù)名, 類似于函數(shù)的形參, qyer_ios是參數(shù)值,類似于函數(shù)的實參
同步: 所有事情都是按照先后順序來做(效率比較低, 阻塞主線程)
異步: 所有事情都是同時進行(效率比較高)
目錄
一. NSURLConnection實現(xiàn)網(wǎng)絡(luò)下載
二. 根據(jù)城覓首頁的接口, 實現(xiàn)下載, 顯示數(shù)據(jù)
- 創(chuàng)建導(dǎo)航視圖控制器, 創(chuàng)建表格視圖TabelView
- 網(wǎng)絡(luò)下載數(shù)據(jù), 遵守協(xié)議NSURLConnectionDelegate, NSURLConnectionDataDelegate
- 用下載并解析好的數(shù)據(jù)創(chuàng)建數(shù)據(jù)源(使用KVC設(shè)置屬性值, 所以模型中要重寫- (void)setValue:(id)value forUndefinedKey:(NSString *)key)
- 自定義Cell(如果使用Xib的方式的話, 一定要在在.xib文件中設(shè)置重用標(biāo)簽), 注冊Cell, 實現(xiàn)UITableView的相關(guān)協(xié)議方法返回Cell等
- 因為網(wǎng)絡(luò)數(shù)據(jù)是異步下載的, 因此在成功下載數(shù)據(jù)創(chuàng)建數(shù)據(jù)源后需要刷新表格
三. 愛限免的首頁
- 新建UITabBarController的子類和5個視圖控制器的類
- 在新建的UITabBarController的子類中創(chuàng)建需要其管理的5個視圖控制器
- 設(shè)置LimitFreeController的導(dǎo)航條
- 下載數(shù)據(jù)創(chuàng)建表格視圖UITableView對象, 實現(xiàn)下載數(shù)據(jù)的代理方法(表格視圖的代理方法略)
- 創(chuàng)建模型類, 完成自定義Cell
- 處理下載數(shù)據(jù)創(chuàng)建數(shù)據(jù)源
- 實現(xiàn)UITableView的相關(guān)代理方法, 返回行數(shù), 設(shè)置cell高度, 返回cell
一. NSURLConnection實現(xiàn)網(wǎng)絡(luò)下載
二. 根據(jù)城覓首頁的接口, 實現(xiàn)下載, 顯示數(shù)據(jù)
NSURLConnection是系統(tǒng)實現(xiàn)網(wǎng)絡(luò)請求的方式
目標(biāo): 實現(xiàn)下圖效果
-
創(chuàng)建導(dǎo)航視圖控制器, 創(chuàng)建表格視圖TabelView
-
網(wǎng)絡(luò)下載數(shù)據(jù), 遵守協(xié)議NSURLConnectionDelegate, NSURLConnectionDataDelegate
NSURLConnectionDelegate 下載是否成功等信息
NSURLConnectionDataDelegate 處理返回的數(shù)據(jù)
1. 定義屬性: 網(wǎng)絡(luò)請求
@property (nonatomic, strong) NSURLConnection *conn;
2. 下載數(shù)據(jù)
- (void)downloadData
{
// 1.創(chuàng)建NSURL對象
NSURL *url = [NSURL URLWithString:kHomeUrl];
// 2.創(chuàng)建NSURLRequest類型的對象
NSURLRequest request = [NSURLRequest requestWithURL:url];
// 3.創(chuàng)建NSURLConnection類型的對象, 會自動發(fā)送網(wǎng)絡(luò)請求
/
第一個參數(shù): 請求對象
第二個參數(shù): 代理
*/
_conn = [NSURLConnection connectionWithRequest:request delegate:self];
}
3. 接收下載數(shù)據(jù)并解析下載數(shù)據(jù)
* 定義屬性來接收下載的數(shù)據(jù)
@property (nonatomic, strong) NSMutableData *receiveData;
* 判斷是否下載成功, 如果服務(wù)器響應(yīng), 對下載數(shù)據(jù)進行接收解析
1. 如果下載失敗執(zhí)行此方法
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%@", error);
}
2. 網(wǎng)絡(luò)成功被服務(wù)器處理
// 返回響應(yīng)信息
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 返回的響應(yīng)體
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
NSDictionary *dict = res.allHeaderFields;
NSLog(@"%@", dict);
// 響應(yīng)的狀態(tài)碼
// 200: 正常返回
// 404: 客戶端程序錯誤
// 400: 客戶端的其它錯誤
// 500: 服務(wù)器的錯誤
NSInteger code = res.statusCode;
NSLog(@"%ld", code);
// 清空下載回來的數(shù)據(jù)
[self.receiveData setLength:0];
}
3. 接收下載數(shù)據(jù)
// 通常下載的數(shù)據(jù)量會比較大, 會將數(shù)據(jù)分批下載
// 每一次下載回來都會調(diào)用這個方法
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// 存儲下載回來的數(shù)據(jù)
// 每次下載的數(shù)據(jù)都在data這個形參中
[_receiveData appendData:data];
}
4. 下載結(jié)束時調(diào)用的代理方法
// 前面的代理方法都是異步調(diào)用的, 這個代理方法會將程序返回主線程
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 下載結(jié)束, 處理數(shù)據(jù)
// JSON解析
id result = [NSJSONSerialization JSONObjectWithData:self.receiveData options:NSJSONReadingMutableContainers error:nil];
if ([result isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = result;
NSLog(@"%@", dict);
}
}
-
用下載并解析好的數(shù)據(jù)創(chuàng)建數(shù)據(jù)源(使用KVC設(shè)置屬性值, 所以模型中要重寫
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
)// 下載結(jié)束時調(diào)用的代理方法 // 前面的代理方法都是異步調(diào)用的, 這個代理方法會將程序返回主線程 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // 下載結(jié)束, 處理數(shù)據(jù) // 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設(shè)置屬性值 [model setValuesForKeysWithDictionary:sectionDict]; [self.dataArray addObject:model]; } } }
-
自定義Cell(如果使用Xib的方式的話, 一定要在在.xib文件中設(shè)置重用標(biāo)簽), 注冊Cell, 實現(xiàn)UITableView的相關(guān)協(xié)議方法返回Cell等
-
因為網(wǎng)絡(luò)數(shù)據(jù)是異步下載的, 因此在成功下載數(shù)據(jù)創(chuàng)建數(shù)據(jù)源后需要刷新表格
// 下載結(jié)束時調(diào)用的代理方法 // 前面的代理方法都是異步調(diào)用的, 這個代理方法會將程序返回主線程 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // 下載結(jié)束, 處理數(shù)據(jù) …………………………………………………………………………………… [self.tbView reloadData]; }
三. 愛限免的首頁
-
新建UITabBarController的子類和5個視圖控制器的類
-
在新建的UITabBarController的子類中創(chuàng)建需要其管理的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]]; // 添加導(dǎo)航 UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController:ctrl]; // 添加到數(shù)組中 [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];
}
-
-
設(shè)置LimitFreeController的導(dǎo)航條
- (void)configNavBar { // 設(shè)置導(dǎo)航欄背景圖片 // 圖片拉伸 上下不拉伸 左邊5個點不拉伸 [self.navigationController.navigationBar setBackgroundImage:[[UIImage imageNamed:@"navigationbar"] stretchableImageWithLeftCapWidth:5 topCapHeight:0] forBarMetrics:UIBarMetricsDefault]; // 導(dǎo)航欄中間文字 self.title = @"限免"; // 導(dǎo)航條標(biāo)題文字顏色 // 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];
- 設(shè)置導(dǎo)航條中間標(biāo)題文字顏色和字體
[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上的小圖標(biāo)> // 圖片 ctrl.tabBarItem.image = [[UIImage imageNamed:imageArray[i]] **imageWithRenderingMode:**UIImageRenderingModeAlwaysOriginal]; // 選中時的圖片 ctrl.tabBarItem.selectedImage = [[UIImage imageNamed:selectImageArray[i]] **imageWithRenderingMode:**UIImageRenderingModeAlwaysOriginal];
-
下載數(shù)據(jù)創(chuàng)建表格視圖UITableView對象, 實現(xiàn)下載數(shù)據(jù)的代理方法(表格視圖的代理方法略)
-
新建屬性
@property (nonatomic, strong) UITableView *tbView; @property (nonatomic, strong) NSMutableArray *dataArray; // 下載的數(shù)據(jù) @property (nonatomic, strong) NSMutableData *receiveData;
下載數(shù)據(jù)
- (void)downloadData
{
NSURLConnection *conn = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:kUrl]] delegate:self];
// 遵守協(xié)議, 實現(xiàn)方法
}-
創(chuàng)建表格視圖, 代理方法略
- (void)createTableView
{
// 導(dǎo)航下面
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]; }
-
NSURLConnection協(xié)議方法
// 下載失敗 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"%@", error); } // 網(wǎng)絡(luò)請求返回 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { // 清空以前的數(shù)據(jù) [self.receiveData setLength:0]; } // 每次下載數(shù)據(jù)返回 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.receiveData appendData:data]; } // 下載結(jié)束調(diào)用 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { }
-
-
創(chuàng)建模型類, 完成自定義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中除了連線以外, 勿忘設(shè)置cell的重用標(biāo)簽
-
-
處理下載數(shù)據(jù)創(chuàng)建數(shù)據(jù)源
-
在NSURLConnectionDataDelegate協(xié)議的
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
方法中用下載數(shù)據(jù)創(chuàng)建數(shù)據(jù)源
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 處理下載數(shù)據(jù)
// 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) { // 創(chuàng)建模型對象 LimitFreeModel *model = [[LimitFreeModel alloc] init]; // kvc [model setValuesForKeysWithDictionary:appDict]; // 添加到數(shù)組 [self.dataArray addObject:model]; } // 刷新表格 [self.tbView reloadData]; } }
-
-
實現(xiàn)UITableView的相關(guān)代理方法, 返回行數(shù), 設(shè)置cell高度, 返回cell