ios-tracker/HabitTracker/Support/NotificationManager.swift
rene 22b8f5d806 Initiales HabitTracker-Projekt: SwiftUI + SwiftData Gewohnheiten-Tracker
Natives iOS-App-Gerüst (Xcode 26, synchronisierte Ordner, iOS 18+).

Features:
- Gewohnheiten anlegen (Name, SF-Symbol, Farbe), heute abhaken, Streaks, Löschen
- Detailansicht mit Monatskalender (Tage nachtragbar) und Statistiken
- Tägliche Erinnerungen via lokale Notifications
- Home-Screen-Widget (klein/mittel) mit App-Group-Datenaustausch
2026-05-29 21:12:45 +02:00

49 lines
1.7 KiB
Swift

import Foundation
import UserNotifications
@MainActor
enum NotificationManager {
/// Default reminder time (09:00) used when the user first enables a reminder.
static var defaultTime: Date {
Calendar.current.date(bySettingHour: 9, minute: 0, second: 0, of: .now) ?? .now
}
@discardableResult
static func requestAuthorization() async -> Bool {
do {
return try await UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge])
} catch {
return false
}
}
/// Cancels any existing reminder for the habit and, if it has a reminder
/// time, schedules a new daily notification.
static func reschedule(for habit: Habit) {
let center = UNUserNotificationCenter.current()
let id = identifier(for: habit)
center.removePendingNotificationRequests(withIdentifiers: [id])
guard let time = habit.reminderTime else { return }
let content = UNMutableNotificationContent()
content.title = habit.name
content.body = "Zeit für deine Gewohnheit"
content.sound = .default
let components = Calendar.current.dateComponents([.hour, .minute], from: time)
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
let request = UNNotificationRequest(identifier: id, content: content, trigger: trigger)
center.add(request)
}
static func cancel(for habit: Habit) {
UNUserNotificationCenter.current()
.removePendingNotificationRequests(withIdentifiers: [identifier(for: habit)])
}
private static func identifier(for habit: Habit) -> String {
"habit-\(habit.uuid.uuidString)"
}
}