You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

153 lines
5.1 KiB

/**
* DailyNotificationPowerManager.swift
* Daily Notification Plugin for Capacitor
*
* Manages power state and battery optimization for notifications
*/
import Foundation
import UIKit
import UserNotifications
/// Manages power state and battery optimization for the notification plugin
public class DailyNotificationPowerManager {
/// Shared instance for singleton access
public static let shared = DailyNotificationPowerManager()
private var batteryLevel: Float = 1.0
private var isCharging = false
private var lastBatteryCheck: Date = Date()
private var powerState: UIDevice.BatteryState = .unknown
private var adaptiveSchedulingEnabled = true
private init() {
setupBatteryMonitoring()
}
private func setupBatteryMonitoring() {
UIDevice.current.isBatteryMonitoringEnabled = true
updateBatteryStatus()
NotificationCenter.default.addObserver(
self,
selector: #selector(batteryLevelDidChange),
name: UIDevice.batteryLevelDidChangeNotification,
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(batteryStateDidChange),
name: UIDevice.batteryStateDidChangeNotification,
object: nil
)
}
@objc private func batteryLevelDidChange() {
updateBatteryStatus()
}
@objc private func batteryStateDidChange() {
updateBatteryStatus()
}
private func updateBatteryStatus() {
batteryLevel = UIDevice.current.batteryLevel
isCharging = UIDevice.current.batteryState == .charging
powerState = UIDevice.current.batteryState
lastBatteryCheck = Date()
DailyNotificationLogger.shared.log(
.debug,
"Battery status updated: \(Int(batteryLevel * 100))% (\(isCharging ? "charging" : "not charging"))"
)
}
/// Gets the current battery status
/// - Returns: Dictionary containing battery information
public func getBatteryStatus() -> [String: Any] {
return [
"level": Int(batteryLevel * 100),
"isCharging": isCharging,
"lastCheck": lastBatteryCheck.timeIntervalSince1970,
"powerState": getPowerStateString()
]
}
/// Gets the current power state
/// - Returns: Dictionary containing power state information
public func getPowerState() -> [String: Any] {
return [
"powerState": getPowerStateString(),
"adaptiveScheduling": adaptiveSchedulingEnabled,
"batteryLevel": Int(batteryLevel * 100),
"isCharging": isCharging,
"lastCheck": lastBatteryCheck.timeIntervalSince1970
]
}
/// Sets whether adaptive scheduling is enabled
/// - Parameter enabled: Whether to enable adaptive scheduling
public func setAdaptiveScheduling(_ enabled: Bool) {
adaptiveSchedulingEnabled = enabled
DailyNotificationLogger.shared.log(
.info,
"Adaptive scheduling \(enabled ? "enabled" : "disabled")"
)
}
/// Gets the appropriate scheduling interval based on battery level
/// - Returns: TimeInterval for scheduling
public func getSchedulingInterval() -> TimeInterval {
guard adaptiveSchedulingEnabled else {
return DailyNotificationConfig.SchedulingIntervals.normal
}
let batteryPercentage = Int(batteryLevel * 100)
switch batteryPercentage {
case ..<DailyNotificationConfig.BatteryThresholds.critical:
return DailyNotificationConfig.SchedulingIntervals.critical
case ..<DailyNotificationConfig.BatteryThresholds.low:
return DailyNotificationConfig.SchedulingIntervals.low
case ..<DailyNotificationConfig.BatteryThresholds.medium:
return DailyNotificationConfig.SchedulingIntervals.medium
default:
return DailyNotificationConfig.SchedulingIntervals.normal
}
}
/// Gets the appropriate wake lock duration based on battery level
/// - Returns: TimeInterval for wake lock
public func getWakeLockDuration() -> TimeInterval {
let batteryPercentage = Int(batteryLevel * 100)
switch batteryPercentage {
case ..<DailyNotificationConfig.BatteryThresholds.critical:
return DailyNotificationConfig.WakeLockDurations.critical
case ..<DailyNotificationConfig.BatteryThresholds.low:
return DailyNotificationConfig.WakeLockDurations.low
default:
return DailyNotificationConfig.WakeLockDurations.normal
}
}
private func getPowerStateString() -> String {
switch powerState {
case .charging:
return "CHARGING"
case .full:
return "FULL"
case .unplugged:
return "UNPLUGGED"
case .unknown:
return "UNKNOWN"
@unknown default:
return "UNKNOWN"
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}