import Flutter import UIKit import ScreenTime @available(iOS 14.0, *) public class TimeTrackingPlugin: NSObject, FlutterPlugin { public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel( name: "autotime_tracker/time_tracking", binaryMessenger: registrar.messenger() ) let instance = TimeTrackingPlugin() registrar.addMethodCallDelegate(instance, channel: channel) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { case "hasPermission": hasPermission(result: result) case "requestPermission": requestPermission(result: result) case "getAppUsage": getAppUsage(call: call, result: result) case "startBackgroundTracking": startBackgroundTracking(result: result) case "stopBackgroundTracking": stopBackgroundTracking(result: result) case "isBackgroundTrackingActive": isBackgroundTrackingActive(result: result) default: result(FlutterMethodNotImplemented) } } // MARK: - Permission Methods private func hasPermission(result: @escaping FlutterResult) { if #available(iOS 14.0, *) { let authorizationStatus = STScreenTime.getAuthorizationStatus() result(authorizationStatus == .authorized) } else { result(false) } } private func requestPermission(result: @escaping FlutterResult) { if #available(iOS 14.0, *) { STScreenTime.requestAuthorization { success, error in if let error = error { result(FlutterError( code: "AUTHORIZATION_FAILED", message: error.localizedDescription, details: nil )) } else { result(success) } } } else { result(FlutterError( code: "UNSUPPORTED_VERSION", message: "Screen Time API requires iOS 14.0 or later", details: nil )) } } // MARK: - App Usage Methods @available(iOS 14.0, *) private func getAppUsage(call: FlutterMethodCall, result: @escaping FlutterResult) { guard let args = call.arguments as? [String: Any], let startTimeMs = args["startTime"] as? Int64, let endTimeMs = args["endTime"] as? Int64 else { result(FlutterError( code: "INVALID_ARGUMENTS", message: "Invalid arguments", details: nil )) return } let startTime = Date(timeIntervalSince1970: Double(startTimeMs) / 1000.0) let endTime = Date(timeIntervalSince1970: Double(endTimeMs) / 1000.0) // 检查权限 guard STScreenTime.getAuthorizationStatus() == .authorized else { result(FlutterError( code: "PERMISSION_DENIED", message: "Screen Time permission not granted", details: nil )) return } // 获取应用使用数据 STScreenTime.getAppUsage(from: startTime, to: endTime) { usage, error in if let error = error { result(FlutterError( code: "GET_USAGE_FAILED", message: error.localizedDescription, details: nil )) return } guard let usage = usage else { result([]) return } // 转换为 Flutter 可用的格式 var appUsageList: [[String: Any]] = [] // 遍历应用使用数据 // 注意:实际的 Screen Time API 使用方式可能不同 // 这里提供基本框架,需要根据实际 API 调整 // 示例数据结构 for (bundleId, timeInterval) in usage { let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ?? bundleId appUsageList.append([ "packageName": bundleId, "appName": appName, "startTime": startTime.timeIntervalSince1970 * 1000, "endTime": endTime.timeIntervalSince1970 * 1000, "duration": Int(timeInterval), "deviceUnlockCount": 0 ]) } result(appUsageList) } } // MARK: - Background Tracking Methods private func startBackgroundTracking(result: @escaping FlutterResult) { // iOS 后台追踪实现 // 注意:iOS 对后台运行有严格限制 // 可以使用 Background Tasks 或 Notification Service Extension result(true) } private func stopBackgroundTracking(result: @escaping FlutterResult) { result(true) } private func isBackgroundTrackingActive(result: @escaping FlutterResult) { result(false) } }