iOS controller中網(wǎng)絡數(shù)據(jù)獲取的細節(jié)

一 設置刷新方法

// 添加刷新控件

  • 先將footer隱藏
/**
 * 添加刷新控件
 */
- (void)setupRefresh {

    self.userTableView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewUsers)];
    
    self.userTableView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreUsers)];
    
    self.userTableView.footer.hidden = YES;
}

二 網(wǎng)絡請求結(jié)束在回調(diào)方法中不管成功失敗都要結(jié)束刷新
// 結(jié)束刷新
        [self.userTableView.header endRefreshing];

成功獲取到數(shù)據(jù)還要檢測footer狀態(tài) 判斷是否全部加載完畢

        // 讓底部控件結(jié)束刷新
        [self checkFooterState];

檢測footer狀態(tài)方法

/**
 * 時刻監(jiān)測footer的狀態(tài)
 */
- (void)checkFooterState {

    XMGRecommendCategory *rc = XMGSelectedCategory;
    
    // 每次刷新右邊數(shù)據(jù)時, 都控制footer顯示或者隱藏
    self.userTableView.footer.hidden = (rc.users.count == 0);
    
    // 讓底部控件結(jié)束刷新
    if (rc.users.count == rc.total) { // 全部數(shù)據(jù)已經(jīng)加載完畢
        [self.userTableView.footer noticeNoMoreData];
    } else { // 還沒有加載完畢
        [self.userTableView.footer endRefreshing];
    }
}

每次數(shù)據(jù)加載完畢 刷新tableview都會調(diào)用這個方法

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

所以在這個方法中判斷footer狀態(tài)

// 監(jiān)測footer的狀態(tài)
    [self checkFooterState];
三 點擊cell發(fā)送網(wǎng)絡請求 快速點擊多個cell時候 網(wǎng)絡請求處理

首先,在代理方法中停止之前的刷新動作

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // 結(jié)束刷新
    [self.userTableView.header endRefreshing];
    [self.userTableView.footer endRefreshing];
}

若是有數(shù)據(jù) 就顯示數(shù)據(jù) 刷新tableview 若是沒數(shù)據(jù)就先刷新表格 清空上次的數(shù)據(jù) 再進行刷新請求數(shù)據(jù)

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // 結(jié)束刷新
    [self.userTableView.header endRefreshing];
    [self.userTableView.footer endRefreshing];
    
    XMGRecommendCategory *c = self.categories[indexPath.row];
    if (c.users.count) {
        // 顯示曾經(jīng)的數(shù)據(jù)
        [self.userTableView reloadData];
    } else {
        // 趕緊刷新表格,目的是: 馬上顯示當前category的用戶數(shù)據(jù), 不讓用戶看見上一個category的殘留數(shù)據(jù)
        [self.userTableView reloadData];
    
        // 進入下拉刷新狀態(tài)
        [self.userTableView.header beginRefreshing];
    }
}
五 同時快速切換點擊的時候 對block中回調(diào)數(shù)據(jù)的處理

先定義參數(shù)屬性

/** 請求參數(shù) */
@property (nonatomic, strong) NSMutableDictionary *params;
  • 在刷新方法中 設置完參數(shù) 用屬性保存參數(shù)信息
    // 請求參數(shù)
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"list";
    params[@"c"] = @"subscribe";
    params[@"category_id"] = @(rc.id);
    params[@"page"] = @(rc.currentPage);
// 保存參數(shù)
    self.params = params;
  • 在回調(diào)block中通過參數(shù)判斷 對數(shù)據(jù)進行處理
    (多次網(wǎng)絡請求 我們只要取最后一次請求,其余返回的數(shù)據(jù)放在相對應的模型中就好 不必展示)
        // 不是最后一次請求
        if (self.params != params) return;
  • 不管返回成功失敗 都需要處理 不然上次請求失敗 此次請求中會展示錯誤toast,而實際上此次請求并沒有錯誤
六 控制器銷毀時候 撤銷所有網(wǎng)絡請求
  • 網(wǎng)絡加載慢的時候 用戶可能退出控制器,此時若是請求完成在回調(diào)block中調(diào)用可能會引起崩潰,所以在銷毀控制器的時候,撤銷網(wǎng)絡請求
  • 先定義AFN manager屬性
/** AFN請求管理者 */
@property (nonatomic, strong) AFHTTPSessionManager *manager;
  • 懶加載
