# receive_sharing_intent **Repository Path**: Spring_Cloud_Sell/receive_sharing_intent ## Basic Information - **Project Name**: receive_sharing_intent - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-20 - **Last Updated**: 2026-08-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # receive_sharing_intent [![pub package](https://img.shields.io/pub/v/receive_sharing_intent.svg)](https://pub.dev/packages/receive_sharing_intent) A Flutter plugin that enables flutter apps to receive sharing photos, videos, text, urls or any other file types from another app. Also, supports iOS Share extension and launching the host app automatically. Check the provided [example](./example/lib/main.dart) for more info. | | Android | iOS | |-------------|------------------------|-------------------| | **Support** | SDK 21+ (Kotlin 2.4.0) | 13.0+ (Swift 5.0) | ![Alt Text](./example/demo.gif) # Usage To use this plugin, add `receive_sharing_intent` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). For example: ```yaml dependencies: receive_sharing_intent: ^latest ``` ## Android Add the following filters to your [android/app/src/main/AndroidManifest.xml](./example/android/app/src/main/AndroidManifest.xml): ```xml .... ``` ## iOS #### 1. Create Share Extension - Using Xcode, go to File/New/Target and Choose "Share Extension". - Give it a name, i.e., "Share Extension". Make sure the deployment target for Runner.app and the share extension is the same. #### 2. Replace your [ios/Share Extension/Info.plist](./example/ios/Share%20Extension/Info.plist) with the following: ```xml AppGroupId $(CUSTOM_GROUP_ID) CFBundleVersion $(FLUTTER_BUILD_NUMBER) NSExtension NSExtensionAttributes PHSupportedMediaTypes Video Image NSExtensionActivationRule NSExtensionActivationSupportsText NSExtensionActivationSupportsWebURLWithMaxCount 1 NSExtensionActivationSupportsImageWithMaxCount 100 NSExtensionActivationSupportsMovieWithMaxCount 100 NSExtensionActivationSupportsFileWithMaxCount 1 NSExtensionMainStoryboard MainInterface NSExtensionPointIdentifier com.apple.share-services ``` #### 3. Add the following to your [ios/Runner/Info.plist](./example/ios/Runner/Info.plist): ```xml ... AppGroupId $(CUSTOM_GROUP_ID) CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLSchemes ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER) NSPhotoLibraryUsageDescription To upload photos, please allow permission to access your photo library. ... ``` #### 4. Add the following to your [ios/Runner/Runner.entitlements](./example/ios/Runner/Runner.entitlements): ```xml .... com.apple.developer.associated-domains applinks:example.com .... ``` #### 5. Make the plugin available to the Share Extension (Swift Package Manager) This plugin is distributed as a **Swift Package** (SPM only — there is no CocoaPods podspec). Make sure Swift Package Manager is enabled for your project: ```sh flutter config --enable-swift-package-manager ``` Flutter automatically adds the plugin to your **Runner** target. Your **Share Extension** target also needs access to the `receive_sharing_intent` module (it provides `RSIShareViewController`). Add it in Xcode: * Select the **Share Extension** target → **General** tab. * Under **Frameworks and Libraries**, click **+**. * Choose the **`FlutterGeneratedPluginSwiftPackage`** library from the `receive_sharing_intent` Swift package and add it. > If you previously used CocoaPods, remove the `ios/Podfile` and run > `pod deintegrate` in the `ios/` directory, then remove the > `#include "Pods/..."` lines from `ios/Flutter/Debug.xcconfig`, > `ios/Flutter/Release.xcconfig` and any references to > **`receive-sharing-intent`** in `project.pbxproj`. See the > [example project](./example/ios) for a fully SPM-only setup. #### 6. Add Runner and Share Extension in the same group * Go to `Signing & Capabilities` tab and add App Groups capability in **BOTH** Targets: `Runner` and `Share Extension` * Add a new container with the name of your choice. For example `group.MyContainer` in the example project its `group.com.kasem.ShareExtention` * Add User-defined(`Build Settings -> +`) string `CUSTOM_GROUP_ID` in **BOTH** Targets: `Runner` and `Share Extension` and set value to group id created above. You can use different group ids depends on your flavor schemes #### 7. Go to Build Phases of your Runner target and move `Embed Foundation Extension` to the top of `Thin Binary`. #### 8. Make your `ShareViewController` [ios/Share Extension/ShareViewController.swift](./example/ios/Share%20Extension/ShareViewController.swift) inherit from `RSIShareViewController`: ```swift // If you get no such module 'receive_sharing_intent' error. // Go to Build Phases of your Runner target and // move `Embed Foundation Extension` to the top of `Thin Binary`. import receive_sharing_intent class ShareViewController: RSIShareViewController { // Use this method to return false if you don't want to redirect to host app automatically. // Default is true override func shouldAutoRedirect() -> Bool { return false } } ``` ```xml NSExtensionPrincipalClass $(PRODUCT_MODULE_NAME).ShareViewController ``` The example's **Action Extension** ("Share to RSI") demonstrates this direct-open mode; the **Share Extension** demonstrates the compose-dialog mode. ##### Auto-redirect vs. the built-in compose UI `RSIShareViewController` is a plain `UIViewController` (it no longer subclasses the deprecated `SLComposeServiceViewController`). Its behaviour depends on `shouldAutoRedirect()`: * **`true` (default)** — no UI is shown. The shared content is processed and the extension immediately redirects into your host app. There is no white compose card and no dimmed system sheet behind it. * **`false`** — a built-in compose sheet is shown: a bottom card with a circular close button, a "Send" button, an auto-focused message field (the keyboard comes up automatically), and a thumbnail preview of the first shared item. Tapping the dimmed background cancels the share. You can customise the built-in compose UI by overriding these `open` members: ```swift class ShareViewController: RSIShareViewController { override func shouldAutoRedirect() -> Bool { false } // Placeholder shown in the empty message field. override var placeholder: String { "Add a caption…" } // Title of the confirm button (can be a long label). override var sendButtonTitle: String { "Send to Example" } // Gate the Send button on your own validation. Default: always valid. override func isContentValid() -> Bool { !contentText.isEmpty } // Called when the user taps Send. Default saves the message and redirects. override func didSelectPost() { saveAndRedirect(message: contentText) } // Called when the user taps Cancel / taps the dimmed background. // Default cancels the extension request. override func didSelectCancel() { cancel() } } ``` The typed message is available via `contentText` and is forwarded to your Flutter app as a shared text item. > **Migration note:** the compose UI previously came from the system > `SLComposeServiceViewController`. That API is deprecated, so the plugin now > ships its own equivalent UI (implemented in `RSIComposeView`). The > `contentText`, `isContentValid()` and `didSelectPost()` hooks are preserved. > The old `navigationTitle` and `characterLimit` overrides were removed. #### 9. Adopt `UISceneDelegate` (required for upcoming iOS versions) Newer iOS versions deliver lifecycle events (including shared URLs) through a `UISceneDelegate` instead of the `AppDelegate`. This plugin already adopts the scene lifecycle (it conforms to `FlutterSceneLifeCycleDelegate` and registers itself with `addSceneDelegate`), so it keeps working automatically once your app adopts a scene delegate. Follow Flutter's official [UISceneDelegate migration guide](https://docs.flutter.dev/release/breaking-changes/uiscenedelegate), summarized below. b. Add a `SceneDelegate` that subclasses `FlutterSceneDelegate` (see [example/ios/Runner/SceneDelegate.swift](./example/ios/Runner/SceneDelegate.swift)). For a typical app this can be empty — the plugin handles the shared URLs itself. Only override `scene(_:openURLContexts:)` if your app uses multiple libraries that handle incoming URLs and you need to disambiguate between them: ```swift import Flutter import UIKit import receive_sharing_intent class SceneDelegate: FlutterSceneDelegate { // Optional - only needed when multiple libraries handle incoming URLs. // Called on a cold start when the scene connects. The shared URL (if any) // is delivered here via connectionOptions instead of the launchOptions. override func scene( _ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions ) { // Work-around to prevent other libraries like flutter_branch_sdk from absorbing links meant to be handled by receive_sharing_intent. _ = ReceiveSharingIntentPlugin.instance.scene(scene, willConnectTo: session, options: connectionOptions) super.scene(scene, willConnectTo: session, options: connectionOptions) } // Called while the app is already running (warm start). override func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { // Work-around to prevent other libraries like flutter_branch_sdk from absorbing links meant to be handled by receive_sharing_intent. if ReceiveSharingIntentPlugin.instance.scene(scene, openURLContexts: URLContexts) { return } // Proceed url handling for other Flutter libraries like uni_links super.scene(scene, openURLContexts: URLContexts) } } ``` > This plugin is distributed via Swift Package Manager only, so make sure SPM is > enabled (`flutter config --enable-swift-package-manager`). #### Compiling issues and their fixes * Error: No such module 'receive_sharing_intent' (in the Share Extension) * Fix: Add the `receive-sharing-intent` library to the Share Extension target under **General → Frameworks and Libraries** (see step 5). * Error: Unable to resolve module dependency: 'receive_sharing_intent' * Fix: Ensure Swift Package Manager is enabled and the Share Extension target links the `receive-sharing-intent` Swift package product (see step 5). * Error: Invalid Bundle. The bundle at 'Runner.app/Plugins/Sharing Extension.appex' contains disallowed file 'Frameworks' * Fix: https://stackoverflow.com/a/25789145/2061365 ## Full Example [main.dart](./example/lib/main.dart) ```dart import 'package:flutter/material.dart'; import 'dart:async'; import 'package:receive_sharing_intent/receive_sharing_intent.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { late StreamSubscription _intentSub; final _sharedFiles = []; @override void initState() { super.initState(); // Listen to media sharing coming from outside the app while the app is in the memory. _intentSub = ReceiveSharingIntent.instance.getMediaStream().listen((value) { setState(() { _sharedFiles.clear(); _sharedFiles.addAll(value); print(_sharedFiles.map((f) => f.toMap())); }); }, onError: (err) { print("getIntentDataStream error: $err"); }); // Get the media sharing coming from outside the app while the app is closed. ReceiveSharingIntent.instance.getInitialMedia().then((value) { setState(() { _sharedFiles.clear(); _sharedFiles.addAll(value); print(_sharedFiles.map((f) => f.toMap())); // Tell the library that we are done processing the intent. ReceiveSharingIntent.instance.reset(); }); }); } @override void dispose() { _intentSub.cancel(); super.dispose(); } @override Widget build(BuildContext context) { const textStyleBold = const TextStyle(fontWeight: FontWeight.bold); return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Plugin example app'), ), body: Center( child: Column( children: [ Text("Shared files:", style: textStyleBold), Text(_sharedFiles .map((f) => f.toMap()) .join(",\n****************\n")), ], ), ), ), ); } } ```