我正从非常慢的服务器下载JSON数据。从服务器获得一个resoonse大约需要一分钟。我使用AFNetworking库,我的代码抛出“请求超时”错误:
NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
[self parseJsonWithAccountsData:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", operation.responseString);
[self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
}];
没有找到为AFHTTPRequestOperationManager
设置超时的方法。我该怎么办?
答案 0 :(得分:41)
在AFNetworking 2库中,AFHTTPRequestSerializer
中的方法直接设置了请求超时间隔。
NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
[manager.requestSerializer setTimeoutInterval:TIME_OUT_INTERVAL];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
[self parseJsonWithAccountsData:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", operation.responseString);
[self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
}];
您无需覆盖类以设置请求超时间隔。
答案 1 :(得分:12)
方法1。
我认为最好的方法是继承AFHTTPRequestSerializer
并覆盖
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
像这样:
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
{
NSMutableURLRequest *request = [super requestWithMethod:method URLString:URLString parameters:parameters];
[request setTimeoutInterval:YOUR_TIMEOUT_INTERVAL_HERE];
return request;
}
然后
NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
[manager setRequestSerializer:YOUR_NEW_REQUEST_SERIALIZER_HERE];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
[manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
[self parseJsonWithAccountsData:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", operation.responseString);
[self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
}];
方法2
NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
[manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
[manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:urlString relativeToURL:manager.baseURL] absoluteString] parameters:nil];
[request setTimeoutInterval:YOUR_TIMEOUT_INTERVAL_HERE];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", responseObject);
[self parseJsonWithAccountsData:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", operation.responseString);
[self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
}];
[manager.operationQueue addOperation:operation];
答案 2 :(得分:4)
我有点懒于分类或子类。您可以直接访问经理的请求序列化程序:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer.timeoutInterval = INTERNET_TIMEOUT;
manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
答案 3 :(得分:1)
创建子类
self.requestOperationManager.requestSerializer = [[TimeoutAFHTTPRequestSerializer alloc] initWithTimeout:30];
<强> TimeoutAFHTTPRequestSerializer.h 强>
#import "AFURLRequestSerialization.h"
@interface TimeoutAFHTTPRequestSerializer : AFHTTPRequestSerializer
@property (nonatomic, assign) NSTimeInterval timeout;
- (id)initWithTimeout:(NSTimeInterval)timeout;
@end
<强> TimeoutAFHTTPRequestSerializer.m 强>
#import "TimeoutAFHTTPRequestSerializer.h"
@implementation TimeoutAFHTTPRequestSerializer
- (id)initWithTimeout:(NSTimeInterval)timeout {
self = [super init];
if (self) {
self.timeout = timeout;
}
return self;
}
- (NSMutableURLRequest *)requestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
error:(NSError *__autoreleasing *)error
{
NSMutableURLRequest *request = [super requestWithMethod:method URLString:URLString parameters:parameters error:error];
if (self.timeout > 0) {
[request setTimeoutInterval:self.timeout];
}
return request;
}
@end
答案 4 :(得分:1)
实际上,timeoutInterval
属性的值会被忽略 - 我已通过调试方法requestWithMethod:URLString:parameters:error:
来检查
我设法子类化并覆盖方法(Swift)
class RequestSerializer: AFHTTPRequestSerializer {
override func requestWithMethod(method: String!, URLString: String!, parameters:AnyObject!, error: NSErrorPointer) -> NSMutableURLRequest {
var req = super.requestWithMethod(method, URLString: URLString, parameters: parameters, error: error)
req.timeoutInterval = self.timeoutInterval
return req
}
}