2015-07-15 16 views
11

tôi đang tạo ra một NSMutableRequest:timeout NSURLSessionDataTask yêu cầu tiếp theo thất bại

self.req = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0]; 

Thời gian chờ được thiết lập để có 10 giây bởi vì tôi không muốn người dùng phải chờ đợi quá lâu để có được một thông tin phản hồi. Sau đó tôi tạo ra một NSURLSessionDataTask:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response; 
    if (error) { 
     // this is where I get the timeout 
    } 
    else if (httpResp.statusCode < 200 || httpResp.statusCode >= 300) { 
     // handling error and giving feedback 
    } 
    else { 
     NSError *serializationError = nil; 
     NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&serializationError]; 
    } 
    [task resume]; 
} 

Vấn đề là các máy chủ đi vào Cổng Timeout và phải mất rất nhiều thời gian. Tôi nhận được lỗi hết thời gian chờ và tôi đưa ra phản hồi cho người dùng, nhưng tất cả các cuộc gọi API sau đều không thành công theo cùng một cách do lỗi hết thời gian chờ. Cách duy nhất để ngăn chặn nó là để giết các ứng dụng và bắt đầu lại. Có điều gì tôi nên làm để giết nhiệm vụ hoặc kết nối sau một lỗi hết thời gian chờ không? Nếu tôi không đặt thời gian chờ và tôi đợi cho đến khi tôi nhận được mã lỗi từ máy chủ thì tất cả các cuộc gọi sau hoạt động hoàn hảo (Nhưng người dùng chờ rất nhiều!).

tôi đã cố gắng để hủy bỏ nhiệm vụ:

NSURLSessionDataTask *task = [self.session dataTaskWithRequest:self.req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    NSHTTPURLResponse * httpResp = (NSHTTPURLResponse *)response; 
    if (error) { 
     // this is where I get the timeout 
     [task cancel]; 
    } 
    ... 
    [task resume]; 
} 
+0

tôi đoán, bạn có thể yêu cầu để tái khởi tạo 'self.req' nếu có một lỗi/thời gian chờ. Không chắc chắn về điều này mặc dù. – Mrunal

+0

thử gọi các kết nối bằng ứng dụng POSTMAN trong chrome và xem bạn vẫn nhận được lỗi hết thời gian chờ hay không –

+0

Bạn có đang tạo tác vụ này trong một số khối không? Hoặc một số chủ đề khác, ngoài chủ đề chính? –

Trả lời

4

tôi didnt xem bạn tiếp tục công việc bạn bắt đầu. Bạn cần khai báo:

[task resume]; 

Dòng này Tiếp tục công việc, nếu nó bị tạm ngưng.

Cố gắng gọi NSURLSession như sau:

[NSURLSession sharedSessison] instead of self.session 

và vô hiệu hóa phiên bởi:

[[NSURLSession sharedSession]invalidateAndCancel]; 

Từ Tài liệu của Apple:

Khi ứng dụng của bạn không còn cần có một phiên , vô hiệu hóa nó bằng cách gọi hoặc invalidateAndCancel (để hủy các tác vụ xuất sắc) hoặc finishTasksAndInvalidate (để cho phép nhiệm vụ xuất sắc để hoàn thành trước khi vô hiệu hóa đối tượng).

- (void)invalidateAndCancel 

Khi không còn giá trị, tài liệu tham khảo cho các đối tượng đại biểu và gọi lại là bị hỏng. Không thể sử dụng lại các đối tượng phiên.

Để cho phép tác vụ xuất sắc chạy cho đến khi hoàn thành, hãy gọi finishTasksAndInvalidate thay thế.

- (void)finishTasksAndInvalidate 

Phương pháp này sẽ trả về ngay lập tức mà không cần chờ công việc kết thúc. Sau khi phiên không hợp lệ, không thể tạo tác vụ mới trong phiên, nhưng các tác vụ hiện tại vẫn tiếp tục cho đến khi hoàn thành. Sau khi tác vụ cuối cùng kết thúc và phiên làm cho cuộc gọi đại biểu cuối cùng, tham chiếu đến các đối tượng đại biểu và gọi lại bị hỏng. Không thể sử dụng lại các đối tượng phiên.

Để hủy tất cả tác vụ chưa xử lý, hãy gọi invalidateAndCancel để thay thế.

+0

Có, tôi đã quên tiếp tục ở đây trong câu hỏi. Tôi sẽ chỉnh sửa nó. Và phương pháp duy nhất tôi có thể gọi vào nhiệm vụ để vô hiệu hóa nó, là "hủy bỏ". Tôi không thể thấy những người khác. Tôi đã thử nhưng nó không giải quyết được vấn đề. Cảm ơn –

+0

how u r gọi hủy? –

+0

Tôi đã chỉnh sửa câu hỏi. Cảm ơn –

0

Nguyên nhân có thể xảy ra nhất cho thời gian chờ là DNS được giải quyết thành địa chỉ IP không tồn tại hoặc máy chủ bị lỗi và cần khởi động lại. Trong mọi trường hợp, nếu một yêu cầu không thành công với thời gian chờ, nhiều yêu cầu hơn có khả năng bị lỗi thời gian chờ hợp lý.

Bạn rõ ràng là cần viết ứng dụng của mình theo cách sao cho nó có thể tồn tại khi máy chủ không trả lời.

+0

Nếu tôi đặt thời gian chờ là 60 thay vì 10 giây, tôi nhận được "Thời gian chờ cổng" từ máy chủ và tất cả yêu cầu tôi làm sau đó hoạt động hoàn hảo. Vấn đề là khi thời gian chờ xảy ra trước khi câu trả lời từ máy chủ. Tất cả các yêu cầu sau đều không thành công cho đến khi tôi xóa ứng dụng. –

1

Bạn có thể thiết lập thời gian chờ theo cách khác nhau như mã sau

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
sessionConfiguration.timeoutIntervalForRequest = timeout; 
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:nil delegateQueue:nil]; 
1

Vấn đề mà bạn đang có lẽ hầu hết gặp phải ở đây là nhiệm vụ của bạn không được hủy hoặc hoàn thành và được do đó giữ phiên từ chấp nhận bất kỳ nhiệm vụ hơn . Theo tài liệu của Apple

Sau khi bạn tạo một tác vụ, bạn bắt đầu bằng cách gọi phương thức tiếp tục của nó. Phiên sau đó duy trì một tham chiếu mạnh mẽ đến nhiệm vụ cho đến khi yêu cầu kết thúc hoặc không thành công;

Như T_77 gợi ý, hãy thử sử dụng [NSURLSession sharedSession]

Ngoài ra một điều nữa tôi sẽ cố gắng để làm tại thời điểm này đang cố gắng để tìm hiểu xem có một chu kỳ giữ lại tạo ra giữa các đối tượng session và nhiệm vụ, sử dụng các công cụ

Một điều nữa có thể xảy ra là yêu cầu không được tạo đúng và không được thực hiện hoặc bị treo. Tôi đã phải đối mặt với một vấn đề tương tự một lần khi tôi cố gắng tải một URL vào một trang web. Trang không tải và không phát ra lỗi. Thử xác minh yêu cầu url cũng một lần.

Cảm ơn, Suraj

Các vấn đề liên quan