You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

修改SCPreferences持久化存储遇无效参数错误求助

解决SCPreferencesCommitChanges返回Code=1002 "Invalid argument"的问题

我之前也踩过类似的蓝牙plist修改坑,这个“设置值成功但提交失败”的矛盾错误,其实大概率是参数格式不规范或者权限/会话配置有问题,咱们一步步来排查:

1. 先修正AuthorizationFlags的重复问题

你代码里的flags重复写了.extendRights,虽然不一定是直接诱因,但规范的配置能避免潜在的权限异常:

let flags: AuthorizationFlags = [.interactionAllowed, .extendRights, .preAuthorize]

2. 更换SCPreferences会话的标识符

SCPreferencesCreateWithAuthorization的第二个参数是会话的唯一标识,你传的"defaults"太通用,系统可能会因为这个不规范的标识拒绝提交。建议换成你应用的Bundle ID,比如:

let preferences = SCPreferencesCreateWithAuthorization(
    kCFAllocatorDefault,
    "com.yourcompany.yourapp" as CFString, // 替换成你的真实Bundle ID
    "/Library/Preferences/com.apple.Bluetooth.plist" as CFString,
    authRef
)

3. 重点检查PairedDevices的格式匹配

这是最常见的触发原因:你传入的paired对象的类型/结构和原plist里的PairedDevices不匹配。系统允许临时设置值,但提交时会严格验证plist合法性,一旦结构不对就会返回1002错误。

  • 先读取原plist的PairedDevices值,确认它的类型(通常是CFArray,内部是蓝牙设备的UUID字符串或字典)
  • 确保你构造的paired对象和原结构完全一致,比如原先是数组就别传字典,元素类型也要严格对应

推荐先读取原值再修改,这样能保证结构绝对正确:

guard let prefs = preferences else {
    print("Failed to create preferences reference")
    return false
}

// 读取原PairedDevices值
if let originalPaired = SCPreferencesGetValue(prefs, "PairedDevices" as CFString) as? CFArray {
    // 在这里修改originalPaired得到新的数组(比如移除指定设备)
    let newPaired = ... // 你的修改逻辑
    // 写入修改后的值
    if SCPreferencesSetValue(prefs, "PairedDevices" as CFString, newPaired) {
        print("Set Value success")
        let ok = SCPreferencesCommitChanges(prefs)
        if ok {
            print("Commit success")
        } else {
            if let error = SCCopyLastError() {
                print("Commit Changes Error: \(error)")
            }
        }
    } else {
        if let error = SCCopyLastError() {
            print("Set Value Error: \(error)")
        }
    }
} else {
    print("Failed to read original PairedDevices")
}

4. 额外排查点:文件占用和权限

  • 蓝牙守护进程blued可能正在占用这个plist文件,导致无法提交。可以先断开所有蓝牙设备,或者重启blued(需要root权限:sudo launchctl stop com.apple.blued && sudo launchctl start com.apple.blued
  • 确认权限获取是否成功:打印AuthorizationCopyRights返回的osStatus,确保它等于errAuthorizationSuccess(即0):
print("Authorization status: \(osStatus)")

内容的提问来源于stack exchange,提问作者Mike JS Choi

火山引擎 最新活动