增加 Markdown 文件分享支持

This commit is contained in:
2026-07-14 22:29:58 +08:00
parent e19dba594c
commit 3dccd16757
9 changed files with 657 additions and 5 deletions
@@ -0,0 +1,103 @@
import UIKit
import UniformTypeIdentifiers
class ShareViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
handleSharedItems()
}
private func handleSharedItems() {
guard let items = extensionContext?.inputItems as? [NSExtensionItem] else {
closeExtension()
return
}
let fileManager = FileManager.default
guard let containerURL = fileManager.containerURL(forSecurityApplicationGroupIdentifier: "group.com.fishestlife.note") else {
closeExtension()
return
}
let sharedDir = containerURL.appendingPathComponent("SharedFiles", isDirectory: true)
try? fileManager.createDirectory(at: sharedDir, withIntermediateDirectories: true)
var sharedTexts: [String] = []
var sharedFileNames: [String] = []
let group = DispatchGroup()
for item in items {
guard let attachments = item.attachments else { continue }
for attachment in attachments {
group.enter()
if attachment.hasItemConformingToTypeIdentifier(UTType.plainText.identifier) {
attachment.loadItem(forTypeIdentifier: UTType.plainText.identifier, options: nil) { data, _ in
defer { group.leave() }
if let text = data as? String {
sharedTexts.append(text)
} else if let url = data as? URL, let text = try? String(contentsOf: url, encoding: .utf8) {
sharedTexts.append(text)
}
}
} else if attachment.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
attachment.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) { data, _ in
defer { group.leave() }
if let url = data as? URL, let text = try? String(contentsOf: url, encoding: .utf8) {
sharedTexts.append(text)
}
}
} else {
attachment.loadItem(forTypeIdentifier: UTType.data.identifier, options: nil) { data, _ in
defer { group.leave() }
if let url = data as? URL {
let destURL = sharedDir.appendingPathComponent(url.lastPathComponent)
try? fileManager.removeItem(at: destURL)
if (try? fileManager.copyItem(at: url, to: destURL)) != nil {
sharedFileNames.append(url.lastPathComponent)
}
} else if let fileData = data as? Data {
let fileName = "shared-\(UUID().uuidString).md"
let destURL = sharedDir.appendingPathComponent(fileName)
if (try? fileData.write(to: destURL)) != nil {
sharedFileNames.append(fileName)
}
}
}
}
}
}
group.notify(queue: .main) { [weak self] in
self?.openMainApp(texts: sharedTexts, fileNames: sharedFileNames)
}
}
private func openMainApp(texts: [String], fileNames: [String]) {
var components = URLComponents(string: "noteapp://share")!
var queryItems: [URLQueryItem] = []
for (index, text) in texts.prefix(5).enumerated() {
queryItems.append(URLQueryItem(name: "text\(index)", value: text))
}
for (index, fileName) in fileNames.prefix(5).enumerated() {
queryItems.append(URLQueryItem(name: "file\(index)", value: fileName))
}
components.queryItems = queryItems.isEmpty ? nil : queryItems
guard let url = components.url else {
closeExtension()
return
}
extensionContext?.open(url) { [weak self] _ in
self?.closeExtension()
}
}
private func closeExtension() {
extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
}
}