Created
September 8, 2024 09:40
-
-
Save yccheok/cf7358a2f8a813da290ab36240f81c52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ShareViewController: UIViewController { | |
override func viewDidAppear(_ animated: Bool) { | |
super.viewDidAppear(animated) | |
// Get the all encompasing object that holds whatever was shared. If not, dismiss view. | |
guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { | |
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) | |
return | |
} | |
accessWebpageProperties(extensionItem: extensionItem) | |
} | |
private func accessWebpageProperties(extensionItem: NSExtensionItem) { | |
guard let attachments = extensionItem.attachments else { | |
return | |
} | |
Task { | |
for attachment in attachments { | |
if let url = await handleIncomingURL(itemProvider: attachment) { | |
shareAndBye(url: url) | |
return | |
} | |
if let url = await handleIncomingText(itemProvider: attachment) { | |
shareAndBye(url: url) | |
return | |
} | |
} | |
bye() | |
} | |
} | |
private func handleIncomingURL(itemProvider: NSItemProvider) async -> String? { | |
do { | |
if let url = try await itemProvider.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) as? NSURL { | |
if let urlString = url.absoluteString?.trimmingCharacters(in: .whitespacesAndNewlines), ShareViewController.isValidWebsiteURL(urlString) { | |
return urlString | |
} | |
} | |
} catch { | |
// Handle errors appropriately here | |
print("Error handling incoming URL: \(error)") | |
} | |
return nil | |
} | |
private func handleIncomingText(itemProvider: NSItemProvider) async -> String? { | |
do { | |
let text = try await itemProvider.loadItem(forTypeIdentifier: UTType.text.identifier, options: nil) as? String | |
if let text = text?.trimmingCharacters(in: .whitespacesAndNewlines) { | |
do { | |
let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) | |
let matches = detector.matches( | |
in: text, | |
options: [], | |
range: NSRange(location: 0, length: text.utf16.count) | |
) | |
for match in matches { | |
if let range = Range(match.range, in: text) { | |
let url = String(text[range]).trimmingCharacters(in: .whitespacesAndNewlines) | |
if ShareViewController.isValidWebsiteURL(url) { | |
return url | |
} | |
} | |
} | |
} catch let error { | |
print("Do-Try Error: \(error.localizedDescription)") | |
} | |
} | |
} catch { | |
// Handle errors appropriately here | |
print("Error handling incoming text: \(error)") | |
} | |
return nil | |
} | |
// TODO: Need to fix this. | |
private static func isValidWebsiteURL(_ urlString: String) -> Bool { | |
if urlString.isEmpty { | |
return false | |
} | |
if let url = URL(string: urlString), url.host != nil, (url.scheme == "http" || url.scheme == "https") { | |
return true | |
} | |
return false | |
} | |
@MainActor | |
private func shareAndBye(url: String) { | |
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: { _ in | |
if let encodedURL = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { | |
let appURL = "melonote://share?url=" + encodedURL | |
guard let url = URL(string: appURL) else { return } | |
_ = self.openURL(url) | |
} | |
}) | |
} | |
@MainActor | |
private func bye() { | |
self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) | |
} | |
// Courtesy: https://stackoverflow.com/a/44499222/13363449 👇🏾 | |
// Function must be named exactly like this so a selector can be found by the compiler! | |
// Anyway - it's another selector in another instance that would be "performed" instead. | |
@objc private func openURL(_ url: URL) -> Bool { | |
var responder: UIResponder? = self | |
while responder != nil { | |
if let application = responder as? UIApplication { | |
return application.perform(#selector(openURL(_:)), with: url) != nil | |
} | |
responder = responder?.next | |
} | |
return false | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment