[Share Extension] Update to support video (#5385)
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||||
<integer>10</integer>
|
<integer>10</integer>
|
||||||
|
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||||
|
<integer>1</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>NSExtensionPointIdentifier</key>
|
<key>NSExtensionPointIdentifier</key>
|
||||||
@@ -38,4 +40,4 @@
|
|||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ class ShareViewController: UIViewController {
|
|||||||
// scheme.
|
// scheme.
|
||||||
let appScheme = Bundle.main.object(forInfoDictionaryKey: "MainAppScheme") as? String ?? "bluesky"
|
let appScheme = Bundle.main.object(forInfoDictionaryKey: "MainAppScheme") as? String ?? "bluesky"
|
||||||
|
|
||||||
//
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
@@ -24,6 +23,8 @@ class ShareViewController: UIViewController {
|
|||||||
await self.handleUrl(item: firstAttachment)
|
await self.handleUrl(item: firstAttachment)
|
||||||
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") {
|
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.image") {
|
||||||
await self.handleImages(items: attachments)
|
await self.handleImages(items: attachments)
|
||||||
|
} else if firstAttachment.hasItemConformingToTypeIdentifier("public.video") {
|
||||||
|
await self.handleVideos(items: attachments)
|
||||||
} else {
|
} else {
|
||||||
self.completeRequest()
|
self.completeRequest()
|
||||||
}
|
}
|
||||||
@@ -31,31 +32,23 @@ class ShareViewController: UIViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func handleText(item: NSItemProvider) async {
|
private func handleText(item: NSItemProvider) async {
|
||||||
do {
|
if let data = try? await item.loadItem(forTypeIdentifier: "public.text") as? String {
|
||||||
if let data = try await item.loadItem(forTypeIdentifier: "public.text") as? String {
|
if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
if let encoded = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
_ = self.openURL(url)
|
||||||
_ = self.openURL(url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.completeRequest()
|
|
||||||
} catch {
|
|
||||||
self.completeRequest()
|
|
||||||
}
|
}
|
||||||
|
self.completeRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleUrl(item: NSItemProvider) async {
|
private func handleUrl(item: NSItemProvider) async {
|
||||||
do {
|
if let data = try? await item.loadItem(forTypeIdentifier: "public.url") as? URL {
|
||||||
if let data = try await item.loadItem(forTypeIdentifier: "public.url") as? URL {
|
if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
if let encoded = data.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
||||||
let url = URL(string: "\(self.appScheme)://intent/compose?text=\(encoded)") {
|
_ = self.openURL(url)
|
||||||
_ = self.openURL(url)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.completeRequest()
|
|
||||||
} catch {
|
|
||||||
self.completeRequest()
|
|
||||||
}
|
}
|
||||||
|
self.completeRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleImages(items: [NSItemProvider]) async {
|
private func handleImages(items: [NSItemProvider]) async {
|
||||||
@@ -105,6 +98,25 @@ class ShareViewController: UIViewController {
|
|||||||
self.completeRequest()
|
self.completeRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func handleVideos(items: [NSItemProvider]) async {
|
||||||
|
let firstItem = items.first
|
||||||
|
|
||||||
|
if let dataUri = try? await firstItem?.loadItem(forTypeIdentifier: "public.video") as? URL {
|
||||||
|
let ext = String(dataUri.lastPathComponent.split(separator: ".").last ?? "mp4")
|
||||||
|
if let tempUrl = getTempUrl(ext: ext) {
|
||||||
|
let data = try? Data(contentsOf: dataUri)
|
||||||
|
try? data?.write(to: tempUrl)
|
||||||
|
|
||||||
|
if let encoded = dataUri.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
|
||||||
|
let url = URL(string: "\(self.appScheme)://intent/compose?videoUri=\(encoded)") {
|
||||||
|
_ = self.openURL(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.completeRequest()
|
||||||
|
}
|
||||||
|
|
||||||
private func saveImageWithInfo(_ image: UIImage?) -> String? {
|
private func saveImageWithInfo(_ image: UIImage?) -> String? {
|
||||||
guard let image = image else {
|
guard let image = image else {
|
||||||
return nil
|
return nil
|
||||||
@@ -114,27 +126,26 @@ class ShareViewController: UIViewController {
|
|||||||
// Saving this file to the bundle group's directory lets us access it from
|
// Saving this file to the bundle group's directory lets us access it from
|
||||||
// inside of the app. Otherwise, we wouldn't have access even though the
|
// inside of the app. Otherwise, we wouldn't have access even though the
|
||||||
// extension does.
|
// extension does.
|
||||||
if let dir = FileManager()
|
if let tempUrl = getTempUrl(ext: "jpeg"),
|
||||||
.containerURL(
|
let jpegData = image.jpegData(compressionQuality: 1) {
|
||||||
forSecurityApplicationGroupIdentifier: "group.app.bsky") {
|
try jpegData.write(to: tempUrl)
|
||||||
let filePath = "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).jpeg"
|
return "\(tempUrl.absoluteString)|\(image.size.width)|\(image.size.height)"
|
||||||
|
|
||||||
if let newUri = URL(string: filePath),
|
|
||||||
let jpegData = image.jpegData(compressionQuality: 1) {
|
|
||||||
try jpegData.write(to: newUri)
|
|
||||||
return "\(newUri.absoluteString)|\(image.size.width)|\(image.size.height)"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
} catch {}
|
||||||
} catch {
|
return nil
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func completeRequest() {
|
private func completeRequest() {
|
||||||
self.extensionContext?.completeRequest(returningItems: nil)
|
self.extensionContext?.completeRequest(returningItems: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func getTempUrl(ext: String) -> URL? {
|
||||||
|
if let dir = FileManager().containerURL(forSecurityApplicationGroupIdentifier: "group.app.bsky") {
|
||||||
|
return URL(string: "\(dir.absoluteString)\(ProcessInfo.processInfo.globallyUniqueString).\(ext)")!
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
@objc func openURL(_ url: URL) -> Bool {
|
@objc func openURL(_ url: URL) -> Bool {
|
||||||
var responder: UIResponder? = self
|
var responder: UIResponder? = self
|
||||||
while responder != nil {
|
while responder != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user