import Foundation import EventKit import Combine // MARK: - 日历管理器 class CalendarManager: ObservableObject { static let shared = CalendarManager() private let eventStore = EKEventStore() @Published var objectWillChange = ObservableObjectPublisher() private init() {} // MARK: - 添加事件到日历 func addEventToCalendar(calendarDetails: CalendarDetails, completion: @escaping (Bool, String?) -> Void) { // 检查权限 if #available(iOS 17.0, *) { // iOS 17+ 使用新的权限API switch EKEventStore.authorizationStatus(for: .event) { case .fullAccess, .writeOnly: performAddEvent(calendarDetails: calendarDetails, completion: completion) case .notDetermined: requestCalendarAccess { [weak self] granted in if granted { self?.performAddEvent(calendarDetails: calendarDetails, completion: completion) } else { DispatchQueue.main.async { completion(false, "calendar_permission_denied".localized) } } } case .denied, .restricted: DispatchQueue.main.async { completion(false, "calendar_permission_denied".localized) } @unknown default: DispatchQueue.main.async { completion(false, "calendar_permission_unknown".localized) } } } else { // iOS 16及以下使用旧权限API switch EKEventStore.authorizationStatus(for: .event) { case .authorized: performAddEvent(calendarDetails: calendarDetails, completion: completion) case .notDetermined: requestCalendarAccess { [weak self] granted in if granted { self?.performAddEvent(calendarDetails: calendarDetails, completion: completion) } else { DispatchQueue.main.async { completion(false, "calendar_permission_denied".localized) } } } case .denied, .restricted: DispatchQueue.main.async { completion(false, "calendar_permission_denied".localized) } case .fullAccess: performAddEvent(calendarDetails: calendarDetails, completion: completion) case .writeOnly: performAddEvent(calendarDetails: calendarDetails, completion: completion) @unknown default: DispatchQueue.main.async { completion(false, "calendar_permission_unknown".localized) } } } } // MARK: - 请求日历权限 private func requestCalendarAccess(completion: @escaping (Bool) -> Void) { if #available(iOS 17.0, *) { Task { do { let granted = try await eventStore.requestWriteOnlyAccessToEvents() DispatchQueue.main.async { completion(granted) } } catch { DispatchQueue.main.async { completion(false) } } } } else { eventStore.requestAccess(to: .event) { granted, error in DispatchQueue.main.async { completion(granted) } } } } // MARK: - 执行添加事件 private func performAddEvent(calendarDetails: CalendarDetails, completion: @escaping (Bool, String?) -> Void) { let event = EKEvent(eventStore: eventStore) // 设置事件标题 event.title = calendarDetails.summary.isEmpty ? "calendar_event".localized : calendarDetails.summary // 设置事件描述 if !calendarDetails.description.isEmpty { event.notes = calendarDetails.description } // 设置事件位置 if !calendarDetails.location.isEmpty { event.location = calendarDetails.location } // 设置开始时间 if let startDate = parseCalendarDate(calendarDetails.startTime) { event.startDate = startDate } else { DispatchQueue.main.async { completion(false, "calendar_invalid_start_time".localized) } return } // 设置结束时间 if let endDate = parseCalendarDate(calendarDetails.endTime) { event.endDate = endDate } else { // 如果没有结束时间,设置为开始时间后1小时 event.endDate = event.startDate.addingTimeInterval(3600) } // 设置日历(使用默认日历) event.calendar = eventStore.defaultCalendarForNewEvents // 设置提醒(15分钟前) let alarm = EKAlarm(relativeOffset: -900) // -15分钟 event.addAlarm(alarm) // 保存事件 do { try eventStore.save(event, span: .thisEvent) DispatchQueue.main.async { completion(true, nil) } } catch { DispatchQueue.main.async { completion(false, "calendar_save_failed".localized) } } } // MARK: - 解析日历日期 private func parseCalendarDate(_ dateString: String) -> Date? { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyyMMdd'T'HHmmss" if let date = dateFormatter.date(from: dateString) { return date } // 尝试其他格式 dateFormatter.dateFormat = "yyyyMMdd" return dateFormatter.date(from: dateString) } }