Expensify / react-native-share-menu

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

[iOS] Black screen when sharing into the Expo bare app #200

Open b4lk0n opened 2 years ago

b4lk0n commented 2 years ago

Hey folks - I'm adding the package to Expo bare workflow app. I did everything according to instructions and it works perfectly on Android, but doesn't work on iOS.

$ yarn list react-native-share-menu
└─ react-native-share-menu@6.0.0

App's plist:

<?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>CFBundleIdentifier</key>
  <string>com.product.app</string>

  <key>CFBundleURLTypes</key>
  <array>
    <dict>
      <key>CFBundleTypeRole</key>
      <string>Editor</string>

      <key>CFBundleURLSchemes</key>
      <array>
        <string>com.product.app</string>
      </array>
    </dict>
  </array>

  <key>NSAppTransportSecurity</key>
  <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>

    <key>NSExceptionDomains</key>
    <dict>
      <key>localhost</key>
      <dict>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
      </dict>
    </dict>
  </dict>
...
</dict>
</plist>

Extension's plist:

<?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>HostAppBundleIdentifier</key>
  <string>com.product.app</string>

  <key>HostAppURLScheme</key>
  <string>com.product.app://</string>

  <key>NSExtension</key>
  <dict>
    <key>NSExtensionAttributes</key>
    <dict>
      <key>NSExtensionActivationRule</key>
      <dict>
        <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
        <integer>1</integer>
      </dict>
    </dict>

    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>

    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.share-services</string>
  </dict>

  <key>NSAppTransportSecurity</key>
  <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>

    <key>NSExceptionDomains</key>
    <dict>
      <key>localhost</key>
      <dict>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
      </dict>
    </dict>
  </dict>
</dict>
</plist>

But Expo's AppDelegate.m is a bit different from what instructions have. I tried to put the call of ShareMenuManager's openURL before and after EXDevLauncherController but nothing changes:

// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {

  [ShareMenuManager application:application openURL:url options:options];

  #if defined(EX_DEV_LAUNCHER_ENABLED)
  if ([EXDevLauncherController.sharedInstance onDeepLink:url options:options]) {
    return true;
  }
  #endif

  return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
}

Inside the app I added simple handler:

const handleShare = useCallback((data?: ShareData) => {
    console.log('Shared data:', data);
  }, []);

  useEffect(() => {
    ShareMenu.getInitialShare(handleShare);
  }, []);

  useEffect(() => {
    const listener = ShareMenu.addNewShareListener(handleShare);

    return () => {
      listener.remove();
    };
  }, []);

Actual behavior on both simulator and device:

On the first launch it triggers getInitialShare and logs contain:

Shared data: Object {
  "data": null,
}

If the app is open and I share a link from Safari to it - nothing happens. The app opens, but no event is triggered (no logs).

If the app is closed (but installed) and I share a link from Safari to the app - the app opens but is stuck on the back screen. And I see the following logs in the terminal:

[CoreFoundation] AddInstanceForFactory: No factory registered for id <CFUUID 0x600001ddfa60>
F8BB1C28-BAE8-11D6-9C31-00039315CD46
[CoreAudio]  HALC_ProxyObjectMap::_CopyObjectByObjectID: failed to create the local object
[CoreAudio]  HALC_ShellDevice::RebuildControlList: couldn't find the control object
[UIKitCore] A _UISceneDisplayLink target was deallocated while registered.

Has someone faced such an issue or can anyone assist in resolving it?

b4lk0n commented 2 years ago

use case: sharing a link from Safari to the app.

after some NSLogging and printing I found that the data is sent by the extension's view controller. The ShareMenuManager handles the URL, BUT there is no data inside UserDefaults.

NiftyApp commented 2 years ago

@b4lk0n Did you have any luck getting past the blank screen on expo?

b4lk0n commented 2 years ago

@NiftyApp nope, I ended up creating my own share extension and tweaking the package via patch-package

frankcalise commented 1 year ago

Could you share the solution?