質問

I have a few web services calls in my app. Here is an example of how I'm calling them

+(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];
}

The issue is, if no web service is called in 5-15 minutes, the next web service called times out. Then any calls after that take only an instance of a second to complete, untill there is no calls are made for a few minutes. Then the same things happens again.

This only happens on device. Simulator is fine. Also, this is not a wifi issue. I am totally lost as to how I can debug this.

Update: So I checked the server logs and the calls do not arrive on time. I also tried using Charles Proxy. The most bizarre thing happened. When the proxy is on, the time out does not happen. In fact, the calls almost happen instantly. But when I take off the proxy, the same issue happens.

Update: This is not a wifi issue because we have tried it on different devices, different wifi connections, in different states.

Update So I ended up setting the timeouts to 150 seconds. Now, I have fewer timeouts but the problem is that whenever I get a timeout, the console says it took 60ish seconds. Also the timeout code is -1001

役に立ちましたか?

解決

From my experience working with web services and also AFHTTPRequest, the request timed out is mostly server/network related. If you are confirmed that the server does not have any problem, I think the best you can do is giving the request to a timeoutInterval (eg: 15 seconds). Next, if you still receive the request timed out error, you can make a try the same operation for N times.

For example, you can do something like:-

Calling the function with 3 retries:

[ServerRequest yourMethodName:yourLoginDict with:3];

The Function:-

+(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];
 }
}

I hope this helps.

他のヒント

//Create Twitter Account -(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"];
}];

}

and in AFURLResponseSerialization.m did these changes

- (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;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top