mastodon-ios/OpenInActionExtension/ActionRequestHandler.swift

76 lines
2.8 KiB
Swift

//
// ActionRequestHandler.swift
// OpenInActionExtension
//
// Created by Marcus Kida on 03.01.23.
//
import UIKit
import MobileCoreServices
import UniformTypeIdentifiers
class ActionRequestHandler: NSObject, NSExtensionRequestHandling {
var extensionContext: NSExtensionContext?
func beginRequest(with context: NSExtensionContext) {
// Do not call super in an Action extension with no user interface
self.extensionContext = context
guard
let itemProvider = context.inputItems
.compactMap({ $0 as? NSExtensionItem })
.reduce([NSItemProvider](), { partialResult, acc in
var nextResult = partialResult
nextResult += acc.attachments ?? []
return nextResult
})
.filter({ $0.hasItemConformingToTypeIdentifier(UTType.propertyList.identifier) })
.first
else {
return self.completeWithNotFoundError()
}
itemProvider.loadItem(forTypeIdentifier: UTType.propertyList.identifier, options: nil, completionHandler: { (item, error) in
guard
let dictionary = item as? [String: Any],
let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as? [String: Any]? ?? [:]
else {
return self.completeWithNotFoundError()
}
DispatchQueue.main.async {
self.completeWithOpenUserProfile(results)
}
})
}
}
private extension ActionRequestHandler {
func completeWithOpenUserProfile(_ results: [String: Any]) {
guard let username = results["username"] as? String else { return }
doneWithResults([
"openURL": "mastodon://profile/\(username)"
])
}
func completeWithNotFoundError() {
doneWithResults(
["error": "Failed to find username. Are you sure this is a Mastodon Profile page?"]
)
}
func doneWithResults(_ resultsForJavaScriptFinalizeArg: [String: Any]?) {
if let resultsForJavaScriptFinalize = resultsForJavaScriptFinalizeArg {
let resultsDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: resultsForJavaScriptFinalize]
let resultsProvider = NSItemProvider(item: resultsDictionary as NSDictionary, typeIdentifier: UTType.propertyList.identifier)
let resultsItem = NSExtensionItem()
resultsItem.attachments = [resultsProvider]
self.extensionContext!.completeRequest(returningItems: [resultsItem], completionHandler: nil)
} else {
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
self.extensionContext = nil
}
}