2014-04-25 13 views
9

Tôi cần tải xuống với các khả năng nền nhất định (không phải tất cả), sau khi kiểm tra tiêu đề (cho chiều dài và loại), nhưng nó phải ở trong cùng một thao tác, chứ không phải tạo một nhiệm vụ/yêu cầu mới (vì đôi khi tôi gặp lỗi từ máy chủ do nhiều kết nối trong một khoảng thời gian ngắn). Vì vậy, tôi bắt đầu công tác:Chuyển đổi NSURLSessionDataTask thành tác vụ Tải xuống với hỗ trợ nền

NSURLSessionConfiguration *configuratione = [NSURLSessionConfiguration defaultSessionConfiguration]; 
NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue:nil]; 
NSURLSessionDataTask *datatask = [sessione dataTaskWithRequest:request]; 
[datatask resume]; 

Sau đó, tôi biết rằng có thể chuyển đổi một tác dữ liệu vào một nhiệm vụ Tải khi nhận được phản ứng đầu tiên, với đại biểu này:

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask 
didReceiveResponse:(NSURLResponse *)response 
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler 
{ 
    if(XXXXXXXXXX){ 
     NSLog(@"transform into a download"); 
     completionHandler(NSURLSessionResponseBecomeDownload); 
    }else{ 
     NSLog(@"Keep loading normally"); 
     completionHandler(NSURLSessionResponseAllow); 
    } 
} 

Tuy nhiên, kể từ Công việc dữ liệu không thể sử dụng BackgroundSessionConfiguration, tôi cho rằng tải xuống mới được tạo sẽ sử dụng cùng một Cấu hình phiên mặc định. Làm cách nào để giữ cho bản tải xuống đó chạy trong nền? Có cách nào thay đổi phiên của nó thành phiên bản nền không? Hoặc đó sẽ là cách tiếp cận?

Trả lời

8

Câu hỏi này khó trả lời, đường nối cho tôi, rằng tất cả 3 yếu tố tải URL chính (tạo kiểu sessionType, FG/BG) bị hạn chế bởi thiết kế của bạn.

Kể từ phiên giữ một sâu copy vào cấu hình (mà quyết định default/nền/Ephemeral phiên chất-type), sau khi bắt đầu phiên của bạn (trong trường hợp của chúng tôi: bạn mặc định-type-Session) bạn KHÔNG thể sửa đổi cấu hình-Đối tượng cho phiên hiện tại này nữa. Vì vậy, nếu thiết kế của bạn KHÔNG cho phép thực hiện Tác vụ mới được liên kết với một (hy vọng) BG-type-Session mới, không có cách nào để chỉ chuyển đổi một cách chính xác "dataTask" thành "downloadTask".

Hãy ghi nhớ, NSURLSessionDataTaskNSURLSessionDownloadTask đều lớp con của NSURLSessionTask, NSURLSessionDataTask và NSURLSessionDownloadTask xử lý đến dữ liệu đáp ứng (piece-khôn ngoan VS file-khôn ngoan tương ứng) rất khác nhau được thực hiện bởi các khuôn khổ .

Một ảo tưởng hấp dẫn có thể phương pháp hấp dẫn này URLSession:dataTask:didBecomeDownloadTask:, nhưng bạn phải tạo một nhiệm vụ mới (DownloadTask trong hành động) gắn liền với hiện tại (đóng dấu sâu sắc bởi cấu hình trước đó mặc định kiểu của bạn) phiên, và rời khỏi nhiệm vụ ban đầu (dataTask) là trẻ em mồ côi. Sự hiểu biết của tôi là thiết kế của bạn KHÔNG thể thực hiện tùy chọn này do tạo thêm nhiệm vụ, cũng như bạn sẽ phải ở lại với cấu hình phiên loại mặc định.

URLSession: dataTask: didBecomeDownloadTask: thực sự nên được đặt tên như URLSession: dataTask: wasReplacedByDownloadTask:

giải pháp Chỉ đơn giản tôi có bây giờ là, trong dữ liệu giao nhiệm vụ Đại biểu (lớp thực hiện giao thức NSURLSessionDataDelegate) khi nhận URLSession: dataTask: didReceiveData: gọi ban đầu, bắt đầu lưu trữ những dữ liệu mảnh theo cách nào đó (lưu trữ vào tệp tạm thời, có thể, mô phỏng hành động mặc định của NSURLSessionDownloadTask) và đảm bảo thực hiện ủy quyền này không đồng bộ trên NSOperationQueue(Tôi đoán "khả năng nền" của bạn " ans secondary thread, có thể được cung cấp bởi NSOperationQueue gạch dưới cơ chế luồng), cho đến khi tải xuống hoàn tất, sau đó kiểm tra dung lượng lưu trữ của bạn cho kết quả tích lũy (nếu xử lý bất kỳ lỗi nào và/hoặc chuyển tệp ở nơi khác) trong phương pháp này chung NSURLSessionTaskDelegate : nhiệm vụ: didCompleteWithError:"

Làm như vậy, bạn chuyển đổi theo yêu cầu (đại diện bởi một NSURLSessionDataTask) vào một download (không phải là một NSURLSessionDownloadTask). Để đáp ứng chuyển đổi này xảy ra trên hàng đợi nền, cung cấp giá trị không phải là giá trị nil (phiên/nhiệm vụ) tham số cuối cùng của phương thức đại biểu này: - nếu không, hàng đợi hoạt động nối tiếp sẽ không đáp ứng "khả năng nền" của bạn cần

NSOperationQueue* aQueue = [[NSOperationQueue alloc] init]; 

NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue: aQueue]; 

Các ý tưởng khác sẽ được thực hiện thủ công nhiều đối tượng NSOperation, ghi đè phương thức bắt đầu của chúng để đảm bảo thực thi không đồng bộ cho tác vụ tải xuống của bạn, điều này có thể hơi phức tạp một chút.

Bất kỳ người nào khác, những người có giải pháp tốt hơn, vui lòng mang theo nhiều tia lửa hơn ... hoặc sửa tôi vì bất kỳ sự hiểu lầm nào tôi có thể đã thực hiện.

+1

nhưng giải pháp của bạn hoàn toàn khác với cấu hình nền, nơi tải xuống nằm trong quá trình được quản lý OS và nó sẽ tiếp tục ngay cả khi ứng dụng ở chế độ nền và bị hệ điều hành giết. –

+0

Chúng ta có thể nói rằng nhiệm vụ tải xuống mạnh mẽ hơn nhiều so với tác vụ dữ liệu? Bởi vì nó cho phép ** (1) ** Tiếp tục tải xuống khi khởi chạy liên tục Ứng dụng. ** (2) ** Tiếp tục tải xuống ngay cả khi Ứng dụng không ở trạng thái hoạt động, hấp dẫn đối với người dùng. – NSPratik

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