2012-01-14 38 views
20

Khi ứng dụng của tôi được tải xuống ban đầu, người dùng cần tải xuống tệp lớn có kích thước 200MB (giới hạn trên). Tôi chắc chắn không thể mong đợi người dùng giữ ứng dụng mở cho đến khi tệp này được tải xuống. Vì vậy, anh/cô ấy có thể đóng ứng dụng & ứng dụng sẽ chuyển sang chế độ nền.Tải xuống nền iOS khi ứng dụng không hoạt động

Tôi làm cách nào để tiếp tục tải xuống tệp trong trường hợp này? Điều này thậm chí có thể có trong iOS không?

+0

cuối cùng bạn có thể tải xuống tệp đó dưới nền? – Mahesh

+0

Xem câu trả lời của MMR bên dưới. Nền tảng thực sự 'NSURLSession' là cách tốt nhất để đạt được điều này ngày nay. Tất cả các câu trả lời khác được cập nhật trước kỹ thuật này. Nếu bạn có một tải xuống nhỏ cần ít hơn 3 phút để hoàn thành, tác vụ nền là cách tiếp cận tốt, nhưng đối với tải xuống nền lớn, hãy sử dụng nền 'NSURLSession'. – Rob

Trả lời

7

Có thể bắt đầu một nhiệm vụ nền khi bạn bắt đầu quá trình tải về:

Apps đang chuyển đổi sang nền có thể yêu cầu thêm lượng thời gian để hoàn thành bất kỳ nhiệm vụ vào phút chót quan trọng.

Executing a Finite-Length Task in the Background

Tuy nhiên, một nhiệm vụ như vậy được giới hạn ở mức không xác định thời gian thực hiện bởi hệ thống. Tuy nhiên, tải xuống tệp 200Mb có thể là một tác vụ quá lớn trong trường hợp này.

+0

Có. Bạn có thể muốn xem xét sử dụng thư viện mạng cho phép bạn tạm dừng và tiếp tục tải xuống từ nơi họ đã dừng lại, vì vậy người dùng không phải bắt đầu lại từ đầu nếu việc tải xuống bị gián đoạn. ASIHttpRequest có thể làm điều này, nhưng nó không được hỗ trợ nữa vì nó không hoạt động với ARC. –

+2

không chính xác nữa. Trên ARC cho ASIHttp, bạn có thể sử dụng một thư viện tĩnh được biên dịch với môi trường không ARC. – samfisher

37

Thêm bên dưới của bạn - (void)applicationDidEnterBackground:(UIApplication *)application

UIApplication *app = [UIApplication sharedApplication]; 
UIBackgroundTaskIdentifier bgTask; 

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
     [app endBackgroundTask:bgTask]; 
}]; 

và bạn tốt để đi ... Tôi có điều này trong một trong những xuất bản tải về ứng dụng quản lý của tôi

này sẽ chỉ làm việc tốt. Bạn cũng có thể kiểm tra xem bạn có bao nhiêu thời gian, vì táo chỉ cho phép các tác vụ nền 10 phút. Sử dụng:

NSTimeInterval ti = [[UIApplication sharedApplication]backgroundTimeRemaining]; 
NSLog(@"backgroundTimeRemaining: %f", ti); // just for debug 
+0

Vì vậy, với điều này tôi có thể tải về? Có giới hạn thời gian nào như @nick nói ở trên không? –

+10

vâng .. apple nói về giới hạn thời gian .. nhưng tôi có thể tải xuống tệp có kích thước 800 mb với mã trên .. và ứng dụng đang ở trong cửa hàng ứng dụng .. – Saurabh

+0

wow !! nhận xét của bạn là thông tin quý giá @Saurabh. Cảm ơn!! – samfisher

3

AFNetworking cho phép bạn thực hiện thao tác nặng ở chế độ nền.

AFNetworking Thư viện là sự kết hợp tuyệt vời giữa NSURLConnection và NSOperationQueue. Thư viện này được sử dụng để tải xuống Không đồng bộ trong nền không ảnh hưởng đến ứng dụng khác.

AFNetworking cho phép bạn xử lý việc tải xuống bằng ExpirationHandle tức là nếu bất kỳ cách nào trong quá trình tải xuống kết nối bị mất, nó sẽ kết nối lại với nó.

Thư viện Nguồn cho AFNetworking

tham khảo Nguồn liên kếtAFNetworking works in Background

của Apple ReferenceApple

Bối cảnh Thực hiện và Multitasking Apple

5

Trong một trong các ứng dụng của tôi, tôi đã tải lượng dữ liệu khổng lồ. Tôi chắc chắn không thể mong đợi người dùng giữ ứng dụng ở nền trước cho đến khi dữ liệu được tải xuống. Tôi chỉ sử dụng mã sau để tải xuống dữ liệu trong khi ứng dụng ở chế độ nền.làm việc của nó đúng :-)
Hãy đi qua các bước sau:

1) sử dụng dòng sau trong tập tin tiêu đề của ViewController

@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask; 

tổng hợp nó trong file .m.

2) trong viewDidLoad gán UIBackgroundTaskIdentifier như:

self.backgroundTask = UIBackgroundTaskInvalid; 

