SkipBluetooth
这是一个 Skip Lite Swift/Kotlin 库项目,
在 Android 上提供与 CoreBluetooth 对等的 API。
要在项目中引入此框架,请将以下依赖项
添加到 Package.swift 文件中:
let package = Package( name: "my-package", products: [ .library(name: "MyProduct", targets: ["MyTarget"]), ], dependencies: [ .package(url: "https://source.skip.dev/skip-bluetooth.git", "0.0.0"..<"2.0.0"), ], targets: [ .target(name: "MyTarget", dependencies: [ .product(name: "SkipBluetooth", package: "skip-bluetooth") ]) ])SkipBluetooth 旨在提供与 CoreBluetooth 对等的 API,但在少数情况下,你需要在实现中使用 // SKIP DECLARE:。
CoreBluetooth 中有一些委托方法虽然参数名称不同,却拥有相同的参数类型签名。由于 Kotlin 不会根据参数名称区分函数调用,Gradle 会将它们识别为同一个函数。以下就是一个发生冲突的示例:
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)func centralManager(central: CBCentralManager, DidUpdateANCSAuthorizationFor peripheral: CBPeripheral)要在 CBCentralManagerDelegate 实现中实现这些函数,请按照 Swift 的方式编写函数调用,同时在函数上方加入对应的 // SKIP DECLARE: ... 行,用来声明符合 Kotlin 规则的 API 调用。
示例如下:
/* 假设此函数位于遵循 `CBCentralManagerDelegate` 的类中 */
// SKIP DECLARE: override fun centralManagerDidConnect(central: CBCentralManager, didConnect: CBPeripheral)func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { /* 在此处编写你的实现 */}以下列出了目前所有此类可用函数及其对应调用:
CBCentralManagerDelegate
| CoreBluetooth | SkipBluetooth |
|---|---|
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) | // SKIP DECLARE: override fun centralManagerDidConnect(central: CBCentralManager, didConnect: CBPeripheral) |
func centralManager(_ central: CBCentralManager, didUpdateANCSAuthorizationFor peripheral: CBPeripheral) | // SKIP DECLARE: override fun centralManagerDidUpdateANCSAuthorizationFor(central: CBCentralManager, didUpdateANCSAuthorizationFor: CBPeripheral) |
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: (any Error)?) | // SKIP DECLARE: override fun centralManagerDidDisconnectPeripheral(central: CBCentralManager, peripheral: CBPeripheral, error: (any Error)?) |
CBPeripheralManagerDelegate
| CoreBluetooth | SkipBluetooth |
|---|---|
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) | // SKIP DECLARE: override fun peripheralManagerDidSubscribeTo(peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo: CBCharacteristic) |
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) | // SKIP DECLARE: override fun peripheralManagerDidUnsubscribeFrom(peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom: CBCharacteristic) |
CBPeripheralDelegate
| CoreBluetooth | SkipBluetooth |
|---|---|
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: (any Error)?) | // SKIP DECLARE: override fun peripheralDidUpdateValueFor(peripheral: CBPeripheral, didUpdateValueFor: CBCharacteristic, error: Error?) |
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: (any Error)?) | // SKIP DECLARE: override fun peripheralDidWriteValueFor(peripheral: CBPeripheral, didWriteValueFor: CBCharacteristic, error: Error?) |
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: (any Error)?) | // SKIP DECLARE: override fun peripheralDidUpdateNotificationStateFor(peripheral: CBPeripheral, didUpdateNotificationStateFor: CBCharacteristic, error: Error?) |
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: (any Error)?) | // SKIP DECLARE: override fun peripheralDidDiscoverCharacteristicsFor(peripheral: CBPeripheral, didDiscoverCharacteristicsFor: CBService, error: Error?) |
蓝牙在 iOS 和 Kotlin 两端都需要相应权限,因此你必须在 Info.plist 文件中添加以下内容:
并在 AndroidManifest.xml 中添加以下内容:
<manifest> <!-- 通常需要的权限 --> <uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 允许执行需要更高权限的操作(例如在 Android 上开启和关闭蓝牙) --> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- 如果需要中心设备权限
由于蓝牙可用于推断用户的精确位置,你可以使用此属性表明应用不会利用蓝牙获取其位置 (也可以移除此属性,以表明应用确实会将蓝牙用于定位) --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<!-- 如果需要外设权限 --> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- 无论作为哪种角色,只要需要连接就添加此权限 --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 其他属性 --></manifest>使用任何蓝牙 API 之前,都必须向用户请求权限。
一种方式是使用 SkipKit 中的
PermissionManager API:
import SkipKit
func performBluetoothOperation() async { if await PermissionManager.requestPermission("android.permission.BLUETOOTH_SCAN") == true { if await PermissionManager.requestPermission("android.permission.BLUETOOTH_CONNECT") == true { // 执行蓝牙操作…… } }}以下是不使用 SkipKit、手动请求权限的示例。
在这种情况下,请注意必须在将要使用蓝牙的视图或函数体中
请求用户权限。
import SwiftUI
#if SKIPimport SkipBluetoothimport androidx.compose.runtime.Composableimport androidx.compose.runtime.SideEffectimport androidx.activity.compose.rememberLauncherForActivityResultimport androidx.activity.result.contract.ActivityResultContracts#endif
struct ContentView: View { var body: some View {#if SKIP askForBluetoothPermissions()#endif }}
/// 提示用户授予蓝牙权限@Composablepublic func askForBluetoothPermissions() { let requestPermissionLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestMultiplePermissions()) { perms in // 如有需要,可在此处处理权限 }
let permissions: kotlin.Array<String> = kotlin.arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT )
// Skip 无法在 kotlin.Array<string> 与 // skip.lib.Array<String> 之间隐式转换,因此需要进行类型转换 SideEffect { requestPermissionLauncher.launch(permissions) }}#endif视图一出现,这段代码就会请求蓝牙权限。此后再次加载该视图时, 系统不会再次显示提示;如果用户之前拒绝了权限,你需要提示他们前往设置中启用蓝牙。
本项目是一个 Swift Package Manager 模块,它使用 Skip 插件为 iOS 和 Android 构建软件包。
可以使用标准的 swift test 命令测试此模块,
也可以在 Xcode 中运行面向 macOS 的测试目标;
后者既会运行 Swift 测试,也会在 Robolectric Android 模拟环境中
运行转译后的 Kotlin JUnit 测试。
可以使用 skip test 执行一致性测试,
该命令会以表格形式输出两个平台的测试结果。
欢迎通过功能增强和错误修复为此软件包作出贡献。
为此软件包及其他 Skip 软件包贡献代码的一般流程如下:
- 派生(Fork)此仓库,并在 “Actions” 标签页中启用 Actions
- 将你的 Fork 检出到本地
- 与 Skip 应用一同开发时,将软件包添加到共享工作区,以便在应用中看到所做的更改
- 将更改推送到你的 Fork,并确保 “Actions” 标签页中的所有 CI 检查均通过
- 将你的名字添加到 Skip 贡献者协议 ↗中
- 从你的 Fork 发起拉取请求(Pull Request),并说明所做的更改
skiptools/skip-bluetooth ↗ 最近发布的 4 个版本:
- 版本 0.3.0 ↗ — 2025-06-28
- 版本 0.2.0 ↗ — 2025-04-05
- 版本 0.1.1 ↗ — 2025-02-23
- 版本 0.1.0 ↗ — 2024-08-31
完整历史记录:github.com/skiptools/skip-bluetooth/releases ↗ — .atom 订阅源 ↗