增加 Markdown 文件分享支持
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>备忘录格式化助手</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsFileWithMaxCount</key>
|
||||
<integer>10</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.fishestlife.note</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user