在iOS中处理后台任务的正确方法是什么

时间:2013-08-15 07:04:49

标签: ios objective-c conventions

我有一个voip应用程序,它需要在后台运行。据我所知,这些是我需要做的事情:

  1. 将应用标记为voip。
  2. 将“应用程序不在后台运行”标志设置为NO。
  3. 设置一个到期处理程序,一段扩展标准10分钟执行时间的代码。
  4. 更多?
  5. 我在info.plist文件中设置了两个标志,然后我得到了10分钟。我尝试了this post中建议的内容。这是我的代码:

    //in didFinishLaunchingWithOptions:
    expirationHandler = ^{
        NSLog(@"ending background task");
        [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    
        NSLog(@"restarting background task");
        bgTask = UIBackgroundTaskInvalid;
        bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:expirationHandler];
    
        NSLog(@"finished running background task");
    };
    
    //in applicationDidEnterBackground
    NSLog(@"entering background mode");
    bgTask = UIBackgroundTaskInvalid;
    bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:expirationHandler];
    
    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
        // inform others to stop tasks, if you like
        [[NSNotificationCenter defaultCenter] postNotificationName:@"MyApplicationEntersBackground" object:self];
    
        //this while loop is just here for testing
        inBackground = true;
        while (inBackground) {
            NSLog(@"stayin alive!!"); //this keeps going forever
            sleep(10);
        }
    });
    

    情况:

    我使用第三方库来处理与我们的Web服务的通信。该服务是CommuniGate专业版服务器。我通过库接收联系人的在线状态更新(在线/离线)和即时消息。该库是CommuniGate的ximss库,它们制作的协议类似于xmpp,用于基于xml的sip请求,以及IM和状态。当用户登录应用程序时,他会看到他的联系人(CmmuniGate好友列表),他可以选择拨打一个。在发送ximss验证消息并且另一方接受了呼叫之后,它记录呼叫的开始时间并开始临时呼叫。

    问题:

    当应用程序按主页按钮进入后台时,我开始在日志中看到“stayin alive”消息,每隔十分钟我就会看到它重新启动后台任务。
    当应用程序按下电源按钮进入后台时,“保持活动”消息开始显示十分钟,然后重新启动后台任务并开始大约每50-100毫秒重新启动它。
    我现在一直很好,即使它吃电池,因为我有时间处理更新,我们的用户不拥有ipads,我们这样做。我现在的问题是ximss库丢失了它的连接(它是基于会话的)。我可以在库中重新启动会话,但这意味着需要进行相当多的数据传输才能获取联系人列表,而有些用户则使用3g。 我无法编辑库的源代码,也无法看到它,因此我不知道它是否以正确的方式创建了套接字。

    我需要做些什么来正确处理这两种情况?我甚至不明白为什么会有区别。

1 个答案:

答案 0 :(得分:-1)

你无法重新扩展这样的后台任务;您的应用可能会被终止。如果这样做,那是因为您启用了后台voip模式,而不是因为您正在重新启动后台任务。

设置voip plist条目后,iOS会尽可能长时间保持您的应用程序处于活动状态,并在终止时重新启动它。来自Implementing a VoIP App

  

在UIBackgroundModes键中包含voip值可以让系统使用   知道它应该允许应用程序根据需要在后台运行   管理其网络套接字。使用此密钥的应用程序也会重新启动   在系统启动后立即在后台确保   VoIP服务随时可用。

除了设置此密钥外,如果您需要定期运行代码以保持您的voip连接处于活动状态,您可以使用UIApplication上的setKeepAliveTimeout:handler:方法。

另见Tips for Developing a VoIP App

  

实施VoIP应用有几个要求:

     
      
  1. 将UIBackgroundModes键添加到应用的Info.plist文件中。将此键的值设置为包含voip字符串的数组。

  2.   
  3. 配置其中一个应用程序的套接字以供VoIP使用。

  4.   
  5. 在移动到后台之前,调用setKeepAliveTimeout:handler:方法来安装一个处理程序   定期执行。您的应用可以使用此处理程序来维护它   服务连接。

  6.   
  7. 配置音频会话以处理与主动使用之间的转换。

  8.   
  9. 为确保在iPhone上获得更好的用户体验,请使用Core Telephony框架调整与基于单元格相关的行为   电话;请参阅核心电话框架参考。

  10.   
  11. 要确保VoIP应用的良好性能,请使用系统配置框架检测网络更改并允许您的应用   尽可能多地睡觉。

  12.   

您需要的几乎所有文档都在Apple开发人员网站上。