Ios NSURLConnection在进入后台时的最佳实践

Ios NSURLConnection在进入后台时的最佳实践,ios,nsurlconnection,nsurlconnectiondelegate,Ios,Nsurlconnection,Nsurlconnectiondelegate,我注意到在我的应用程序中,当应用程序在加载时进入后台时会导致错误,例如“超时”或“找不到主机名” 这是由于进程不允许连接在后台长时间运行 但这种错误消息会对用户体验造成负面影响。那么我该怎么取消交易呢?我应该取消所有的连接吗?我试图在这里搜索问答,但找不到答案 有关详细信息,我的应用程序使用NSURLConnectionLegate方法。我有一个存储单例,它管理到我的服务器的所有连接。NSURLConnection也在自定义对象中调用和管理 我试图在-applicationidentinterb

我注意到在我的应用程序中,当应用程序在加载时进入后台时会导致错误,例如“超时”或“找不到主机名”

这是由于进程不允许连接在后台长时间运行

但这种错误消息会对用户体验造成负面影响。那么我该怎么取消交易呢?我应该取消所有的连接吗?我试图在这里搜索问答,但找不到答案

有关详细信息,我的应用程序使用NSURLConnectionLegate方法。我有一个存储单例,它管理到我的服务器的所有连接。NSURLConnection也在自定义对象中调用和管理

我试图在-applicationidentinterbackground中[connection cancel]取消连接:但这会导致UI中断,因为我加载数据以放入UITableViewCell,等等。有人能指出解决此类问题的示例吗

更新代码:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
 __block UIBackgroundTaskIdentifier backgroundTask; backgroundTask = 
[application      beginBackgroundTaskWithExpirationHandler: ^ { 
[application endBackgroundTask:backgroundTask]; 
backgroundTask = UIBackgroundTaskInvalid; }]; } 

  }

我可以把这个代码放到appDelegate中吗?与将beginBackgroundTaskWithExpirationHandler放在我希望在后台运行的任务之前相比,这样做的缺点是什么?任务完成后,将endBackgroundTask放在后台运行?我的代码有一个直接处理NSURLConnection的对象

进入后台后,您可以继续运行
NSURLConnection
一段时间。苹果公司没有公布确切的时间段,但只有10分钟。有关如何使用
beginBackgroundTaskWithExpirationHandler:
请求更多时间完成下载的详细信息,请参阅


在大多数情况下,你不应该主动取消下载。您应该等到系统过期后再处理该错误。如果你的下载很短,没有理由取消它(在大多数情况下,连接最昂贵的事情是首先设置连接)。如果下载时间很长,那么如果不在后台继续,用户会感到恼火。(这假设您下载的东西是用户请求的。)

进入后台后,您可以继续运行
NSURLConnection
一段时间。苹果公司没有公布确切的时间段,但只有10分钟。有关如何使用
beginBackgroundTaskWithExpirationHandler:
请求更多时间完成下载的详细信息,请参阅


在大多数情况下,你不应该主动取消下载。您应该等到系统过期后再处理该错误。如果你的下载很短,没有理由取消它(在大多数情况下,连接最昂贵的事情是首先设置连接)。如果下载时间很长,那么如果不在后台继续,用户会感到恼火。(这假设您是因为用户请求而下载内容。)

首先,最好对应用程序委托进行此调用,以便可以关闭NavigationController中的视图。第二,用
beginBackgroundTaskWithExpirationHandler:
标记后台处理的开始,并用
endBackgroundTask:
结束后台处理,如下所示:

.h:

UIBackgroundTaskIdentifier bgTask;
- (void)sendPhoto:(UIImage *)image
{
  UIApplication *app = [UIApplication sharedApplication];

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


  NSLog(@"Sending picture...");

  // Init async NSURLConnection

  // ....
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

  NSLog(@"Picture sent.");

  UIApplication *app = [UIApplication sharedApplication];

  if (bgTask != UIBackgroundTaskInvalid) {
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid;
  }
}
.m:

UIBackgroundTaskIdentifier bgTask;
- (void)sendPhoto:(UIImage *)image
{
  UIApplication *app = [UIApplication sharedApplication];

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


  NSLog(@"Sending picture...");

  // Init async NSURLConnection

  // ....
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

  NSLog(@"Picture sent.");

  UIApplication *app = [UIApplication sharedApplication];

  if (bgTask != UIBackgroundTaskInvalid) {
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid;
  }
}
还有一件事很重要:


在iOS终止应用程序之前,您有10分钟的时间。您可以使用
[
app backgroundTimeRemaining
]

检查这一次。首先,最好对应用程序委托进行此调用,以便可以关闭NavigationController中的视图。第二,用
beginBackgroundTaskWithExpirationHandler:
标记后台处理的开始,并用
endBackgroundTask:
结束后台处理,如下所示:

.h:

UIBackgroundTaskIdentifier bgTask;
- (void)sendPhoto:(UIImage *)image
{
  UIApplication *app = [UIApplication sharedApplication];

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


  NSLog(@"Sending picture...");

  // Init async NSURLConnection

  // ....
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

  NSLog(@"Picture sent.");

  UIApplication *app = [UIApplication sharedApplication];

  if (bgTask != UIBackgroundTaskInvalid) {
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid;
  }
}
.m:

UIBackgroundTaskIdentifier bgTask;
- (void)sendPhoto:(UIImage *)image
{
  UIApplication *app = [UIApplication sharedApplication];

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


  NSLog(@"Sending picture...");

  // Init async NSURLConnection

  // ....
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {

  NSLog(@"Picture sent.");

  UIApplication *app = [UIApplication sharedApplication];

  if (bgTask != UIBackgroundTaskInvalid) {
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid;
  }
}
还有一件事很重要:


在iOS终止应用程序之前,您有10分钟的时间。你可以用
[
应用程序背景时间剩余时间
]

来检查这次,你是说
[连接取消]
?是的,没错。是[连接取消]没有停止。你是说
[连接取消]
?是的,没错。是[连接取消]没有停止。谢谢你的回答。但我不太清楚。你的意思是我应该把这类代码放在controller或appDelegate中吗?或者我可以把这类代码放在appDelegate-(void)applicationidenterbackground:(UIApplication*)application{uuu block uibackgroundtask identifier backgroundTask;backgroundTask=[application beginBackgroundTaskWithExpirationHandler:^{[application endBackgroundTask:backgroundTask];backgroundTask=UIBackgroundTaskInvalid;}];}是的,你可以把这段代码放在你的应用程序代理中,这样就好了!那么你的代码和我在评论中发布的代码有什么区别呢?谢谢你的回答。但我不太清楚。你是说我应该把这类代码放在controller或appDelegate中?还是我可以把这段代码放在appDelegate中-(void)ApplicationIdentinterBackground:(UIApplication*)应用程序{uuuu block UIBackgroundTaskIdentifier backgroundTask;backgroundTask=[application beginBackgroundTaskWithExpirationHandler:^{[application endBackgroundTask:backgroundTask];backgroundTask=UIBackgroundTaskInvalid;}]是的,你可以将此代码放在你的应用程序代理中,这样做很好!那么,你的代码与我在评论中发布的代码有什么区别?谢谢你的建议。我的应用程序将有另一个对象处理下载内容。因此,在ApplicationIdentinterBackground代理中。我可以打电话给你吗_uu块UIBackgroundTaskIdentifier backgroundTask;backgroundTask=[application beginBackgroundTaskWithExpirationHandler:^{[application endBackgroundTask:backgroundT]