2012-01-14 50 views
20

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

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

+0

终于你能够在后台下载该文件? – Mahesh 2016-06-03 15:15:09

+0

请参阅下面的MMR的答案。真正的背景'NSURLSession'是实现这一点的最佳方式。所有这些其他答案都是在此技术之前进行的。如果你有一个小小的下载需要不到3分钟的时间完成,后台任务是好办法,但对于大背景下载,使用背景'NSURLSession'。 – Rob 2016-07-07 11:51:00

回答

7

这是可能的,当你开始下载启动一个后台任务:即将转移到后台可以要求额外 量的时间来完成任何重要的最新任务

应用。

Executing a Finite-Length Task in the Background

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

+0

是的。您可能需要查看使用网络库的方法,该网络库允许您暂停并从停止的位置继续下载,以便用户在下载中断时不必从头开始重新开始。 ASIHttpRequest可以做到这一点,但它不再支持,因为它不适用于ARC。 – 2012-01-14 11:47:43

+2

那不正确了。在ARC for ASIHttp上,您可以使用在非ARC环境下编译的静态库。 – samfisher 2013-04-12 05:21:25

37

- (void)applicationDidEnterBackground:(UIApplication *)application

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

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

下方添加,你是好去...我有这个在我发表的下载管理器应用程序

这会工作得很好的一个。你也可以检查你有多少时间,因为苹果只启用10分钟的后台任务。用途:

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

那么这个我可以下载?有没有像@nick上面所说的时间限制? – 2012-01-14 14:40:27

+10

是的..苹果谈论的时间限制..但我可以下载一个文件大小为800 MB与上述代码..和应用程序在应用商店.. – Saurabh 2012-01-14 14:59:03

+0

哇!你的评论是宝贵的信息@沙拉布。谢谢!! – samfisher 2012-01-14 16:08:17

3

AFNetworking可以让你在后台执行繁重的操作。

AFNetworking库是NSURLConnection和NSOperationQueue的完美结合。该库用于在不影响其他应用程序的背景下进行异步下载。

AFNetworking允许您使用ExpirationHandle处理下载,即无论如何在下载期间连接丢失,它都会再次连接到它。

库源AFNetworking

参考源AFNetworking works in Background

苹果参考链接Apple

后台执行和多任务处理Apple

5

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

1)使用以下行的ViewController

合成它在.m文件的
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTask; 

头文件。

2)在viewDidLoad中分配UIBackgroundTaskIdentifier像:

self.backgroundTask = UIBackgroundTaskInvalid; 

3)使用下面的代码行,在这里我只是保持在getDataFromServer方法内beginBackgroundTaskWithExpirationHandler:块。

 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)如果您要检查剩余时间在后台下载数据,包括applicationDidEnterBackground以下行:(UIApplication的*)应用程序委托的AppDelegate的方法:

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

晶莹剔透的答案,非常感谢您的帮助 – byJeevan 2015-07-06 09:55:46

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

你可以从这个slide知道更多。
我只是从这张幻灯片的片段做一些简单有用的修改。 希望这有助于。

0

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

斯坦达特的iOS aplications:关闭时

  • 不能下载数据。
  • 可以在推送到后台时在有限的时间内下载数据。
  • 没有足够的时间下载200MB。

NewsStand应用程序在关闭或inBackground时有额外的时间权限下载。 每24小时一次,他们有权回答remoteContentReady委托调用。

构建newsStand应用程序与构建非标准iOS应用程序没有区别。您只需将其标记为newStand应用程序即可。

然后您将有权运行位于remoteContentReady委托内的代码。

要接收remoteContentReady信号,您必须从您的serverside(c#,php,bla bla)发送一个信号。

不适用于每个iOS应用。像一个remoteNotification信号。您可能需要为您的网站获得ssl认证才能完成此操作。

问候

+0

不知道这个,谢谢分享@ Add080bbA – Prashant 2018-02-07 12:00:19

5

你可以使用NSURLSession中的iOS 7.0推出以后继续即使该应用程序被暂停的文件的上传/下载。

Apple documentation

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

而且

背景会话让你在后台执行上传和内容 下载,而你的应用程序没有运行。您可以通过调用 backgroundSessionConfiguration: NSURLSessionConfiguration类的方法来创建后台会话配置。

一个很酷的教程,在这个link使用NSURLSession。

+0

这是正确答案,使用后台'NSURLSession'!其他答案会在此技术发布之前进行,但这是实现长时间下载的最佳方式,可能会超过“UIBackgroundTask”方法允许的3分钟。 – Rob 2016-07-07 11:41:47

相关问题