mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 09:58:38 +00:00
iOS: add write commands for contacts/calendar/reminders
This commit is contained in:
committed by
Mariano Belinky
parent
f72ac60b01
commit
a884955cd6
@@ -47,6 +47,59 @@ final class RemindersService: RemindersServicing {
|
||||
return OpenClawRemindersListPayload(reminders: payload)
|
||||
}
|
||||
|
||||
func add(params: OpenClawRemindersAddParams) async throws -> OpenClawRemindersAddPayload {
|
||||
let store = EKEventStore()
|
||||
let status = EKEventStore.authorizationStatus(for: .reminder)
|
||||
let authorized = await Self.ensureWriteAuthorization(store: store, status: status)
|
||||
guard authorized else {
|
||||
throw NSError(domain: "Reminders", code: 2, userInfo: [
|
||||
NSLocalizedDescriptionKey: "REMINDERS_PERMISSION_REQUIRED: grant Reminders permission",
|
||||
])
|
||||
}
|
||||
|
||||
let title = params.title.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
guard !title.isEmpty else {
|
||||
throw NSError(domain: "Reminders", code: 3, userInfo: [
|
||||
NSLocalizedDescriptionKey: "REMINDERS_INVALID: title required",
|
||||
])
|
||||
}
|
||||
|
||||
let reminder = EKReminder(eventStore: store)
|
||||
reminder.title = title
|
||||
if let notes = params.notes?.trimmingCharacters(in: .whitespacesAndNewlines), !notes.isEmpty {
|
||||
reminder.notes = notes
|
||||
}
|
||||
reminder.calendar = try Self.resolveList(
|
||||
store: store,
|
||||
listId: params.listId,
|
||||
listName: params.listName)
|
||||
|
||||
if let dueISO = params.dueISO?.trimmingCharacters(in: .whitespacesAndNewlines), !dueISO.isEmpty {
|
||||
let formatter = ISO8601DateFormatter()
|
||||
guard let dueDate = formatter.date(from: dueISO) else {
|
||||
throw NSError(domain: "Reminders", code: 4, userInfo: [
|
||||
NSLocalizedDescriptionKey: "REMINDERS_INVALID: dueISO must be ISO-8601",
|
||||
])
|
||||
}
|
||||
reminder.dueDateComponents = Calendar.current.dateComponents(
|
||||
[.year, .month, .day, .hour, .minute, .second],
|
||||
from: dueDate)
|
||||
}
|
||||
|
||||
try store.save(reminder, commit: true)
|
||||
|
||||
let formatter = ISO8601DateFormatter()
|
||||
let due = reminder.dueDateComponents.flatMap { Calendar.current.date(from: $0) }
|
||||
let payload = OpenClawReminderPayload(
|
||||
identifier: reminder.calendarItemIdentifier,
|
||||
title: reminder.title,
|
||||
dueISO: due.map { formatter.string(from: $0) },
|
||||
completed: reminder.isCompleted,
|
||||
listName: reminder.calendar.title)
|
||||
|
||||
return OpenClawRemindersAddPayload(reminder: payload)
|
||||
}
|
||||
|
||||
private static func ensureAuthorization(store: EKEventStore, status: EKAuthorizationStatus) async -> Bool {
|
||||
switch status {
|
||||
case .authorized:
|
||||
@@ -67,4 +120,52 @@ final class RemindersService: RemindersServicing {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private static func ensureWriteAuthorization(store: EKEventStore, status: EKAuthorizationStatus) async -> Bool {
|
||||
switch status {
|
||||
case .authorized, .fullAccess, .writeOnly:
|
||||
return true
|
||||
case .notDetermined:
|
||||
return await withCheckedContinuation { cont in
|
||||
store.requestAccess(to: .reminder) { granted, _ in
|
||||
cont.resume(returning: granted)
|
||||
}
|
||||
}
|
||||
case .restricted, .denied:
|
||||
return false
|
||||
@unknown default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private static func resolveList(
|
||||
store: EKEventStore,
|
||||
listId: String?,
|
||||
listName: String?) throws -> EKCalendar
|
||||
{
|
||||
if let id = listId?.trimmingCharacters(in: .whitespacesAndNewlines), !id.isEmpty,
|
||||
let calendar = store.calendar(withIdentifier: id)
|
||||
{
|
||||
return calendar
|
||||
}
|
||||
|
||||
if let title = listName?.trimmingCharacters(in: .whitespacesAndNewlines), !title.isEmpty {
|
||||
if let calendar = store.calendars(for: .reminder).first(where: {
|
||||
$0.title.compare(title, options: [.caseInsensitive, .diacriticInsensitive]) == .orderedSame
|
||||
}) {
|
||||
return calendar
|
||||
}
|
||||
throw NSError(domain: "Reminders", code: 5, userInfo: [
|
||||
NSLocalizedDescriptionKey: "REMINDERS_LIST_NOT_FOUND: no list named \(title)",
|
||||
])
|
||||
}
|
||||
|
||||
if let fallback = store.defaultCalendarForNewReminders() {
|
||||
return fallback
|
||||
}
|
||||
|
||||
throw NSError(domain: "Reminders", code: 6, userInfo: [
|
||||
NSLocalizedDescriptionKey: "REMINDERS_LIST_NOT_FOUND: no default list",
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user