- (AFHTTPSessionManager *)manager {
    if (!_manager) {
        _manager = [AFHTTPSessionManager manager];
    }
    return _manager;
}
  • 控制器銷毀的時候調(diào)用
#pragma mark - 控制器的銷毀
- (void)dealloc {
    // 停止所有操作
    [self.manager.operationQueue cancelAllOperations];
}

附上代碼

#import "XMGRecommendViewController.h"
#import <AFNetworking.h>
#import <SVProgressHUD.h>
#import "XMGRecommendCategoryCell.h"
#import <MJExtension.h>
#import "XMGRecommendCategory.h"
#import "XMGRecommendUserCell.h"
#import "XMGRecommendUser.h"
#import <MJRefresh.h>

#define XMGSelectedCategory self.categories[self.categoryTableView.indexPathForSelectedRow.row]

@interface XMGRecommendViewController () <UITableViewDataSource, UITableViewDelegate>
/** 左邊的類別數(shù)據(jù) */
@property (nonatomic, strong) NSArray *categories;

/** 左邊的類別表格 */
@property (weak, nonatomic) IBOutlet UITableView *categoryTableView;
/** 右邊的用戶表格 */
@property (weak, nonatomic) IBOutlet UITableView *userTableView;

/** 請求參數(shù) */
@property (nonatomic, strong) NSMutableDictionary *params;

/** AFN請求管理者 */
@property (nonatomic, strong) AFHTTPSessionManager *manager;
@end

@implementation XMGRecommendViewController

static NSString * const XMGCategoryId = @"category";
static NSString * const XMGUserId = @"user";

- (AFHTTPSessionManager *)manager
{
    if (!_manager) {
        _manager = [AFHTTPSessionManager manager];
    }
    return _manager;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 控件的初始化
    [self setupTableView];
    
    // 添加刷新控件
    [self setupRefresh];
    
    // 加載左側(cè)的類別數(shù)據(jù)
    [self loadCategories];
}

/**
 * 加載左側(cè)的類別數(shù)據(jù)
 */
- (void)loadCategories {
    // 顯示指示器
    [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];
    
    // 發(fā)送請求
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"category";
    params[@"c"] = @"subscribe";
    [self.manager GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
        // 隱藏指示器
        [SVProgressHUD dismiss];
        
        // 服務器返回的JSON數(shù)據(jù)
        self.categories = [XMGRecommendCategory objectArrayWithKeyValuesArray:responseObject[@"list"]];
        
        // 刷新表格
        [self.categoryTableView reloadData];
        
        // 默認選中首行
        [self.categoryTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionTop];
        
        // 讓用戶表格進入下拉刷新狀態(tài)
        [self.userTableView.header beginRefreshing];
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        // 顯示失敗信息
        [SVProgressHUD showErrorWithStatus:@"加載推薦信息失敗!"];
    }];
}

/**
 * 控件的初始化
 */
- (void)setupTableView {
    // 注冊
    [self.categoryTableView registerNib:[UINib nibWithNibName:NSStringFromClass([XMGRecommendCategoryCell class]) bundle:nil] forCellReuseIdentifier:XMGCategoryId];
    [self.userTableView registerNib:[UINib nibWithNibName:NSStringFromClass([XMGRecommendUserCell class]) bundle:nil] forCellReuseIdentifier:XMGUserId];
    
    // 設置inset
    self.automaticallyAdjustsScrollViewInsets = NO;
    self.categoryTableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
    self.userTableView.contentInset = self.categoryTableView.contentInset;
    self.userTableView.rowHeight = 70;
    
    // 設置標題
    self.title = @"推薦關(guān)注";
    
    // 設置背景色
    self.view.backgroundColor = XMGGlobalBg;
}

/**
 * 添加刷新控件
 */
- (void)setupRefresh {
    self.userTableView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewUsers)];
    
    self.userTableView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreUsers)];
    
    self.userTableView.footer.hidden = YES;
}

