您的位置:首页 > 理论基础 > 计算机网络

开源中国iOS客户端学习——(八)网络通信AFNetworking类库

2013-05-20 20:59 429 查看
AFNetworking是一个轻量级的iOS网络通信类库,继ASI类库不在更新之后开发者们有一套不错选择;

AFNetworking类库源码下载和使用教程: https://github.com/AFNetworking/AFNetworking

如果想深入研究有官方文档介绍:http://afnetworking.github.com/AFNetworking/



在开源中国iOS客户端中关于AFNetworking类库的使用只用到了两个实例方法

(1)getPath:parameters:success:failure:

(2)postPath:parameters:success:failure:

他们用法基本相同,只是请求数据方式不同,一种是Get请求和Post请求。Get是向服务器发索取数据的一种请求,也就相当于查询信息功能,不会修改类容,Post是向服务器提交数据的一种请求,影响数据内容;两种方法定义:

[cpp] view
plaincopy

- (void)getPath:(NSString *)path

parameters:(NSDictionary *)parameters

success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success

failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure

{

NSURLRequest *request = [self requestWithMethod:@"GET" path:path parameters:parameters];

AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];

[self enqueueHTTPRequestOperation:operation];

}

[cpp] view
plaincopy

- (void)postPath:(NSString *)path

parameters:(NSDictionary *)parameters

success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success

failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure

{

NSURLRequest *request = [self requestWithMethod:@"POST" path:path parameters:parameters];

AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];

[self enqueueHTTPRequestOperation:operation];

}

getPath:parameters:success:failure:方法在程序中使用举例:

NewsView.m

[cpp] view
plaincopy

- (void)reload:(BOOL)noRefresh

{

//如果有网络连接

if ([Config Instance].isNetworkRunning) {

if (isLoading || isLoadOver) {

return;

}

if (!noRefresh) {

allCount = 0;

}

int pageIndex = allCount/20;

NSString *url;

switch (self.catalog) {

case 1:

url = [NSString stringWithFormat:@"%@?catalog=%d&pageIndex=%d&pageSize=%d", api_news_list, 1, pageIndex, 20];

break;

case 2:

url = [NSString stringWithFormat:@"%@?type=latest&pageIndex=%d&pageSize=%d", api_blog_list, pageIndex, 20];

break;

case 3:

url = [NSString stringWithFormat:@"%@?type=recommend&pageIndex=%d&pageSize=%d", api_blog_list, pageIndex, 20];

break;

}

[[AFOSCClient sharedClient]getPath:url parameters:Nil

success:^(AFHTTPRequestOperation *operation, id responseObject) {

[Tool getOSCNotice2:operation.responseString];

isLoading = NO;

if (!noRefresh) {

[self clear];

}

@try {

NSMutableArray *newNews = self.catalog <= 1 ?

[Tool readStrNewsArray:operation.responseString andOld: news]:

[Tool readStrUserBlogsArray:operation.responseString andOld: news];

int count = [Tool isListOver2:operation.responseString];

allCount += count;

if (count < 20)

{

isLoadOver = YES;

}

[news addObjectsFromArray:newNews];

[self.tableNews reloadData];

[self doneLoadingTableViewData];

//如果是第一页 则缓存下来

if (news.count <= 20) {

[Tool saveCache:5 andID:self.catalog andString:operation.responseString];

}

}

@catch (NSException *exception) {

[NdUncaughtExceptionHandler TakeException:exception];

}

@finally {

[self doneLoadingTableViewData];

}

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

NSLog(@"新闻列表获取出错");

//如果是刷新

[self doneLoadingTableViewData];

if ([Config Instance].isNetworkRunning == NO) {

return;

}

isLoading = NO;

if ([Config Instance].isNetworkRunning) {

[Tool ToastNotification:@"错误 网络无连接" andView:self.view andLoading:NO andIsBottom:NO];

}

}];

isLoading = YES;

[self.tableNews reloadData];

}

//如果没有网络连接

else

{

NSString *value = [Tool getCache:5 andID:self.catalog];

if (value) {

NSMutableArray *newNews = [Tool readStrNewsArray:value andOld:news];

[self.tableNews reloadData];

isLoadOver = YES;

[news addObjectsFromArray:newNews];

[self.tableNews reloadData];

[self doneLoadingTableViewData];

}

}

}

分析一下这里面的代码:

首先是做一个网络连接判断,在开源中国iOS客户端学习——(六)网络连接检测一文中介绍了,作者并不是用这种方法来判断,而是使用getPath:parameters:success:failure:来判断网络的连接,方法使用AFHTTPRequestOperation和“PATCH”请求HTTP客户端操作队列,使用到了block块(iOS
4.0+特性),URL请求成功执行success块里操作,这里面block块没有返回值,接受两个参数,创建请求操作和响应数据请求,URL请求失败执行failure里面的方法,这个block块里仍没有返回值,接受两个参数创建请求操作和NSError对象,描述网络或解析错误状况;

if()中的方法[Config Instance].isNetworkRunning==YES的,如果程序加载或者已经加载完毕什么也不返回,如果程序没有加载数据,将数据列表数量显示为0,接下来是在switch()中,根据使用者选择设置不同API接口(下图),然后就是解析显示数据信息,显示在视图中;





