Skip to content

Instantly share code, notes, and snippets.

@pesterev
Created February 12, 2024 11:13
Show Gist options
  • Save pesterev/b2fba7ad2dbd5a7a2ea9e43cc3fa0062 to your computer and use it in GitHub Desktop.
Save pesterev/b2fba7ad2dbd5a7a2ea9e43cc3fa0062 to your computer and use it in GitHub Desktop.
nvim-reminders-xpc
//
// main.swift
// nvim-reminders-xpc
//
// Created by . on 2/11/24.
//
import XPC
import EventKit
startListener()
func startListener() {
do {
_ = try XPCListener(service: "pesterev.nvim-reminders-xpc") { request in
request.accept { message in
return handleMessage(with: message)
}
}
} catch {
print("Failed to create listener, error: \(error)")
return
}
dispatchMain()
}
func handleMessage(with message: XPCReceivedMessage) -> Encodable? {
do {
let request = try message.decode(as: IncomingMessage.self)
} catch {
print("Failed to decode received message, error: \(error)")
return nil
}
let semaphore = DispatchSemaphore(value: 1)
var allReminders: [Reminder] = []
withUnsafeMutablePointer(to: &allReminders) {
pointer in
Task {
let store = EKEventStore()
let granted = try await store.requestFullAccessToReminders()
if !granted {
return
}
let predicate = store.predicateForReminders(in: nil)
let reminders = await withCheckedContinuation { continuation in store.fetchReminders(matching: predicate, completion: continuation.resume)
}
guard let reminders = reminders else {
return
}
let allReminders = reminders.map {
it in
Reminder(description: it.description, isCompleted: it.isCompleted)
}
pointer.pointee = allReminders
semaphore.signal()
}
}
switch semaphore.wait(timeout: .now() + 10) {
case .success: return OutgoingMessage.allReminders(allReminders)
case .timedOut: return nil
}
}
/*
To use this service from an app or other process, use XPCSession to establish a connection to the service.
do {
session = try XPCSession(xpcService: "pesterev.nvim-reminders-xpc")
} catch {
print("Failed to connect to listener, error: \(error)")
}
Once you have a connection to the service, create a Codable request and send it to the service.
do {
let request = CalculationRequest(firstNumber: 23, secondNumber: 19)
let reply = try session.sendSync(request)
let response = try reply.decode(as: CalculationResponse.self)
DispatchQueue.main.async {
print("Received response with result: \(response.result)")
}
} catch {
print("Failed to send message or decode reply: \(error.localizedDescription)")
}
When you're done using the connection, cancel it by doing the following:
session.cancel(reason: "Done with calculation")
*/
//
// nvim_reminders_xpcTypes.swift
// nvim-reminders-xpc
//
// Created by . on 2/11/24.
//
enum IncomingMessage: Codable {
case fetchAllReminders
}
enum OutgoingMessage: Codable {
case allReminders([Reminder])
}
struct Reminder: Codable {
let description: String
let isCompleted: Bool
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment