objective-c在applicationWillResignActive

时间:2017-07-19 13:00:59

标签: ios objective-c bluetooth application-state

我试图在applicationWillResignActive期间运行一些代码,当用户打开任务切换器时它已经正常工作,直到我开始在我的应用程序中使用蓝牙。

当蓝牙尝试连接到设备时,它会显示一个警告窗口,询问用户是否要配对设备。此警报足以触发applicationWillResignActive方法,然后在应用程序远离(任务切换器)时运行我的代码。这导致了一个大问题,因为我打算在切换时运行的代码运行,关闭实际应用程序中一些非常需要的功能。所以一旦按下"配对"或者"取消"在那个警报上,我的所有应用都停止运作,因为应用已失去焦点。

我试图在此期间检测应用程序的状态... NSUInteger state = [[UIApplication sharedApplication] applicationState];当然认为当警报弹出时会被视为活动状态,而在任务切换器中则是非活动状态。但是,对于这两种用例而言,情况并非如此。

更新#1

问题......

如何区分 app 之间的应用程序导致系统级非活动焦点状态(如运行代码连接到蓝牙),而用户导致系统级别处于非活动状态重点像双击主页按钮?所有这些都是为了区分导致applicationWillResignActive方法触发的原因。

更新#2

此功能的目的是在蓝牙连接到设备时在NSUserDefaults中设置标志。正在观察这个标志"并用于触发将视图控制器更改为与此新BT连接相关的页面。当用户双击主页按钮并移动到任务切换器时,我关闭BT并切换到iBeacon,以便我可以通知事件。所有条形码1的用例都适用于当前实现。

如果用户尚未连接到BT设备并且它第一次连接并且配对警报出现,则会触发applicationWillResignActive方法,就像双击主页按钮一样。在此方法中,代码然后检查该NSUserDefaults标志以查看它是否已打开(此时这是因为BT已经到达CBCentralManager' s didConnectPeripheral方法并将其打开)如果它打开,它会关闭BT并切换到扫描iBeacon。因为应用程序仍然打开,这显然会导致问题。该应用程序正在运行,因此用户看到BT连接,新视图滑入,配对警报出现,然后新视图向右滑动,iBeacon开始发送用户在任务中的通知切换器。

我已经在applicationWillEnterBackground方法中发生了这个确切的功能,因此不是答案。我需要有一种说法"该应用程序现在正在运行,我们已经收到警报而不是双击回家,所以请不要关闭BT并打开iBeacon&#34 ;

1 个答案:

答案 0 :(得分:1)

两种可能的解决方案:

<强> 1。答案可能在于以下陈述:

  

当蓝牙尝试连接到设备时,它会显示一个警告窗口,询问用户是否要配对设备。

您的应用必须执行某些内容才能显示此警报。当发生这种情况时,您可以将Date字段设置为AppDelegate中的当前时间,然后当您拨打applicationWillResignActive时,可以将该时间戳与当前时间进行比较,如果它是&lt; 1秒左右,你有一个非常好的线索,蓝牙对话框上升了。

当然,这不是万无一失的。正如@danh在评论中指出的那样,iOS的设计使得这非常困难。您无法确定蓝牙对话框是否已启动,或者用户或操作系统是否恰好同时将其他内容带到了前台。更重要的是,即使蓝牙对话框出现,用户也可能决定在那个时刻检查他或她的电子邮件或开始浏览Facebook。在这种情况下,蓝牙对话框确实将您的应用程序发送到后台, AND 用户导航离开应用程序。不幸的是,iOS并没有真正为您提供区分这两者的方法。

<强> 2。您可以使用后台任务来处理清理逻辑。

您可以在致电applicationWillResignActive后请求最多180秒的后台运行时间,这样您就可以推迟清理任务,直到您的应用程序退出后台已经过了175秒。如果用户在3分钟内没有回来,那么无论如何都可能有时间进行清理。我的博文here显示了设置后台任务的基础知识。它专门用于扩展信标测距时间,但您可以在后台代码块中放置您想要的任何逻辑,如下所示:

- (void)extendBackgroundRunningTime {
  if (_backgroundTask != UIBackgroundTaskInvalid) {
    // if we are in here, that means the background task is already running.
    // don't restart it.
    return;
  }
  NSLog(@"Attempting to extend background running time");

  __block Boolean self_terminate = YES;

  _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"DummyTask" expirationHandler:^{
    NSLog(@"Background task expired by iOS");
    if (self_terminate) {
        [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
        _backgroundTask = UIBackgroundTaskInvalid;
    }
  }];



 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"Background task started.  Waiting 175 seconds before cleanup.");
    [NSThread sleepForTimeInterval:175];

    //TODO: perform cleanup code if app is not in the foreground by now

  });
}