/expo-share-intent-demo

React Native Expo Share Intent

Primary LanguageJavaScriptApache License 2.0Apache-2.0

Expo Share Intent Demo

This project demonstrates a functional share intent in an Expo (React Native) project. It allows to use Expo's auto-configuration for the react-native-receive-sharing-intent package.

This demo works with Expo SDK 48. Is compatible with Android and iOS and support URL, text, images, videos and files sharing.

More Demo :

Table of Contents

Getting Started

yarn install
yarn prebuild
yarn ios
yarn android

How It Works

We're using and tweaking two awesome projects:

And to make life easier, we've got patch-package doing the heavy lifting for patching. Check out the "patches" directory for details.

iOS Tricks

Thanks to the expo-config-plugin-ios-share-extension package, manual configuration, as described in the original documentation, is not needed.

Content Types

Simply choose content types you need :

  "plugins": [
      [
        "expo-config-plugin-ios-share-extension",
        {
          "activationRules": {
            "NSExtensionActivationSupportsText": true,
            "NSExtensionActivationSupportsWebURLWithMaxCount": 1,
            "NSExtensionActivationSupportsWebPageWithMaxCount": 1,
            "NSExtensionActivationSupportsImageWithMaxCount": 1,
            "NSExtensionActivationSupportsMovieWithMaxCount": 1,
          }
        }
      ],
  ],
Option Values
activationRules Allow text sharing with "NSExtensionActivationSupportsText": true
Url sharing with "NSExtensionActivationSupportsWebURLWithMaxCount": 1 and "NSExtensionActivationSupportsWebPageWithMaxCount": 1
Images sharing with "NSExtensionActivationSupportsImageWithMaxCount": 1
Videos sharing with "NSExtensionActivationSupportsImageWithMaxCount": 1
default value: { "NSExtensionActivationSupportsWebURLWithMaxCount": 1, "NSExtensionActivationSupportsWebPageWithMaxCount": 1 }"

WIP: There's a matching PR for "expo-config-plugin-ios-share-extension"

Android Magic

For Android, a config plugin has been added (see plugins/withAndroidShareExtension directory) to add missing elements and automate the steps from the documentation.

Content Types

Simply choose content types you need :

  "plugins": [
      [
        "./plugins/withAndroidShareExtension/index",
        {
          "androidIntentFilters": [
            "text/*",
            "image/*",
            "video/*"
          ],
        }
      ],
  ],
Option Values
androidIntentFilters array of MIME types :"text/*" / "image/*" / "video/*" / "*/*"
default value: ["text/*"] (text and url)
androidMainActivityAttributes default value: { "android:launchMode": "singleTask" }
androidExtraBuildProperties https://docs.expo.dev/versions/latest/sdk/build-properties/#pluginconfigtypeandroid
example: { "targetSdkVersion": 33 } , default value: {}

Deep Dive

Expo Router

With expo-router you need to handle loading elements on Layout. It's the only way to call the native module using deeplink url (useShareIntent hook).

An example is available with Expo Router v2 on branch expo49-expo-router

React Navigation

If you want to handle share intent with react-navigation (v6), you could add a custom mapping function in our linking configuration like this :

  // see: https://reactnavigation.org/docs/configuring-links/#advanced-cases
  getStateFromPath(path, config) {
    if (path?.includes(`dataurl=${Constants.expoConfig.scheme}sharekey`)) {
      return {
        routes: [{ name: 'HomeStackScreen', params: { screen: 'ShareIntentScreen' } }],
      };
    }
    return getStateFromPath(path, config);
  },

Troubleshooting - FAQ

iOS Extension Target

When building on EAS you should only have one extension target (during credentials setting process).

To avoid expo auto configuration to add an experimental "appExtensions" to app.json you must manually configure your eas build (projectId in app.json and a eas.json file).

More details in #1

Expo Go ?

We are using native code to make share intent works, so we can't use Expo Go and have to use a custom dev client, that's why the demo use expo prebuild --no-install command and then expo run:ios, instead of a simple expo start --ios -> More information here

That way you can test your share intent into simulator, but that does not exempt you to test a complete build on device at the end of your development process to make sure all works as excepted.

NB: don't commit your ios/ and android/ folder, rebuild it before EAS build.

Custom view ?

This project does not support iOS custom view (native view in share intent context). Everything must be handle into React Native code.

Support

Enjoying this project? Wanna show some love? Drop a star and consider buying me a coffee to keep me fueled and motivated

Buy Me A Coffee