mirror of
https://github.com/carey314/mio-plugin-airdrop.git
synced 2026-06-11 03:54:33 +00:00
56 lines
1.8 KiB
Swift
56 lines
1.8 KiB
Swift
|
|
//
|
||
|
|
// AirDropService.swift
|
||
|
|
// MioIsland AirDrop Plugin
|
||
|
|
//
|
||
|
|
// Thin wrapper around NSSharingService(.sendViaAirDrop). This is a
|
||
|
|
// 100% public Apple API — no entitlements, no permissions, no
|
||
|
|
// private frameworks. When invoked, macOS pops the native AirDrop
|
||
|
|
// chooser sheet; we don't render the device list ourselves.
|
||
|
|
//
|
||
|
|
|
||
|
|
import AppKit
|
||
|
|
import Foundation
|
||
|
|
|
||
|
|
enum AirDropError: Error, LocalizedError {
|
||
|
|
case serviceUnavailable
|
||
|
|
case cannotPerform
|
||
|
|
|
||
|
|
var errorDescription: String? {
|
||
|
|
switch self {
|
||
|
|
case .serviceUnavailable:
|
||
|
|
return L10n.errServiceUnavailable
|
||
|
|
case .cannotPerform:
|
||
|
|
return L10n.errCannotPerform
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
enum AirDropService {
|
||
|
|
/// Invoke macOS' AirDrop chooser for the given files.
|
||
|
|
///
|
||
|
|
/// NSSharingService does NOT surface per-recipient completion,
|
||
|
|
/// so we can only distinguish "could not start" vs "started and
|
||
|
|
/// returned control to us". A returned .success(()) means the
|
||
|
|
/// chooser sheet was presented; the user may have cancelled it,
|
||
|
|
/// but from our UI perspective we treat it as handled.
|
||
|
|
static func perform(
|
||
|
|
files: [URL],
|
||
|
|
completion: @escaping (Result<Void, Error>) -> Void
|
||
|
|
) {
|
||
|
|
DispatchQueue.main.async {
|
||
|
|
guard let service = NSSharingService(named: .sendViaAirDrop) else {
|
||
|
|
completion(.failure(AirDropError.serviceUnavailable))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
guard service.canPerform(withItems: files) else {
|
||
|
|
completion(.failure(AirDropError.cannotPerform))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
service.perform(withItems: files)
|
||
|
|
// AirDrop chooser is modal; perform() returns right after
|
||
|
|
// presenting. Treat that as success.
|
||
|
|
completion(.success(()))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|