3) Sử dụng dòng mã sau đây, ở đây tôi chỉ giữ trên phương pháp getDataFromServer bên beginBackgroundTaskWithExpirationHandler: block.

 self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 

     [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask]; 
     self.backgroundTask = UIBackgroundTaskInvalid; 
    }]; 

    /* Here your downloading Code, let say getDataFromServer method */ 

    [self getDataFromServer]; // Its dummy method 

    /* Your downloading Code End Here */ 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask]; 
     self.backgroundTask = UIBackgroundTaskInvalid; 
    }); 

4) Nếu bạn muốn kiểm tra thời gian còn lại để tải dữ liệu ở chế độ nền, bao gồm dòng sau trong applicationDidEnterBackground: (UIApplication *) Phương pháp đại biểu áp dụng appdelegate:

 NSLog(@"Background time remaining = %.1f seconds", [UIApplication sharedApplication].backgroundTimeRemaining); 
+0

Câu trả lời rõ ràng bằng pha lê, cảm ơn rất nhiều sự trợ giúp – byJeevan

0
#pragma mark - View Loading handling 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; 
} 

#pragma mark - Background handling when application goes background 
UIBackgroundTaskIdentifier background_task; 
- (void)appDidEnterBackground:(NSNotification *)notification { 
    UIApplication *application = [UIApplication sharedApplication]; 
    if([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) 
    { 
     NSLog(@"Multitasking Supported"); 
     if (background_task == UIBackgroundTaskInvalid) { 
      background_task = [application beginBackgroundTaskWithExpirationHandler:^ { 
       NSLog(@"Background task expiration\n"); 
       //Clean up code. Tell the system that we are done. 
       [application endBackgroundTask: background_task]; 
       background_task = UIBackgroundTaskInvalid; 
      }]; 
      //To make the code block asynchronous 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       //### background task starts 
       NSLog(@"Running in the background\n"); 
       for(int cnt=0; cnt<10; cnt++) //while(TRUE) 
       { 
        NSLog(@"Background time Remaining: %f",[[UIApplication sharedApplication] backgroundTimeRemaining]); 
        [NSThread sleepForTimeInterval:1]; //wait for 1 sec 
       } 
       //#### background task ends 
       //Clean up code. Tell the system that we are done. 
       NSLog(@"here you can do something before it really enters background"); 
       [NSThread sleepForTimeInterval:1]; //wait for 1 sec 
       [application endBackgroundTask: background_task]; 
       background_task = UIBackgroundTaskInvalid; 
      }); 
     } 
     else 
     { 
      NSLog(@"Multitasking Not Supported"); 
     } 
    } 
} 

Bạn có thể biết thêm từ điều này slide.
Tôi chỉ thực hiện một số sửa đổi hữu ích đơn giản từ đoạn trích của trang trình bày này. Hy vọng điều này sẽ hữu ích.

0

Tạo ứng dụng iOS bản tinStand; không phải là một ứng dụng iOS nổi bật.

Standart iOS aplications:

  • không thể tải dữ liệu khi đóng cửa.
  • có thể tải xuống dữ liệu trong thời gian giới hạn khi được đẩy lên nền.
  • Không đủ thời gian để tải xuống 200mb.

Ứng dụng NewsStand có đặc quyền thêm thời gian để tải xuống khi đóng hoặc trongBackground. Một lần trong mỗi 24 giờ, họ có đặc quyền để trả lời cuộc gọi đại biểu remoteContentReady.

Tạo tin tứcỨng dụng ứng dụng không khác gì so với việc tạo ứng dụng iOS standart. Bạn sẽ chỉ đánh dấu nó là ứng dụng newStand.

Sau đó, bạn sẽ có đặc quyền để chạy mã nằm trong ủy nhiệm remoteContentReady.

Để nhận tín hiệu RemoteContentReady, bạn phải gửi tín hiệu từ máy chủ của bạn (C#, php, bla bla).

Không áp dụng cho mọi ứng dụng iOS. Một cái gì đó giống như một tín hiệu từ xa. Bạn có thể cần chứng nhận ssl cho trang web của mình để thực hiện việc này.

Trân trọng

+0

Không biết điều này, cảm ơn bạn đã chia sẻ @ Add080bbA – Prashant

5

Bạn có thể sử dụng NSURLSession giới thiệu trong iOS 7.0 và sau đó để tiếp tục tải lên/tải về của một tập tin ngay cả khi ứng dụng bị đình chỉ.

Apple documentation

Lớp NSURLSession và các lớp học có liên quan cung cấp một API cho nội dung tải về. API này cung cấp một tập hợp các phương thức ủy nhiệm phong phú để hỗ trợ xác thực và cung cấp cho ứng dụng của bạn khả năng thực hiện tải xuống khi ứng dụng của bạn không chạy hoặc trong iOS, trong khi ứng dụng của bạn bị tạm ngưng.

phiên Background phép bạn thực hiện cập nhật và tải nội dung ở chế độ nền trong khi ứng dụng của bạn không chạy. Bạn có thể tạo cấu hình phiên nền bằng cách gọi phương thức backgroundSessionConfiguration: trên lớp NSURLSessionConfiguration.

Hướng dẫn thú vị để sử dụng NSURLSession tại link này.

+0

Đây là câu trả lời đúng. Sử dụng nền 'NSURLSession'!Các câu trả lời khác đã được cập nhật trước kỹ thuật này, nhưng đây là cách tốt nhất để thực hiện các tải xuống dài có thể vượt quá 3 phút được cho phép bởi phương pháp 'UIBackgroundTask'. – Rob

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