mastodon-ios/FollowActionExtension/ActionRequestHandler.swift

92 lines
3.6 KiB
Swift

//
// ActionRequestHandler.swift
// FollowActionExtension
//
// 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
var found = false
// Find the item containing the results from the JavaScript preprocessing.
outer:
for item in context.inputItems as! [NSExtensionItem] {
if let attachments = item.attachments {
for itemProvider in attachments {
if itemProvider.hasItemConformingToTypeIdentifier(UTType.propertyList.identifier) {
itemProvider.loadItem(forTypeIdentifier: UTType.propertyList.identifier, options: nil, completionHandler: { (item, error) in
guard
let dictionary = item as? [String: Any],
let res = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as? [String: Any]? ?? [:]
else {
self.doneWithResults(
["error": "Failed to find username. Are you sure this is a Mastodon Profile page?"]
)
return
}
OperationQueue.main.addOperation {
self.itemLoadCompletedWithPreprocessingResults(res)
}
})
found = true
break outer
}
}
}
}
if !found {
self.doneWithResults(nil)
}
}
func itemLoadCompletedWithPreprocessingResults(_ javaScriptPreprocessingResults: [String: Any]) {
guard let username = javaScriptPreprocessingResults["username"] as? String else { return }
doneWithResults([
"openURL": "mastodon://profile/\(username)"
])
}
func doneWithResults(_ resultsForJavaScriptFinalizeArg: [String: Any]?) {
if let resultsForJavaScriptFinalize = resultsForJavaScriptFinalizeArg {
// Construct an NSExtensionItem of the appropriate type to return our
// results dictionary in.
// These will be used as the arguments to the JavaScript finalize()
// method.
let resultsDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: resultsForJavaScriptFinalize]
let resultsProvider = NSItemProvider(item: resultsDictionary as NSDictionary, typeIdentifier: UTType.propertyList.identifier)
let resultsItem = NSExtensionItem()
resultsItem.attachments = [resultsProvider]
// Signal that we're complete, returning our results.
self.extensionContext!.completeRequest(returningItems: [resultsItem], completionHandler: nil)
} else {
// We still need to signal that we're done even if we have nothing to
// pass back.
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
// Don't hold on to this after we finished with it.
self.extensionContext = nil
}
}