UITableView介绍 之 加载网络数据

UITableView加载网络数据

  UITableView加载网络数据是一个很常见的需求,但是要彻底理解还是需要认真学习一下的。

加载简单的字信息

使用苹果原生的网络请求API

  首先新建一个空的ios项目,在默认的UIViewController的viewDidLoad方法中初始化UITableView,并实现UITableViewDataSource中的要求的代理方法,具体代码如下:

#import "ViewController.h"

// 定义static变量
static NSString *const ID = @"cell";

@interface ViewController ()<UITableViewDataSource>

/**数据源*/
@property (nonatomic, strong) NSMutableArray *dataSource;
/**table引用*/
@property (nonatomic, weak) UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:tableView];
    self.tableView = tableView;
    tableView.dataSource = self;
    
    // cell注册
    [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
    
    // 请求数据
    // ......
}

#pragma mark -  代理方法<UITableViewDataSource>
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataSource.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    // 先从缓存中找,如果没有再创建
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    cell.textLabel.text = self.dataSource[indexPath.row];
    
    return cell;
}

/**
 *  数据源懒加载
 */
- (NSMutableArray *)dataSource {
    if (_dataSource == nil) {
        _dataSource = [NSMutableArray array];
    }
    return _dataSource;
}

@end

tableView的基本框架已搭好,剩下的就是处理网络请求和返回数据的解析

 为了模拟数据web端用Node.js写了一个小小的http服务器代码也非常简单,服务端代码:

const http = require('http');
const hostname = '127.0.0.1';
const port = 8000;
// 从外部获取数据
const data = require('./data.js');

http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/json;charset=UTF-8' });
  // 将数据返回给客户端
  res.end(JSON.stringify(data));
}).listen(port);

console.log('server is running');

返回Json的格式如下:

{"data": 
	[
        {
            "text": "光计算机离我们究竟还有多远?"
        },
        {
            "text": "Google揭秘SSD可靠性:SLC闪存神话破灭"
        }
        ....
     ]
 }

访问网络请求:

/**
 *  请求网络数据
 */
- (void)getDataFromWeb {
    NSString *url = @"http:192.168.31.167:8000";
    
    // 创建session
    NSURLSession *session = [NSURLSession sessionWithConfiguration:
            [NSURLSessionConfiguration defaultSessionConfiguration]];
    // 创建请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    
    // 为了防止block中产生循环引用
    __weak typeof (self)weakSelf = self;
    // 创建请求任务
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, 
    NSURLResponse *response, NSError *error) {
        // 请求完成处理
        if (error) {
            NSLog(@"Error :%@", error.localizedDescription);
        } else {
            // 将Json数据解析成OC对象
            NSDictionary *
            dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            NSMutableArray *arr = [NSMutableArray array];
            NSArray *temp = dict[@"data"];
            
            for (NSInteger i=0; i < temp.count; i++) {
                [arr addObject: [NSString stringWithFormat:@"%zd、%@",(i + 1), temp[i][@"text"]]];
            }
            
            // 在主线程中刷新数据
            [weakSelf performSelectorOnMainThread:@selector(refreshDataSource:) 
                                               withObject:arr waitUntilDone:YES];
        }
        
    }];
    // 启动请求
    [task resume];
    
}

/**
 *  刷新数据源
 */
- (void)refreshDataSource:(NSArray *)data {
    [self.dataSource addObjectsFromArray:data];
    [self.tableView reloadData];
}

注意:如果是ios9系统要访问http请求要在plist文件中加入如下代码

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

运行效果

使用三方框架进行网络请求

ios的网络框架比较多,现在比较流行的就是AFNetworking github地址

这个框架基本包含了http请求的所有功能,而且使用起来也比较方便,所以也被广泛应用到很多商业软件中,获取AFNetworking的方式大体有两种,一种是以cocoapods方式获取然后统一管理框架的版本和框架与框架之间的依赖,另一种方式直接从github上下载源码,找到其中的AFNetworking文件夹拖到工程中就可以了。

使用前先要在ViewController中引入AFNetworking.h,那么上面的网络请求代码就可以改写成如下形式:

/**
 *  请求网络数据
 */
- (void)getDataFromWeb {
    
    // 为了防止block中产生循环引用
    __weak typeof (self)weakSelf = self;
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    [manager GET:@"http:192.168.31.167:8000" parameters:nil progress:nil 
                    success:^(NSURLSessionTask *task, id responseObject) {
        // responseObject已经被解析成了OC
        NSDictionary *dict = responseObject;
        
        NSMutableArray *arr = [NSMutableArray array];
        NSArray *temp = dict[@"data"];
        
        for (NSInteger i=0; i < temp.count; i++) {
            [arr addObject: [NSString stringWithFormat:@"%zd、%@",(i + 1), temp[i][@"text"]]];
        }
        // 由于这个block是在主线程中执行的所以可以直接在这里刷新数据
        [weakSelf refreshDataSource:arr];
    } failure:^(NSURLSessionTask *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

使用三方框架后代码简洁了不少,关于AFNetworking的其他用法官方文档也比较详细这里就不多说了,到此UITableView获取简单的网络数据就介绍完了。

posted @ 2016-03-01 23:08  Code_XQ  阅读(1414)  评论(0编辑  收藏  举报