react-native-share-menu
react-native-share-menu copied to clipboard
ios: sharing system screen snapshot doesn't open the app
Hi,
When taking a screen snapshot and want to share it, my app appears in share menu. If i choose it, the share view of my app appears, but when i click to publish, the menu closes and my app is not displayed. If i try same thing with example provided in this repository, the app's share menu appears and closes immediately.
Any idea ?
Facing Same issue! @xavax31 Did you find any solution?
@iamjatttin, a lot of hacks. The main problem found was that snapshot app doesn't give simply a image type, but a public url. I finally resolved for my use by opening public.url attachment type in the info.plist of shared extension, and doing some change in swift code, but without really swift skills ( my fork here ). I needed also to change my react native code, to copy the provided file in my app tmp directory, to avoid security access error. Not perfect because in my case, I only want images or pdf, but the public.url type include every file format. But this resolve many cases where the plugin didn't work correctly, and is sufficient for me.
info.plist:
<key>NSExtensionAttributes</key> <dict> <key>NSExtensionActivationRule</key> <string> SUBQUERY ( extensionItems, $extensionItem, SUBQUERY ( $extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image" || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url" ).@count == 1 ).@count == 1 </string> </dict>
@xavax31 I've had a similar but different problem (sharing screenshots) I've noticed that within your storeImageRawData function you're loading the item again from the provider. Not sure whether this is intended to work in swift, but then again, I'm lacking swift skills myself. Once I've removed this, your solution of handling it as UIImage has worked nicely for me, so thanks! Posting my unverified, single device, limited manual tested, slim patch for others that end up here
diff --git a/node_modules/react-native-share-menu/ios/Modules/ShareMenuReactView.swift b/node_modules/react-native-share-menu/ios/Modules/ShareMenuReactView.swift
index e290cce..7380ee4 100644
--- a/node_modules/react-native-share-menu/ios/Modules/ShareMenuReactView.swift
+++ b/node_modules/react-native-share-menu/ios/Modules/ShareMenuReactView.swift
@@ -147,7 +147,7 @@ public class ShareMenuReactView: NSObject {
// Writing the image to the URL
try imageData.write(to: imageURL)
- results.append([DATA_KEY: imageUrl.absoluteString, MIME_TYPE_KEY: imageURL.extractMimeType()])
+ results.append([DATA_KEY: imageURL.absoluteString, MIME_TYPE_KEY: imageURL.extractMimeType()])
} catch {
callback(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason:"Can't load image", userInfo:nil))
}
diff --git a/node_modules/react-native-share-menu/ios/ReactShareViewController.swift b/node_modules/react-native-share-menu/ios/ReactShareViewController.swift
index f42bce6..ee36062 100644
--- a/node_modules/react-native-share-menu/ios/ReactShareViewController.swift
+++ b/node_modules/react-native-share-menu/ios/ReactShareViewController.swift
@@ -13,7 +13,7 @@ class ReactShareViewController: ShareViewController, RCTBridgeDelegate, ReactSha
func sourceURL(for bridge: RCTBridge!) -> URL! {
#if DEBUG
return RCTBundleURLProvider.sharedSettings()?
- .jsBundleURL(forBundleRoot: "index.share", fallbackResource: nil)
+ .jsBundleURL(forBundleRoot: "index.share")
#else
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
diff --git a/node_modules/react-native-share-menu/ios/ShareViewController.swift b/node_modules/react-native-share-menu/ios/ShareViewController.swift
index 12d8c92..4653c4c 100644
--- a/node_modules/react-native-share-menu/ios/ShareViewController.swift
+++ b/node_modules/react-native-share-menu/ios/ShareViewController.swift
@@ -166,10 +166,6 @@ class ShareViewController: SLComposeServiceViewController {
self.exit(withError: error.debugDescription)
return
}
- guard let url = data as? URL else {
- self.exit(withError: COULD_NOT_FIND_IMG_ERROR)
- return
- }
guard let hostAppId = self.hostAppId else {
self.exit(withError: NO_INFO_PLIST_INDENTIFIER_ERROR)
return
@@ -181,18 +177,41 @@ class ShareViewController: SLComposeServiceViewController {
return
}
- let mimeType = url.extractMimeType()
- let fileExtension = url.pathExtension
- let fileName = UUID().uuidString
- let filePath = groupFileManagerContainer
- .appendingPathComponent("\(fileName).\(fileExtension)")
+ if let uiImage = data as? UIImage {
+ let fileExtension = "png"
+ let fileName = UUID().uuidString
+ let filePath = groupFileManagerContainer
+ .appendingPathComponent("\(fileName).\(fileExtension)")
- guard self.moveFileToDisk(from: url, to: filePath) else {
- self.exit(withError: COULD_NOT_SAVE_FILE_ERROR)
+ guard let rawData = uiImage.pngData()
+ else {
+ self.exit(withError: "Error while getting raw data")
+ return
+ }
+
+ guard FileManager.default.createFile(atPath: filePath.path, contents: rawData)
+ else {
+ self.exit(withError: "Error while createFile")
+ return
+ }
+ self.sharedItems.append([DATA_KEY: filePath.absoluteString, MIME_TYPE_KEY: "image/png"])
+ } else if let url = data as? URL {
+ let mimeType = url.extractMimeType()
+ let fileExtension = url.pathExtension
+ let fileName = UUID().uuidString
+ let filePath = groupFileManagerContainer
+ .appendingPathComponent("\(fileName).\(fileExtension)")
+
+ guard self.moveFileToDisk(from: url, to: filePath) else {
+ self.exit(withError: COULD_NOT_SAVE_FILE_ERROR)
+ return
+ }
+
+ self.sharedItems.append([DATA_KEY: filePath.absoluteString, MIME_TYPE_KEY: mimeType])
+ } else {
+ self.exit(withError: COULD_NOT_FIND_IMG_ERROR)
return
}
-
- self.sharedItems.append([DATA_KEY: filePath.absoluteString, MIME_TYPE_KEY: mimeType])
semaphore.signal()
}
}
@filipgerat Is this your patch from @xavax31 's fork? Or is that patch from rn-share-menu master branch? I'm currently trying to get the fork running.
@jakehasler the patch is from rn-share-menu.
@filipgerat Your patch is working great! Thank you so much. Been struggling with this for a long while.
In the ShareMenuReactView class, I noticed a variable name inconsistency in the extractDataFromContext function.
The issue is in this block of code:
let imageData: Data! = image.pngData();
// Creating a temporary URL for image data (UIImage)
guard let imageURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("TemporaryScreenshot.png") else {
return
}
do {
// Writing the image to the URL
try imageData.write(to: imageURL)
results.append([DATA_KEY: imageUrl.absoluteString, MIME_TYPE_KEY: imageURL.extractMimeType()])
} catch {
callback(nil, NSException(name: NSExceptionName(rawValue: "Error"), reason:"Can't load image", userInfo:nil))
}
The temporary variable defined for "TemporaryScreenshot.png" is imageURL, but it is incorrectly used as imageUrl here:
results.append([DATA_KEY: imageUrl.absoluteString, MIME_TYPE_KEY: imageURL.extractMimeType()])
To fix this issue, you should change it to:
results.append([DATA_KEY: imageURL.absoluteString, MIME_TYPE_KEY: imageURL.extractMimeType()])
Add this in your ShareViewController in the storeFile function
ShareViewController
if let uiImage = data as? UIImage {
let fileExtension = "png"
let fileName = UUID().uuidString
let filePath = groupFileManagerContainer
.appendingPathComponent("\(fileName).\(fileExtension)")
guard let rawData: Data = uiImage.pngData() else {
self.exit(withError: "Error while getting raw data")
return
}
guard FileManager.default.createFile(atPath: filePath.path, contents: rawData) else {
self.exit(withError: "Error while createFile")
return
}
self.sharedItems.append([DATA_KEY: filePath.absoluteString, MIME_TYPE_KEY: "image/png"])
semaphore.signal()
return
}