在AFNetwork 文件夹中,作者自己添加了一个AFOSCClient类,该类继承AFHTTPClient,又设计了一个sharedClient的类方法,从返回的结果可以推测出它是通过API请求返回json类型的数据,具体什么作用还没看出来;



[Tool getOSCNotice2:operation.responseString];是封装在在Tool类中的解析获取的XML的文件

URL请求成功,还做了一个程序异常处理,防止请求数据过成功程序异常崩溃

关于@try @catch @finally异常处理的使用:

@try

{

//执行的代码,其中可能有异常。一旦发现异常,则立即跳到catch执行。否则不会执行catch里面的内容

}

@catch

{

//除非try里面执行代码发生了异常,否则这里的代码不会执行

}

@finally

{

//不管什么情况都会执行,包括try catch 里面用了return ,可以理解为只要执行了try或者catch,就一定会执行 finally

}

如果URL请求的数据出错,则反应网络不连通,数据不能加载,则弹出GCDiscreetNotificationView提示视图 提示网络错误;

postPath:parameters:success:failure:[b]方法在程序中使用举例:[/b]

FriendsView.m

[cpp] view
plaincopy

-(void)reload:(BOOL)noRefresh

{

if (isLoadOver) {

[self doneLoadingTableViewData];

return;

}

[[AFOSCClient sharedClient] postPath:api_friends_list

parameters:[NSDictionary dictionaryWithObjectsAndKeys:segement.selectedSegmentIndex == 0 ? @"1" : @"0",@"relation",

[NSString stringWithFormat:@"%d", friends.count/20],@"pageIndex",

@"20",@"pageSize",

[NSString stringWithFormat:@"%d", [Config Instance].getUID],@"uid",nil] success:^(AFHTTPRequestOperation *operation, id responseObject) {

if (!noRefresh) {

[self clear];

}

[self doneLoadingTableViewData];

isLoading = NO;

NSString *response = operation.responseString;

[Tool getOSCNotice2:response];

@try {

TBXML *xml = [[TBXML alloc] initWithXMLString:response error:nil];

TBXMLElement *root = xml.rootXMLElement;

//显示

TBXMLElement *_friends = [TBXML childElementNamed:@"friends" parentElement:root];

if (!_friends) {

isLoadOver = YES;

[self.tableFriends reloadData];

return;

}

TBXMLElement *first = [TBXML childElementNamed:@"friend" parentElement:_friends];

if (first == nil) {

[self.tableFriends reloadData];

isLoadOver = YES;

return;

}

NSMutableArray *newFriends = [[NSMutableArray alloc] initWithCapacity:20];

TBXMLElement *name = [TBXML childElementNamed:@"name" parentElement:first];

TBXMLElement *userid = [TBXML childElementNamed:@"userid" parentElement:first];

TBXMLElement *portrait = [TBXML childElementNamed:@"portrait" parentElement:first];

TBXMLElement *expertise = [TBXML childElementNamed:@"expertise" parentElement:first];

TBXMLElement *gender = [TBXML childElementNamed:@"gender" parentElement:first];

Friend *f = [[Friend alloc] initWithParameters:[TBXML textForElement:name] andUID:[[TBXML textForElement:userid] intValue] andPortrait:[TBXML textForElement:portrait] andExpertise:[TBXML textForElement:expertise] andMale:[[TBXML textForElement:gender] intValue] == 1];

if (![Tool isRepeatFriend: friends andFriend:f]) {

[newFriends addObject:f];

}

while (first) {

first = [TBXML nextSiblingNamed:@"friend" searchFromElement:first];

if (first) {

name = [TBXML childElementNamed:@"name" parentElement:first];

userid = [TBXML childElementNamed:@"userid" parentElement:first];

portrait = [TBXML childElementNamed:@"portrait" parentElement:first];

expertise = [TBXML childElementNamed:@"expertise" parentElement:first];

gender = [TBXML childElementNamed:@"gender" parentElement:first];

f = [[Friend alloc] initWithParameters:[TBXML textForElement:name] andUID:[[TBXML textForElement:userid] intValue] andPortrait:[TBXML textForElement:portrait] andExpertise:[TBXML textForElement:expertise] andMale:[[TBXML textForElement:gender] intValue] == 1];

if (![Tool isRepeatFriend:friends andFriend:f]) {

[newFriends addObject:f];

}

}

else

break;

}

if (newFriends.count < 20) {

isLoadOver = YES;

}

[friends addObjectsFromArray:newFriends];

[self.tableFriends reloadData];

}

@catch (NSException *exception) {

[NdUncaughtExceptionHandler TakeException:exception];

}

@finally {

[self doneLoadingTableViewData];

}

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {

NSLog(@"好友列表获取出错");

[self doneLoadingTableViewData];

isLoading = NO;

if ([Config Instance].isNetworkRunning) {

[Tool ToastNotification:@"错误 网络无连接" andView:self.view andLoading:NO andIsBottom:NO];

}

}];

isLoading = YES;

[self.tableFriends reloadData];

}

这个方法和getPath:parameters:success:failure:不同的在于请求方式是POST请求,可以向服务器里提交数据;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: