diff --git a/ios/Plugin/DailyNotificationPlugin.swift b/ios/Plugin/DailyNotificationPlugin.swift index efde624..7a90bad 100644 --- a/ios/Plugin/DailyNotificationPlugin.swift +++ b/ios/Plugin/DailyNotificationPlugin.swift @@ -858,6 +858,95 @@ public class DailyNotificationPlugin: CAPPlugin { call.resolve() } + /** + * Calculate next run time + * + * Calculates the next run time from a cron expression or HH:mm time string. + * + * Equivalent to Android's calculateNextRunTime method. + */ + @objc func calculateNextRunTime(_ call: CAPPluginCall) { + guard let schedule = call.getString("schedule") else { + call.reject("Schedule expression is required") + return + } + + print("DNP-PLUGIN: Calculating next run time: schedule=\(schedule)") + + let nextRunAt = calculateNextRunTimeFromSchedule(schedule) + + let result: [String: Any] = [ + "nextRunAt": Int64(nextRunAt) + ] + + print("DNP-PLUGIN: Next run time calculated: \(nextRunAt)") + call.resolve(result) + } + + /** + * Calculate next run time from schedule string + * + * Supports both cron format ("minute hour * * *") and HH:mm format ("09:30"). + */ + private func calculateNextRunTimeFromSchedule(_ schedule: String) -> TimeInterval { + let calendar = Calendar.current + let now = Date() + + // Try to parse as HH:mm first + if schedule.contains(":") { + let parts = schedule.split(separator: ":") + if parts.count == 2, + let hour = Int(parts[0]), + let minute = Int(parts[1]), + hour >= 0 && hour <= 23, + minute >= 0 && minute <= 59 { + + var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: now) + components.hour = hour + components.minute = minute + components.second = 0 + + if let targetDate = calendar.date(from: components) { + // If time has passed today, schedule for tomorrow + if targetDate <= now { + if let tomorrow = calendar.date(byAdding: .day, value: 1, to: targetDate) { + return tomorrow.timeIntervalSince1970 * 1000 + } + } + return targetDate.timeIntervalSince1970 * 1000 + } + } + } + + // Try to parse as cron expression: "minute hour * * *" + let parts = schedule.trimmingCharacters(in: .whitespaces).split(separator: " ") + if parts.count >= 2, + let minute = Int(parts[0]), + let hour = Int(parts[1]), + minute >= 0 && minute <= 59, + hour >= 0 && hour <= 23 { + + var components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: now) + components.hour = hour + components.minute = minute + components.second = 0 + + if let targetDate = calendar.date(from: components) { + // If time has passed today, schedule for tomorrow + if targetDate <= now { + if let tomorrow = calendar.date(byAdding: .day, value: 1, to: targetDate) { + return tomorrow.timeIntervalSince1970 * 1000 + } + } + return targetDate.timeIntervalSince1970 * 1000 + } + } + + // Fallback: 24 hours from now + print("DNP-PLUGIN: Invalid schedule format, defaulting to 24h from now") + return (now.addingTimeInterval(24 * 60 * 60).timeIntervalSince1970 * 1000) + } + // MARK: - Permission Methods /**