6

Độc đáo tôi nghĩ rằng nếu NSURLSessionDownloadTask hoàn tất thành công, phương thức URLSession:downloadTask:didFinishDownloadingToURL: sẽ được gọi, nếu không vì lý do nào đó - URLSession:task:didCompleteWithError:. Nó hoạt động như mong đợi trên trình mô phỏng (chỉ một trong những phương pháp này được gọi cho một nhiệm vụ tải xuống) nhưng trên thiết bị này không phải là trường hợp: trong trường hợp thất bại cả hai phương pháp này được gọi là, URLSession:downloadTask:didFinishDownloadingToURL: là người đầu tiên. (cả hai phương pháp này đều chuyển cùng một nhiệm vụ trong các tham số)Xử lý NSURLSessionTải xuốngTask thất bại

Có điều gì đó tôi bị thiếu không?

+0

Tôi đã nhận thấy hành vi tương tự trong đó DidFinishDownloadingToURL được gọi cùng với didCompleteWithError. Điều này đã gây ra những vấn đề to lớn cho chúng ta. Bạn đã làm việc như thế nào? – RunLoop

+0

vị trí có thể nằm trong trường hợp đó. Bạm có thể kiểm tra cái này không? – AsifHabib

Trả lời

1

Sử dụng hoàn thành khối thay vì đại biểu:

NSURLSessionDownloadTask *mySessionDownloadTask = [myURLSession downloadTaskWithRequest:myRequest completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if(!error) 
     { 
      // Finish loading 
     } 
     else 
     { 
       // Handle error 
     }); 
}]; 

Lưu ý: Nếu bạn không nhận được hàng đợi chính, bất kỳ bản cập nhật liên quan đến giao diện người dùng sẽ chậm phát triển gây ra những hành vi bị nghi ngờ.

+1

Tôi muốn người dùng của mình hoàn tất tải xuống khi ứng dụng của tôi chuyển sang chế độ nền, vì vậy tôi không thể sử dụng các khối hoàn tất thay vì người được ủy quyền (vì tôi đang sử dụng phiên nền) – dariaa

+0

Tôi nhận được bạn. Vì vậy, làm thế nào về việc sử dụng một BOOL toàn cầu để biết nếu bạn đã xử lý các phản ứng? –

+0

Vâng, tất nhiên có thể có một cách giải quyết, nhưng tôi đã đi cho một số hiểu biết sâu sắc hơn. Đó có phải là hành vi được mong đợi hay là một lỗi cần được báo cáo, v.v.BTW một lá cờ 'BOOL' không phải là lựa chọn tốt nhất ở đây, vì trong 'URLSession: downloadTask: didFinishDownloadingToURL:' (được gọi là đầu tiên) người ta thường sao chép tệp vào thư mục tài liệu để xử lý tiếp. Nó sẽ được tốt đẹp để biết tại thời điểm đó nếu tải xuống hoàn tất thành công hoặc với lỗi. – dariaa

-1

NSURLSessionDownloadTask là một phân lớp của NSURLSessionTask, có thuộc tính error. Bạn có thể kiểm tra điều đó trong phương thức đại diện URLSession:downloadTask:didFinishDownloadingToURL: trước khi bạn cố sao chép tệp của mình không?

+0

Thuộc tính lỗi vẫn giữ nguyên trừ khi đó là lỗi phía máy khách. –

1

Theo tài liệu của Apple theo NSURLSessionDownloadDelegate Đó là hành vi tiêu chuẩn.

/* Sent when a download task that has completed a download. The delegate should 
* copy or move the file at the given location to a new location as it will be 
* removed when the delegate message returns. URLSession:task:didCompleteWithError: 
* will still be called. */ 
0

Tôi tìm thấy một giải pháp cho vấn đề này:

Để có được mã trạng thái trong tiêu đề phản ứng, trước tiên bạn phải bắt đầu một NSURLSessionDataTask.

Điều này sẽ gọi phương thức ủy nhiệm sau URLSession: dataTask: didReceiveResponse: completionHandler:.

Trong phương pháp này, trước tiên bạn có thể kiểm tra mã trạng thái của các thông số NSURLResponse (bằng cách đúc nó vào một NSHTTPURLResponse) và cuối cùng là gọi xử lý hoàn thành với một trong hai NSURLSessionResponseBecomeDownload để chuyển đổi dataTask của bạn đến một downloadTask (mà sẽ hành xử như bạn mong đợi từ NSURLSessionDownloadTask) hoặc NSURLSessionResponseCancel để tránh tải xuống một số dữ liệu bạn không cần (ví dụ: nếu mã trạng thái của phản hồi là 404).

Ngoài ra, nếu bạn cần làm điều gì đó với NSURLSessionDownloadTask được chuyển đổi (như lưu trữ nó trong một mảng hoặc từ điển hoặc thay thế nhiệm vụ dữ liệu với đối tượng mới), nó có thể được thực hiện trong URLSession: dataTask: didBecomeDownloadTask:

Hy vọng điều này sẽ giúp ai đó!

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