first commit
This commit is contained in:
154
ios/Runner/TimeTrackingPlugin.swift
Normal file
154
ios/Runner/TimeTrackingPlugin.swift
Normal file
@@ -0,0 +1,154 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user