当应用程序处于非活动状态时,iOS 后台下载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8861390/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:18:02  来源:igfitidea点击:

iOS Background downloads when the app is not active

objective-ciosios5backgrounddownload

提问by Srikar Appalaraju

When my app is initially downloaded, the user needs to download a large file something like 200MB (upper limit). I definitely can't expect the user to keep the app open till this file is downloaded. So he/she might close the app & the app will go into background.

最初下载我的应用程序时,用户需要下载一个大文件,例如 200MB(上限)。我绝对不能指望用户在下载此文件之前保持应用程序打开。所以他/她可能会关闭应用程序,应用程序将进入后台。

How can I continue to download the file in this scenario? Is this even possible in iOS?

在这种情况下如何继续下载文件?这在iOS中甚至可能吗?

采纳答案by Chris Gummer

It is possible to start a background task when you begin the download:

开始下载时可以启动后台任务:

Apps that are transitioning to the background can request an extra amount of time to finish any important last-minute tasks.

正在过渡到后台的应用程序可能需要额外的时间来完成任何重要的最后一分钟任务。

Executing a Finite-Length Task in the Background

在后台执行有限长度任务

However, such a task is limited to an undefined amount of execution time by the system. However, a 200Mb file download may be too large a task in this case.

然而,这样的任务被系统限制为未定义的执行时间量。但是,在这种情况下,下载 200Mb 的文件可能是一项太大的任务。

回答by Saurabh

Add below in your - (void)applicationDidEnterBackground:(UIApplication *)application

在你的下面添加 - (void)applicationDidEnterBackground:(UIApplication *)application

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

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

and you are good to go... I have this in one of my published download manager app

你很高兴去......我在我发布的下载管理器应用程序之一中有这个

This will work just fine. You can also check how much time you have, since apple only enable 10 minutes background tasks. Use:

这将工作得很好。您还可以查看您有多少时间,因为苹果只启用 10 分钟的后台任务。用:

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

回答by Marimuthu

You could use NSURLSession introduced in iOS 7.0 and later to continue the uploading/download of an file even when the app is suspended.

您可以使用 iOS 7.0 及更高版本中引入的 NSURLSession 来继续上传/下载文件,即使应用程序已暂停。

Apple documentation

苹果文档

The NSURLSession class and related classes provide an API for downloading content. This API provides a rich set of delegate methods for supporting authentication and gives your app the ability to perform background downloads when your app is not running or, in iOS, while your app is suspended.

NSURLSession 类和相关类提供了用于下载内容的 API。此 API 提供了一组丰富的委托方法来支持身份验证,并使您的应用程序能够在您的应用程序未运行时或在 iOS 中,当您的应用程序暂停时执行后台下载。

And

Background sessions let you perform uploads and downloads of content in the background while your app is not running. You can create a background session configuration by calling the backgroundSessionConfiguration: method on the NSURLSessionConfiguration class.

后台会话可让您在应用未运行时在后台执行内容的上传和下载。您可以通过调用NSURLSessionConfiguration 类的backgroundSessionConfiguration: 方法来创建后台会话配置 。

A cool tutorial to use NSURLSession at this link.

在此链接上使用 NSURLSession 的一个很酷的教程。

回答by Himanshu Mahajan

In one of my apps, I was loading huge amount of data. I definitely can't expect the user to keep the app in foreground until the data is downloaded. I just use following code to get the data downloading while app is in background. Its working properly :-)
Please go through following steps:

在我的一个应用程序中,我加载了大量数据。我绝对不能指望用户在下载数据之前将应用程序保持在前台。我只是使用以下代码在应用程序处于后台时获取数据下载。它工作正常:-)
请执行以下步骤:

1) use following line in header file of ViewController

1) 在 ViewController 的头文件中使用以下行

   @property (nonatomic) UIBackgroundTaskIdentifier backgroundTask;

synthesis it in .m file.

在 .m 文件中合成它。

2) in ViewDidLoad assign UIBackgroundTaskIdentifier like:

2)在 ViewDidLoad 中分配 UIBackgroundTaskIdentifier 如:

   self.backgroundTask = UIBackgroundTaskInvalid;

3) Use following line of code, here I am just keeping on getDataFromServer method inside beginBackgroundTaskWithExpirationHandler: block.

3) 使用以下代码行,这里我只保留 beginBackgroundTaskWithExpirationHandler: 块中的 getDataFromServer 方法。

        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) If you want to check time remaining to download data in background, include following line in applicationDidEnterBackground:(UIApplication *)application delegate method of AppDelegate:

4) 如果您想查看后台下载数据的剩余时间,请在 AppDelegate 的 applicationDidEnterBackground:(UIApplication *)application 委托方法中包含以下行:

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

回答by Sumit Sharma

AFNetworkingallows you to perform heavy operation in background.

AFNetworkingLibrary is a excellent combination of NSURLConnection and NSOperationQueue.This library is used for Asynchronous downloading in the background not affecting the other application.

AFNetworkingallows you to handle the downloading with ExpirationHandle i.e. if anyhow during the downloading the connection is lost , it will again connect to it.

AFNetworking允许您在后台执行繁重的操作。

AFNetworking库是 NSURLConnection 和 NSOperationQueue 的绝佳组合。该库用于后台异步下载,不影响其他应用程序。

AFNetworking允许您使用 ExpirationHandle 处理下载,即如果在下载过程中连接丢失,它将再次连接到它。

Library Sourcefor AFNetworking

库源AFNetworking

Reference SourceAFNetworking works in Background

参考源AFNetworking 在后台工作

Apple Reference LinkApple

Apple 参考链接Apple

Background Execution and Multitasking Apple

后台执行和多任务处理 Apple

回答by srjohnhuang

#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");
        }
    }
}

You can know more from this slide.
I just do some simple useful modification from the snippet of this slide. Hope this helps.

您可以从这张幻灯片中了解更多信息。
我只是从这张幻灯片的片段中做了一些简单有用的修改。希望这可以帮助。

回答by Add080bbA

Build a newsStand iOS application; not a standart iOS application.

构建一个 newsStand iOS 应用程序;不是标准的 iOS 应用程序。

Standart iOS aplications:

标准iOS应用程序:

  • can not download data when closed.
  • can download data in limited time when pushed to background.
  • Not enough time to download 200mb.
  • 关闭时无法下载数据。
  • 推送到后台可以限时下载数据。
  • 没有足够的时间下载 200MB。

NewsStand applications have an extra time privilege to download when closed or inBackground. Once in every 24 hours, they have a privilege to answer a remoteContentReady delegate call.

报亭应用程序在关闭或在后台时有额外的时间下载权限。每 24 小时一次,他们有权应答 remoteContentReady 委托呼叫。

Building a newsStand application is no different than building a standart iOS application. You will just mark it as newStand application.

构建 newsStand 应用程序与构建标准的 iOS 应用程序没有什么不同。您只需将其标记为 newStand 应用程序即可。

Then you will have privilege to run code which is inside remoteContentReady delegation.

然后您将有权运行 remoteContentReady 委托中的代码。

To receive remoteContentReady signal, you have to send a signal from your serverside (c#, php, bla bla).

要接收 remoteContentReady 信号,您必须从服务器端(c#、php、bla bla)发送一个信号。

Not to every single iOS app. Something like a remoteNotification signal. You may need ssl certification for your website in order to accomplish this.

不是每个 iOS 应用程序。类似于 remoteNotification 信号的东西。您可能需要为您的网站进行 ssl 认证才能完成此操作。

Best Regards

此致