fix: share extension not accept plaintext content issue. resolve #335

This commit is contained in:
CMK 2022-03-10 17:12:36 +08:00
parent fc2300804a
commit fe14e17810
3 changed files with 60 additions and 10 deletions

View File

@ -55,6 +55,24 @@ extension ItemProviderLoader {
] as CFDictionary
guard let cgImage = CGImageSourceCreateThumbnailAtIndex(source, 0, downsampleOptions) else {
// fallback to loadItem when create thumbnail failure
itemProvider.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { image, error in
if let error = error {
promise(.failure(error))
}
guard let image = image as? UIImage,
let data = image.jpegData(compressionQuality: 0.75)
else {
promise(.success(nil))
assertionFailure()
return
}
let file = Mastodon.Query.MediaAttachment.jpeg(data)
promise(.success(file))
} // end itemProvider.loadItem
return
}

View File

@ -26,6 +26,8 @@
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsImageWithMaxCount</key>

View File

@ -262,6 +262,10 @@ extension ShareViewModel {
itemProviders.append(contentsOf: item.attachments ?? [])
}
let _textProvider = itemProviders.first { provider in
return provider.hasRepresentationConforming(toTypeIdentifier: UTType.plainText.identifier, fileOptions: [])
}
let _urlProvider = itemProviders.first { provider in
return provider.hasRepresentationConforming(toTypeIdentifier: UTType.url.identifier, fileOptions: [])
}
@ -274,25 +278,51 @@ extension ShareViewModel {
return provider.hasRepresentationConforming(toTypeIdentifier: UTType.image.identifier, fileOptions: [])
}
if let urlProvider = _urlProvider {
urlProvider.loadItem(forTypeIdentifier: UTType.url.identifier) { [weak self] item, error in
guard let self = self else { return }
guard let url = item as? URL else { return }
DispatchQueue.main.async {
self.composeViewModel.statusContent = "\(url.absoluteString) "
}
}
} else if let movieProvider = _movieProvider {
Task { @MainActor in
async let text = ShareViewModel.loadText(textProvider: _textProvider)
async let url = ShareViewModel.loadURL(textProvider: _urlProvider)
let content = await [text, url]
.compactMap { $0 }
.joined(separator: " ")
self.composeViewModel.statusContent = content
}
if let movieProvider = _movieProvider {
composeViewModel.setupAttachmentViewModels([
StatusAttachmentViewModel(itemProvider: movieProvider)
])
} else {
} else if !imageProviders.isEmpty {
let viewModels = imageProviders.map { provider in
StatusAttachmentViewModel(itemProvider: provider)
}
composeViewModel.setupAttachmentViewModels(viewModels)
}
}
private static func loadText(textProvider: NSItemProvider?) async -> String? {
guard let textProvider = textProvider else { return nil }
do {
let item = try await textProvider.loadItem(forTypeIdentifier: UTType.plainText.identifier)
guard let text = item as? String else { return nil }
return text
} catch {
return nil
}
}
private static func loadURL(textProvider: NSItemProvider?) async -> String? {
guard let textProvider = textProvider else { return nil }
do {
let item = try await textProvider.loadItem(forTypeIdentifier: UTType.url.identifier)
guard let url = item as? URL else { return nil }
return url.absoluteString
} catch {
return nil
}
}
}
extension ShareViewModel {