Expensify / react-native-share-menu

A module for React Native that adds your app to the share menu of the device
MIT License
653 stars 237 forks source link

Donate Send Message Intent and memory issue #237

Open samin opened 1 year ago

samin commented 1 year ago

Hi! πŸ‘‹

Firstly, thanks for your work on this project! πŸ™‚

Today I used patch-package to patch react-native-share-menu@6.0.0 for the project I'm working on.

  1. Added Intent listener for donated send message intent that works really well with this library: https://github.com/mackenziekira/react-native-donate-send-message-intent

  2. ShareMenuReactView.detachViewDelegate() is not always called because viewDidDisappear is not always called. This causes a memory issue when extension is called multiple times.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-share-menu/ios/Constants.swift b/node_modules/react-native-share-menu/ios/Constants.swift
index 08385b7..87b0d11 100644
--- a/node_modules/react-native-share-menu/ios/Constants.swift
+++ b/node_modules/react-native-share-menu/ios/Constants.swift
@@ -42,6 +42,7 @@ public let COLOR_TRANSPARENT_KEY = "Transparent"

 public let MIME_TYPE_KEY =  "mimeType"
 public let DATA_KEY =  "data"
+public let CONVERSATION_IDENTIFIER_KEY = "conversationIdentifier"
 public let EXTRA_DATA_KEY =  "extraData"

 // MARK: Events
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..b757efa 100644
--- a/node_modules/react-native-share-menu/ios/Modules/ShareMenuReactView.swift
+++ b/node_modules/react-native-share-menu/ios/Modules/ShareMenuReactView.swift
@@ -7,6 +7,7 @@

 import Foundation
 import MobileCoreServices
+import Intents

 @objc(ShareMenuReactView)
 public class ShareMenuReactView: NSObject {
@@ -45,6 +46,7 @@ public class ShareMenuReactView: NSObject {
         }

         extensionContext.completeRequest(returningItems: [], completionHandler: nil)
+        ShareMenuReactView.detachViewDelegate()
     }

     @objc
@@ -89,7 +91,20 @@ public class ShareMenuReactView: NSObject {
                 return
             }

-            resolve([DATA_KEY: data])
+            var intent: INSendMessageIntent? = nil
+            var conversationIdentifier: String? = nil
+
+            // Populate the recipient property with the metadata in case the user taps a suggestion from the share sheet.
+            if #available(iOS 13.0, *) {
+                intent = extensionContext.intent as? INSendMessageIntent
+            } else {
+                intent = nil
+            }
+            if intent != nil {
+                conversationIdentifier = intent!.conversationIdentifier
+            }
+
+            resolve([DATA_KEY: data ?? nil, CONVERSATION_IDENTIFIER_KEY: conversationIdentifier ?? 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..ea18ddd 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
@@ -49,9 +49,16 @@ class ReactShareViewController: ShareViewController, RCTBridgeDelegate, ReactSha
     ShareMenuReactView.attachViewDelegate(self)
   }

+  override func viewWillDisappear(_ animated: Bool) {
+    cancel()
+    ShareMenuReactView.detachViewDelegate()
+    super.viewWillDisappear(animated)
+  }
+
   override func viewDidDisappear(_ animated: Bool) {
     cancel()
     ShareMenuReactView.detachViewDelegate()
+    super.viewDidDisappear(animated)
   }

   func loadExtensionContext() -> NSExtensionContext {

This issue body was partially generated by patch-package.

VikalpP commented 1 year ago

Thanks, @samin We had the same issue where Share Extension opened for the first time, not at another time. Assuming its issues with the memory not realised, I found this GitHub issue & your solution works fine. βœ