AFHTTPRequestOperation 超时
Posted
技术标签:
【中文标题】AFHTTPRequestOperation 超时【英文标题】:AFHTTPRequestOperation times out 【发布时间】:2014-04-29 17:41:43 【问题描述】:我的应用中有一些网络服务调用。这是我如何称呼它们的示例
+(void) login:(NSDictionary *) loginParams
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString * URLString = [MPTLogin getLoginWSAddress];
AFHTTPClient* client = [[AFHTTPClient alloc]initWithBaseURL:[NSURL URLWithString:URLString]];
NSMutableURLRequest *request = [client requestWithMethod:@"POST"
path:URLString
parameters:loginParams];
AFHTTPRequestOperation* operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
[[NSNotificationCenter defaultCenter] postNotificationName:@"didSuccessfullyAttemptLogin" object:nil userInfo:nil];
failure:^(AFHTTPRequestOperation *operation, NSError *error)
if ([operation.response statusCode] == 401)
[[NSNotificationCenter defaultCenter] postNotificationName:@"invalidUserNameOrPassword" object:self userInfo:nil];
else
[[NSNotificationCenter defaultCenter] postNotificationName:@"didFailedAttemptLogin" object:self userInfo:nil];
];
[operation start];
问题是,如果在 5-15 分钟内没有调用任何 Web 服务,则下一个调用的 Web 服务会超时。然后,之后的任何调用只需要一秒钟的时间即可完成,直到几分钟内没有调用。然后同样的事情再次发生。
这只发生在设备上。模拟器很好。另外,这不是wifi问题。我完全不知道如何调试它。
更新:所以我检查了服务器日志,呼叫没有按时到达。 我也尝试使用Charles Proxy。最离奇的事情发生了。当代理打开时,不会发生超时。事实上,电话几乎是立即发生的。但是当我取消代理时,会发生同样的问题。
更新:这不是 wifi 问题,因为我们已经在不同的设备、不同的 wifi 连接、不同的状态下进行了尝试。
更新所以我最终将超时设置为 150 秒。现在,我的超时时间减少了,但问题是每当我超时时,控制台都会说它需要 60 秒。超时代码也是-1001
【问题讨论】:
loginParams 和 URLString 的示例值是什么?它正在使用代理但不使用代理?服务器可以认为该请求是垃圾邮件请求吗?只是随机猜测。 loginParams 是字典:@@"userName":@"simpleString",@"password":@"smipleString",@"deviceName":@"Somestring_anInt"; 你设置的超时时间是在服务器端还是 NSMutableURLRequest 上的 timeoutInterval?如果是 NSMutableURLRequest,150 秒太长了。你能截屏或粘贴超时错误日志吗? 【参考方案1】:根据我使用 Web 服务和 AFHTTPRequest 的经验,请求超时主要与服务器/网络相关。如果您确认服务器没有任何问题,我认为您能做的最好的事情就是将请求发送到 timeoutInterval(例如:15 秒)。接下来,如果您仍然收到请求超时错误,您可以尝试N次相同的操作。
例如,您可以执行以下操作:-
重试 3 次调用函数:
[ServerRequest yourMethodName:yourLoginDict with:3];
功能:-
+(void)yourMethodName:(NSDictionary *) loginParams with:(NSUInteger)ntimes
if (ntimes <= 0)
NSLog(@"Request failed after trying for N times");
else
NSDictionary * postDictionary = loginParams;
NSError * error = nil;
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:postDictionary options:NSJSONWritingPrettyPrinted error:&error];
NSString * urlString = [NSString stringWithFormat:@"%@",@"YOUR URL"];
//Give the Request 15 seconds to load
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15.0];
[urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:jsonData];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:urlRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
NSLog(@"Successful request");
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Request Failed at %d: %@",ntimes,error);
//If the request failed, call again with ntimes-1
[self yourMethodName:loginParams with:ntimes-1];
];
[operation start];
我希望这会有所帮助。
【讨论】:
感谢您的回答。我要试试这个。所以这个问题导致了两件事。第一个只是很长的等待,第二个是失败。这将避免失败,但我仍然希望避免等待。 没问题。如果等待时间过长,可以将 timeoutInterval 减小到 10 或 5 秒。这真的取决于你需要什么。如果您一直面临这个问题,我认为问题实际上出在连接或服务器端。不是你的前端代码的问题。 也许您可以在尝试完代码后报告任何性能或问题,我会看看我能进一步提供什么帮助。【参考方案2】://创建推特账号 -(void)createTwitterAccountWithDictionary:(NSDictionary*)dictionary WithCompletionBlock:(void(^)(user *userObj,NSString *errorMessager))completionBlock
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager manager] initWithBaseURL:BASE_URL];
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
[manager POST:KCreateTwitterAccount parameters:dictionary success:^(AFHTTPRequestOperation *operation, id responseObject)
NSLog(@"Request url:%@",operation.request.URL);
NSLog(@"Response: %@", responseObject);
if ([responseObject[@"status"]isEqualToString:@"SUCCESS"])
user *userObj = [[user alloc]initWithUserDictionary:responseObject[@"data"]];
completionBlock(userObj,nil);
[SVProgressHUD showSuccessWithStatus:@"Success"];
else
[SVProgressHUD dismiss];
completionBlock(nil,responseObject[@"message"]);
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSLog(@"Request url:%@",operation.request.URL);
NSLog(@"Error: %@", error);
[SVProgressHUD showErrorWithStatus:@"Failure"];
];
在 AFURLResponseSerialization.m 中 做了这些改变
- (instancetype)init
self = [super init];
if (!self)
return nil;
#pragma mark - did changes
//add this @"text/html"
self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", nil];
return self;
【讨论】:
以上是关于AFHTTPRequestOperation 超时的主要内容,如果未能解决你的问题,请参考以下文章
未知接收者'AFHTTPRequestOperation';你的意思是'AFHTTPRequestSerializer'
Swift错误无法转换类型'(AFHTTPRequestOperation?,AnyObject?)->()的值
AFHTTPRequestOperation setCacheResponseBlock 无法转换类型的值
AFNetworking + AFHTTPRequestOperation 无法保存数组