You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native Expo原生模块中使用Apple FamilyControls并解决报错

解决Expo原生模块中FamilyControls的4097错误及使用指南

问题重现

在Expo原生模块中导入FamilyControls时出现以下错误:

[FamilyControls] Failed to get service proxy: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.FamilyControlsAgent" UserInfo={NSDebugDescription=connection to service named com.apple.FamilyControlsAgent}

当前模块代码实现:

import ExpoModulesCore
import FamilyControls
public class ExpoScreenTimeApiModule: Module {
  
  public func definition() -> ModuleDefinition {
   let center = AuthorizationCenter.shared
    Name("ExpoScreenTimeApi")
    
      AsyncFunction("requestScreenTimePermission") { () -> String in
      let center = AuthorizationCenter.shared
      do {
        try await center.requestAuthorization(for: .individual)
        return "Permission Granted"
      } catch {
        throw error // This will be caught as a Promise rejection in JavaScript.
      }
    }
  }
}

解决方案及正确使用步骤

1. 必须使用真机测试

FamilyControls框架不支持iOS模拟器,模拟器中不存在com.apple.FamilyControlsAgent服务,直接触发4097错误,请切换到真实iOS设备调试。

2. 配置Info.plist权限

在iOS项目的Info.plist中添加屏幕时间权限描述,否则授权请求会被系统拒绝:

<key>NSFamilyControlsUsageDescription</key>
<string>需要访问屏幕时间数据以管理应用使用时长</string>

替换字符串内容为你的应用实际需求说明。

3. 修正模块代码逻辑

移除definition()函数中提前声明的let center = AuthorizationCenter.shared,并优化授权流程(先检查状态再请求):

import ExpoModulesCore
import FamilyControls

public class ExpoScreenTimeApiModule: Module {
  
  public func definition() -> ModuleDefinition {
    Name("ExpoScreenTimeApi")
    
    AsyncFunction("requestScreenTimePermission") { () -> String in
      let center = AuthorizationCenter.shared
      
      // 先检查当前授权状态
      switch center.authorizationStatus {
      case .authorized:
        return "Permission Already Granted"
      case .denied, .notDetermined:
        do {
          try await center.requestAuthorization(for: .individual)
          return "Permission Granted"
        } catch {
          throw error
        }
      @unknown default:
        throw NSError(domain: "ExpoScreenTimeApi", code: -1, userInfo: [NSLocalizedDescriptionKey: "Unknown authorization status"])
      }
    }
    
    // 新增方法获取当前授权状态
    AsyncFunction("getAuthorizationStatus") { () -> String in
      let status = AuthorizationCenter.shared.authorizationStatus
      switch status {
      case .authorized: return "authorized"
      case .denied: return "denied"
      case .notDetermined: return "notDetermined"
      @unknown default: return "unknown"
      }
    }
  }
}

4. 确保Expo环境配置正确

  • 执行expo prebuild生成原生项目文件,确认模块已在ExpoModules.plist中注册
  • 使用Expo开发客户端(Expo Go不支持自定义原生模块)测试,或直接通过Xcode编译真机运行

内容的提问来源于stack exchange,提问作者Tezzus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 05:23:31