#pragma mark - 加載用戶數(shù)據(jù)
- (void)loadNewUsers {
    XMGRecommendCategory *rc = XMGSelectedCategory;
    
    // 設置當前頁碼為1
    rc.currentPage = 1;
    
    // 請求參數(shù)
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"list";
    params[@"c"] = @"subscribe";
    params[@"category_id"] = @(rc.id);
    params[@"page"] = @(rc.currentPage);
    self.params = params;
    
    // 發(fā)送請求給服務器, 加載右側(cè)的數(shù)據(jù)
    [self.manager GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
        // 字典數(shù)組 -> 模型數(shù)組
        NSArray *users = [XMGRecommendUser objectArrayWithKeyValuesArray:responseObject[@"list"]];
        
        // 清除所有舊數(shù)據(jù)
        [rc.users removeAllObjects];
        
        // 添加到當前類別對應的用戶數(shù)組中
        [rc.users addObjectsFromArray:users];
        
        // 保存總數(shù)
        rc.total = [responseObject[@"total"] integerValue];
        
        // 不是最后一次請求
        if (self.params != params) return;
        
        // 刷新右邊的表格
        [self.userTableView reloadData];
        
        // 結(jié)束刷新
        [self.userTableView.header endRefreshing];
        
        // 讓底部控件結(jié)束刷新
        [self checkFooterState];
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        if (self.params != params) return;
        
        // 提醒
        [SVProgressHUD showErrorWithStatus:@"加載用戶數(shù)據(jù)失敗"];
        
        // 結(jié)束刷新
        [self.userTableView.header endRefreshing];
    }];
}

- (void)loadMoreUsers {
    XMGRecommendCategory *category = XMGSelectedCategory;

    // 發(fā)送請求給服務器, 加載右側(cè)的數(shù)據(jù)
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"a"] = @"list";
    params[@"c"] = @"subscribe";
    params[@"category_id"] = @(category.id);
    params[@"page"] = @(++category.currentPage);
    self.params = params;
    
    [self.manager GET:@"http://api.budejie.com/api/api_open.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
        // 字典數(shù)組 -> 模型數(shù)組
        NSArray *users = [XMGRecommendUser objectArrayWithKeyValuesArray:responseObject[@"list"]];
        
        // 添加到當前類別對應的用戶數(shù)組中
        [category.users addObjectsFromArray:users];
        
        // 不是最后一次請求
        if (self.params != params) return;
        
        // 刷新右邊的表格
        [self.userTableView reloadData];
        
        // 讓底部控件結(jié)束刷新
        [self checkFooterState];
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        if (self.params != params) return;
        
        // 提醒
        [SVProgressHUD showErrorWithStatus:@"加載用戶數(shù)據(jù)失敗"];
        
        // 讓底部控件結(jié)束刷新
        [self.userTableView.footer endRefreshing];
    }];
}

/**
 * 時刻監(jiān)測footer的狀態(tài)
 */
- (void)checkFooterState {
    XMGRecommendCategory *rc = XMGSelectedCategory;
    
    // 每次刷新右邊數(shù)據(jù)時, 都控制footer顯示或者隱藏
    self.userTableView.footer.hidden = (rc.users.count == 0);
    
    // 讓底部控件結(jié)束刷新
    if (rc.users.count == rc.total) { // 全部數(shù)據(jù)已經(jīng)加載完畢
        [self.userTableView.footer noticeNoMoreData];
    } else { // 還沒有加載完畢
        [self.userTableView.footer endRefreshing];
    }
}

#pragma mark - <UITableViewDataSource>
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // 左邊的類別表格
    if (tableView == self.categoryTableView) return self.categories.count;
    
    // 監(jiān)測footer的狀態(tài)
    [self checkFooterState];
    
    // 右邊的用戶表格
    return [XMGSelectedCategory users].count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (tableView == self.categoryTableView) { // 左邊的類別表格
        XMGRecommendCategoryCell *cell = [tableView dequeueReusableCellWithIdentifier:XMGCategoryId];
        cell.category = self.categories[indexPath.row];
        return cell;
    } else { // 右邊的用戶表格
        XMGRecommendUserCell *cell = [tableView dequeueReusableCellWithIdentifier:XMGUserId];
        cell.user = [XMGSelectedCategory users][indexPath.row];
        return cell;
    }
}

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // 結(jié)束刷新
    [self.userTableView.header endRefreshing];
    [self.userTableView.footer endRefreshing];
    
    XMGRecommendCategory *c = self.categories[indexPath.row];
    if (c.users.count) {
        // 顯示曾經(jīng)的數(shù)據(jù)
        [self.userTableView reloadData];
    } else {
        // 趕緊刷新表格,目的是: 馬上顯示當前category的用戶數(shù)據(jù), 不讓用戶看見上一個category的殘留數(shù)據(jù)
        [self.userTableView reloadData];
    
        // 進入下拉刷新狀態(tài)
        [self.userTableView.header beginRefreshing];
    }
}

#pragma mark - 控制器的銷毀
- (void)dealloc {
    // 停止所有操作
    [self.manager.operationQueue cancelAllOperations];
}
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容