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获取简单的网络数据就介绍完了。