UNPKG

expo-sharing

Version:

Provides a way to share files directly with other compatible applications.

133 lines (118 loc) 4.56 kB
import { ConfigPlugin, createRunOncePlugin, StaticPlugin, withPlugins } from '@expo/config-plugins'; import { parseIntentFilters } from './android/parseIntentFilters'; import { withAndroidIntentFilters } from './android/withAndroidIntentFilters'; import { withShareIntoSchemeString } from './android/withShareIntoSchemeString'; import { ShareExtensionFiles } from './ios/setupShareExtensionFiles'; import { withAppGroupId } from './ios/withAppGroupId'; import withIosWarning from './ios/withIosWarning'; import { withShareExtensionFiles } from './ios/withShareExtensionFiles'; import { withShareExtensionXcodeProject } from './ios/withShareExtensionXcodeProject'; import { ShareExtensionConfigPluginProps } from './sharingPlugin.types'; import { withConfig } from './withConfig'; const EXPO_SHARE_EXTENSION_TARGET_NAME = 'expo-sharing-extension'; const pkg = require('../../package.json'); type ShareExtensionConfigPlugin = ConfigPlugin<ShareExtensionConfigPluginProps>; const withShareExtension: ShareExtensionConfigPlugin = (config, props?) => { let plugins: (StaticPlugin | ConfigPlugin | string)[] = []; const iosEnabled = props?.ios?.enabled ?? false; const androidEnabled = props?.android?.enabled ?? false; if (iosEnabled) { const deploymentTarget = '16.4'; const bundleIdentifier = config.ios?.bundleIdentifier; if (!bundleIdentifier) { throw new Error( "The application config doesn't define a bundle identifier. Make sure that `ios.bundleIdentifier` field has a value." ); } const extensionBundleIdentifier = props?.ios?.extensionBundleIdentifier ?? `${config.ios?.bundleIdentifier}.${EXPO_SHARE_EXTENSION_TARGET_NAME}`; const fallbackAppGroupId = `group.${bundleIdentifier}`; const appGroupId = props?.ios?.appGroupId ?? fallbackAppGroupId; const urlScheme = config.scheme ?? bundleIdentifier; const activationRule = props?.ios?.activationRule ?? { supportsText: true, supportsWebUrlWithMaxCount: 1, }; if (!urlScheme) { throw new Error( `Expo sharing: The app doesn't define a scheme or a bundle identifier. Define at least one of those properties in app json` ); } if (!props?.ios?.appGroupId) { plugins.push([ withIosWarning, { property: 'appGroupId', warning: `Expo sharing: Using the default ${fallbackAppGroupId} app group id. If you are using EAS Build` + ` no further steps are required, otherwise make sure that this app group is registered` + ` with your Apple development team, or set \`ios.appGroupId\` field to an already registered app group.`, }, ]); } const shareExtensionFiles: ShareExtensionFiles = {} as ShareExtensionFiles; plugins = [ ...plugins, [ withConfig, { bundleIdentifier: extensionBundleIdentifier, targetName: EXPO_SHARE_EXTENSION_TARGET_NAME, groupIdentifier: appGroupId, }, ], [withAppGroupId, appGroupId], [ withShareExtensionFiles, { targetName: EXPO_SHARE_EXTENSION_TARGET_NAME, appGroupId, urlScheme, activationRule, onFilesWritten: (writtenFiles: ShareExtensionFiles) => { Object.assign(shareExtensionFiles, writtenFiles); }, }, ], [ withShareExtensionXcodeProject, { targetName: EXPO_SHARE_EXTENSION_TARGET_NAME, bundleIdentifier: extensionBundleIdentifier, deploymentTarget, activationRule, shareExtensionFiles, }, ], ]; } if (androidEnabled) { const urlScheme = config.scheme ?? config.android?.package; if (!urlScheme) { throw new Error( "The application config doesn't define a scheme or an Android package. Define the scheme in the app config." ); } const singleIntentFilter = parseIntentFilters( props?.android?.singleShareMimeTypes ?? [], 'single' ); const multiIntentFilter = parseIntentFilters( props?.android?.multipleShareMimeTypes ?? [], 'multiple' ); plugins = [ ...plugins, [ withAndroidIntentFilters, { intentFilters: [singleIntentFilter, multiIntentFilter], }, ], [withShareIntoSchemeString, urlScheme], ]; } return withPlugins(config, plugins); }; export default createRunOncePlugin(withShareExtension, pkg.name, pkg.version);