AFNtworking同步请求解决方法

很多时候我们在做网络请求的时候,往往要拿到数据后才能去处理进一步的操作。但是,AFNetworking并没有同步的方法,那么我们应该怎么处理呢?


方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
- (void)getWeatherData
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

__block dispatch_semaphore_t sem = dispatch_semaphore_create(0);
__block BOOL isSuccess = NO;
__block NSDictionary *json = nil;

[manager GET:@"http://www.weather.com.cn/data/sk/101010100.html"
parameters:nil
success:^(NSURLSessionDataTask *task, id responseObject)
{
NSLog(@"加载成功 %@",responseObject);

isSuccess = YES;

if ([responseObject isKindOfClass:[NSDictionary class]]) {
json = responseObject;
}

dispatch_semaphore_signal(sem);

} failure:^(NSURLSessionDataTask *task, NSError *error) {

NSLog(@"加载失败 %@",error);

isSuccess = NO;

dispatch_semaphore_signal(sem);
}];

dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

dispatch_async(dispatch_get_main_queue(), ^{

/* 回到主线程做进一步处理 */

if(isSuccess) {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"请求成功" message:[NSString stringWithFormat:@"%@",json] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alert show];
}
});
});
}

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
- (void)getWeatherData
{
dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSCondition *condition = [[NSCondition alloc] init];

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

__block BOOL isSuccess = NO;
__block NSDictionary *json = nil;

[manager GET:@"http://www.weather.com.cn/data/sk/101010100.html"
parameters:nil
success:^(NSURLSessionDataTask *task, id responseObject)
{
NSLog(@"加载成功 %@",responseObject);

isSuccess = YES;

if ([responseObject isKindOfClass:[NSDictionary class]]) {
json = responseObject;
}

[condition lock];
[condition signal];
[condition unlock];

} failure:^(NSURLSessionDataTask *task, NSError *error) {

NSLog(@"加载失败 %@",error);

isSuccess = NO;

[condition lock];
[condition signal];
[condition unlock];
}];

[condition lock];
[condition wait];
[condition unlock];

dispatch_async(dispatch_get_main_queue(), ^{

/* 回到主线程做进一步处理 */

if(isSuccess) {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"请求成功" message:[NSString stringWithFormat:@"%@",json] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alert show];
}
});
});
}

方法三:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- (NSDictionary *)getJsonData
{
NSString *url = [NSString stringWithFormat:@"请求的url字符串"];

/* 请求参数字典 */
NSMutableDictionary *requestParms = [[NSMutableDictionary alloc] init];
[requestParms setObject:@"value" forKey:@"key"];

AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"POST" URLString:url parameters:requestParms error:nil];

/* 最终继承自 NSOperation,看到这个,大家可能就知道了怎么实现同步的了,也就是利用 NSOperation 来做的同步请求 */
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
AFHTTPResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];

[requestOperation setResponseSerializer:responseSerializer];

[requestOperation start];

[requestOperation waitUntilFinished];

/* 请求结果 */
NSDictionary *result = (NSDictionary *)[requestOperation responseObject];

if (result != nil) {

return result;
}
return nil;
}

小结

使用上面任意一种方法都可以解决AFNetworking同步请求的操作。需要注意的是,前两种方法中请求要放在异步线程执行,否则会死锁,在请求结束后再回到主线程执行。


原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0