在iOS平台中,要实现读取设备上其他App的使用时间,核心依赖于 Screen Time API(也称为 DeviceActivity API),该API是苹果从iOS 12开始推出的,用于支持屏幕使用时间相关功能的开发,仅能在iOS 12及以上版本中使用。本文将详细讲解完整的实现流程、权限配置与核心代码编写。
要使用Screen Time API,首先需要在Xcode项目中配置相关权限,告知用户App将获取屏幕使用时间数据。
NSUsageDescription(完整键名:Screen Time Usage Description)// 导入Screen Time框架 import ScreenTime import DeviceActivity
在App首次启动或需要使用该功能时,向用户申请Screen Time权限,只有获得授权后,才能读取其他App的使用数据。
// 初始化Screen Time授权管理器
let center = DASharedApplicationCenter.shared
// 申请授权
func requestScreenTimePermission() {
center.requestAuthorization { (granted, error) in
DispatchQueue.main.async {
if granted {
// 用户授权成功,可开始读取App使用数据
print("Screen Time 授权成功")
self.loadOtherAppUsageData()
} else {
// 用户拒绝授权,提示用户前往设置开启
print("Screen Time 授权失败:\(error?.localizedDescription ?? "未知错误")")
self.showPermissionTips()
}
}
}
}
// 提示用户前往设置开启权限
func showPermissionTips() {
let alert = UIAlertController(title: "权限申请失败", message: "请前往「设置」→「屏幕使用时间」→「内容与隐私访问限制」→「允许App」中开启本App的权限", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "知道了", style: .default))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true)
}
授权成功后,可通过 DAApplicationUsage 类获取指定时间范围内的其他App使用数据,包括使用时长、启动次数等。
// App使用信息模型
struct AppUsageModel {
let appName: String? // App名称
let bundleId: String // App唯一标识(Bundle ID)
let usageTime: TimeInterval // 使用时长(秒)
let launchCount: Int // 启动次数
}
// 加载其他App的使用时间数据(近24小时)
func loadOtherAppUsageData() {
// 定义时间范围:近24小时
let endDate = Date()
let startDate = Calendar.current.date(byAdding: .day, value: -1, to: endDate)!
// 获取App使用数据
DAApplicationUsage.fetchUsage(from: startDate, to: endDate) { (usageRecords, error) in
DispatchQueue.main.async {
guard let records = usageRecords, error == nil else {
print("读取App使用数据失败:\(error?.localizedDescription ?? "未知错误")")
return
}
// 转换为自定义模型(过滤当前App自身数据)
let currentBundleId = Bundle.main.bundleIdentifier!
var appUsageList: [AppUsageModel] = []
for record in records {
// 过滤当前App,只读取其他App的数据
guard record.bundleIdentifier != currentBundleId else {
continue
}
let appUsage = AppUsageModel(
appName: record.applicationName,
bundleId: record.bundleIdentifier,
usageTime: record.totalUsageTime,
launchCount: record.launchCount
)
appUsageList.append(appUsage)
}
// 处理读取到的其他App使用数据(展示、统计等)
self.handleAppUsageList(appUsageList)
}
}
}
// 处理读取到的App使用数据
func handleAppUsageList(_ list: [AppUsageModel]) {
for app in list {
let usageHours = String(format: "%.2f", app.usageTime / 3600)
print("App名称:\(app.appName ?? "未知App")")
print("Bundle ID:\(app.bundleId)")
print("使用时长:\(usageHours) 小时")
print("启动次数:\(app.launchCount) 次")
print("————————————————")
}
}
totalUsageTime 的单位是「秒」,如需转换为分钟/小时,需进行除法运算(1分钟=60秒,1小时=3600秒)applicationName 可能为 nil(部分系统App或未命名App),需做非空处理bundleIdentifier 区分不同App(如微信:com.tencent.xin,支付宝:com.eg.android.AlipayGphone)startDate 和 endDate 即可