ios swift app在后台或是被杀死了怎样使用蓝牙

本文详细探讨了iOS设备在后台运行时蓝牙连接与iBeacon的相关行为。作者通过实践发现,app在后台未被系统杀死时可以自动重连并发送数据;若被系统杀死,某些特定情况下(如iBeacon状态变化)app能够被唤醒。此外,app被唤醒后只能活跃10秒左右。同时,文章提到了苹果对于后台定位权限的限制,并分享了关于蓝牙何时能被系统唤醒的测试结果。此外,还提供了相关参考博客链接,供进一步研究。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

持续更新中。。。
尝试用蓝牙hid协议

文章目录

1.个人实践

  • 下图箭头的地方打印始终是nil
    请添加图片描述
  • 在xcode中点击终止(stop)后再点击运行,开始扫描的时候,下面的代理方法会被调用,并且搜不到原来的设备。如果用户手动杀死app,再扫描时,下面的代理方法不会被调用,可以搜到原来的蓝牙设备
    请添加图片描述
  • 有时会报出下面的错误

API MISUSE: Cancelling connection for unused peripheral <CBPeripheral: 0x282ed8280, identifier = E5FACCFF-D897xx-4353-BF95-998905C0FF07, name = (null), state = connecting>, Did you forget to keep a reference to it?

[CoreBluetooth] API MISUSE: Cancelling connection for unused peripheral

1.1 app在后台处于没有被系统杀死时,可以自动重连和发数据

1.2 但在后台被系统杀死(没有被收到杀死),当连接状态发生变化的时候,系统会唤醒app,扫描后会调用

1.3 因为后台获取位置时,即使app被手动杀死,系统也会唤醒app获取位置。所有应该可以用iBeacon实现在app被手动杀死的情况下也可以发蓝牙数据。下面是本人亲测有效的app被杀死的情况下上报位置的博客

iOS swift 在app被杀死的情况下获取(上报)位置 后台 定位 本人实测有效

1.4 app连接外设后被挂起,这时其他设备搜不到外设,外设还是和app连接的,这时再手动杀死app,这时其他设备还是搜不到外设;这时关闭外设使得连接断开,app会被系统唤醒

  • 先挂起(在xcode上按stop)后手动杀死,关闭外设,app会被唤醒(百发百中)。然后再手动打开app的时候launchOptions?[UIApplication.LaunchOptionsKey.bluetoothCentrals]有值,会走willRestoreState方法。然后再手动杀死,其他设备还是搜不到外设。这时app还是处于唤醒状态。再手动打开,再app搜不到设备,再手动杀死。其他设备才可以搜到外设
  • 直接手动杀死外设,关闭外设,app不会被唤醒
  • app被挂起后,发数据已经测试成功
  • app被挂起后手动杀死,只要外设的开关状态变化,app就会被系统唤醒(百发百中)
  • app在唤醒状态下被收到打开didFinishLaunchingWithOptions方法不会被调用
  • 连续几次手动打开关闭app,才会再走didFinishLaunchingWithOptions方法,launchOptions为nil,willRestoreState方法不被调用,其他设备可以搜到外设
  • 调用centralManager的扫描方法,willRestoreState代理方法才会被调用

1.5 app在后台或是挂起后被系统唤醒时,开定时器0.1秒调用readRSSI方法,didReadRSSI代理方法只会被调用10次。如果2秒调用一次,只会调用1~2次,也就是说只会活跃很短的一段时间,貌似是10秒

  • 定时器方法如果不进行复杂操作,一般是调用10次

2.苹果官网文档 - 蓝牙后台运行

苹果官网文档 - 蓝牙后台运行

2.我的测试结果总结

始终获取位置的弹框

弹出框不再有“始终允许”这个选项。让它们能一直获取用户位置的唯一方法是手动进入“设置>隐私>定位服务”,点击对应的程序,然后选择“始终”选项(有些App还没有这选项)。

苹果对iOS 13更严格的位置权限发声明:为保护隐私

  • 下面的弹框不知道什么时候弹出,好像是app被关闭后

请添加图片描述

2.1 因ibeacon被系统唤醒后,搜索蓝牙

请添加图片描述

2.2 用ibeacon,APP被手动杀死,也是可以进行无钥匙解锁的,但是需要用到网络(蓝牙设备那边可以和服务器通讯)

2.3 通过ibeacon广播蓝牙,广播关闭后,要大概一分钟,蓝牙中心才会显示断开

请添加图片描述

2.3 蓝牙什么时候可以被系统唤醒

可以被唤醒

  • 在后台被系统挂起
  • 在后台被系统挂起后,然后被手动杀死
  • 在后台被系统挂起后,然后被手动杀死,然后手机关机再开机

不能被唤醒

  • 在前台或是在后台被手动杀死

2.4 ibeacon被系统唤醒后会活跃10秒钟

请添加图片描述

3.比较有用的参考博客

iOS App 蓝牙在程序关闭的情况下能否自动连接?如果可以应该怎么处理?

使用iBeacon在程序杀死的情况下唤醒BLE功能 - GitHub

iBeacon
详解iOS的iBeacon 后台运行
ios - iBeacon-可以使用startRangingBeacons进行检测,但不能用于didEnterRegion
Hunting the beacon: CLBeaconRegion

background fetch
stack overflow - ios background fetch
IOS后台运行 之 Background Fetch

4. iBeacon苹果官网文档和我另一篇博客

4.1 app从杀死状态,被系统唤醒后会活跃10秒,本人亲测

  • 定时器设为1秒会上报10次,2秒会上报5次
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
 
        print("index \(MyFileManager.shared.userDefaultIndex)")
   
//        MyFileManager.shared.userDefaultIndex = 0
        
        if let launch = launchOptions {
            let num = launch[UIApplication.LaunchOptionsKey.location] as! NSNumber
            MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: String(num.intValue))
            Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (timer) in
                MyFileManager.shared.sendBluetoothState(state: "timer", content:"timer")
                }
        }else{
            MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: "noLaunchOptions")
        }
      
        return true
    }
    

请添加图片描述

请添加图片描述

请添加图片描述

4.1.1 像下面没有声明要后台操作的定时器,一到后台就会立刻停止

请添加图片描述

4.2 ibeacon广播设备开关状态发生变化时,APP就会被唤醒,反复开关变化,app会反复的被唤醒。

  • 但didFinishLaunchingWithOptions方法可能只会被调用一次。
  • 关闭ibeacon的时候触发的时间比较长,打开的时候很快就触发定时器上传数据
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
 
        print("index \(MyFileManager.shared.userDefaultIndex)")
   
//        MyFileManager.shared.userDefaultIndex = 0
        
        if let launch = launchOptions {
            let num = launch[UIApplication.LaunchOptionsKey.location] as! NSNumber
            MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: String(num.intValue))
            Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { (timer) in
                MyFileManager.shared.sendBluetoothState(state: "timer", content:"timer")
                }
        }else{
            MyFileManager.shared.sendBluetoothState(state: "didFinishLaunchingWithOptions", content: "noLaunchOptions")
        }
      
        return true
    }
    

请添加图片描述

请添加图片描述

5.其他参考博客

iOS蓝牙APP常驻后台

iBeacon定位+BLE自动唤醒app技术方案调研

iOS开发中APP在后台运行与扫描蓝牙遇到的坑
iOS 唤醒被Kill的APP保证蓝牙的长连接
Getting Location Updates for iOS 7 and 8 when the App is Killed/ Terminated/ Suspended

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值