|
|
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)
|
|
|
}
|
|
|
@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)
|
|
|
}
|
|
|
}
|