---
description: Capacitor plugin to receive content such as text, links, and files from other apps. Available for Android, iOS, and Web.
title: Capacitor Share Target Plugin for Android, iOS & Web - Capawesome
image: https://capawesome.io/docs/assets/images/social/plugins/share-target.png
---

[ Skip to content](#capawesome-teamcapacitor-share-target) 

[ 🎉 Introducing **Capawesome Platform** — one platform for Live Updates, Native Builds, App Store Publishing, and Insider SDKs.](https://capawesome.io) 

* [  Formbricks ](/docs/plugins/formbricks/)
* [  Geocoder ](/docs/plugins/geocoder/)
* [  Google Sign-In ](/docs/plugins/google-sign-in/)
* [  libSQL ](/docs/plugins/libsql/)
* [  Live Update ](/docs/plugins/live-update/)
* [  Managed Configurations ](/docs/plugins/managed-configurations/)
* [  Media Session ](/docs/plugins/media-session/)
* [  ML Kit ](/docs/plugins/mlkit/)
* [  NFC ](/docs/plugins/nfc/)
* [  OAuth ](/docs/plugins/oauth/)
* [  Pedometer ](/docs/plugins/pedometer/)
* [  Photo Editor ](/docs/plugins/photo-editor/)
* [  PostHog ](/docs/plugins/posthog/)
* [  Printer ](/docs/plugins/printer/)
* [  Purchases ](/docs/plugins/purchases/)
* [  RealtimeKit ](/docs/plugins/realtimekit/)
* [  Screen Orientation ](/docs/plugins/screen-orientation/)
* [  Screenshot ](/docs/plugins/screenshot/)
* [  Secure Preferences ](/docs/plugins/secure-preferences/)
* [  Speech Recognition ](/docs/plugins/speech-recognition/)
* [  Speech Synthesis ](/docs/plugins/speech-synthesis/)
* Share Target [  Share Target ](/docs/plugins/share-target/)
* [  iOS ](#ios)
* [  Configuration ](#configuration)
* [  Web ](#web)
* [  Usage ](#usage)
* [  API ](#api)
* [  Troubleshooting ](#troubleshooting)
* [  Changelog ](#changelog)
* [  Breaking Changes ](#breaking-changes)
* [  License ](#license)
* [  Square Mobile Payments ](/docs/plugins/square-mobile-payments/)
* [  SQLite ](/docs/plugins/sqlite/)
* [  Superwall ](/docs/plugins/superwall/)
* [  Torch ](/docs/plugins/torch/)
* [  Wifi ](/docs/plugins/wifi/)
* [  Zip ](/docs/plugins/zip/)
* [  Cloud ](/docs/cloud/)
* [  Live Updates ](/docs/cloud/live-updates/)
* Advanced
* Integrations
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Configuration ](/docs/cloud/native-builds/configuration/)
* [  Environments ](/docs/cloud/native-builds/environments/)
* Guides
* [  Sample Projects ](/docs/cloud/native-builds/sample-projects/)
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  Automations ](/docs/cloud/automations/)
* [  Assist ](/docs/cloud/assist/)
* Account
* Organizations
* [  Organization and User Management ](/docs/cloud/organizations/memberships/)
* [  Single Sign-On (SSO) ](/docs/cloud/organizations/sso/)
* [  Teams ](/docs/cloud/organizations/teams/)
* [  Two-Factor Authentication ](/docs/cloud/organizations/two-factor-authentication/)
* [  Integrations ](/docs/cloud/integrations/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Pricing ](https://capawesome.io/pricing/)
* [  FAQ ](/docs/cloud/faq/)
* [  Support ](/docs/cloud/support/)
* [  Contributing ](/docs/contributing/)
* [  LLMs ](/docs/llms/)
* [  Insiders ](/docs/insiders/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/insiders/support/)
* [  FAQ ](/docs/insiders/faq/)
* [  Blog ](/blog/)
* Categories

* [  iOS ](#ios)
* [  Configuration ](#configuration)
* [  Web ](#web)
* [  Usage ](#usage)
* [  API ](#api)
* [  Troubleshooting ](#troubleshooting)
* [  Changelog ](#changelog)
* [  Breaking Changes ](#breaking-changes)
* [  License ](#license)

# @capawesome-team/capacitor-share-target[¶](#capawesome-teamcapacitor-share-target "Permanent link")

Capacitor plugin to receive content such as text, links, and files from other apps.

[ ![Deliver Live Updates to your Capacitor app with Capawesome Cloud](../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## Features[¶](#features "Permanent link")

We are proud to offer one of the most complete and feature-rich Capacitor plugins for receiving content from other apps. Here are some of the key features:

* 🖥️ **Cross-platform**: Supports Android, iOS and Web.
* 📝 **Multi-content types**: Handle text, URLs, images, videos, and files.
* 🌐 **Web Share Target API**: Leverage the native sharing capabilities of the web.
* 📦 **Large File Support**: Efficient file caching without memory limitations.
* 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
* 🔁 **Up-to-date**: Always supports the latest Capacitor version.
* ⭐️ **Support**: Priority support from the Capawesome Team.
* ✨ **Handcrafted**: Built from the ground up with care and expertise, not forked or AI-generated.

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Newsletter[¶](#newsletter "Permanent link")

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).

## Compatibility[¶](#compatibility "Permanent link")

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 8.x.x          | \>=8.x.x          | Active support |
| 0.2.x          | 7.x.x             | Deprecated     |

## Demo[¶](#demo "Permanent link")

A working example can be found [here](https://github.com/capawesome-team/capacitor-share-target-demo).

| Android                                                                                           | iOS                                                                                       | Web                                                                                       |
| ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| ![Android Demo](https://capawesome.io/docs/assets/images/gifs/capacitor-share-target-android.gif) | ![iOS Demo](https://capawesome.io/docs/assets/images/gifs/capacitor-share-target-ios.gif) | ![Web Demo](https://capawesome.io/docs/assets/images/gifs/capacitor-share-target-web.gif) |

## Installation[¶](#installation "Permanent link")

This plugin is only available to [Capawesome Insiders](https://capawesome.io/insiders/). First, make sure you have the Capawesome npm registry set up. You can do this by running the following commands:

`[](#%5F%5Fcodelineno-0-1)npm config set @capawesome-team:registry https://npm.registry.capawesome.io
[](#%5F%5Fcodelineno-0-2)npm config set //npm.registry.capawesome.io/:_authToken <YOUR_LICENSE_KEY>
`

**Attention**: Replace `<YOUR_LICENSE_KEY>` with the license key you received from Polar. If you don't have a license key yet, you can get one by becoming a [Capawesome Insider](https://capawesome.io/insiders/).

Next, you can use our **AI-Assisted Setup** to install the plugin. Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

`[](#%5F%5Fcodelineno-1-1)npx skills add capawesome-team/skills --skill capacitor-plugins
`

Then use the following prompt:

`` [](#%5F%5Fcodelineno-2-1)Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome-team/capacitor-share-target` plugin in my project.
 ``

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

`[](#%5F%5Fcodelineno-3-1)npm install @capawesome-team/capacitor-share-target
[](#%5F%5Fcodelineno-3-2)npx cap sync
`

### Android[¶](#android "Permanent link")

#### Intent Filters[¶](#intent-filters "Permanent link")

To enable your app to receive shared content from other apps, you need to add intent filters to your main activity in `AndroidManifest.xml` (usually `android/app/src/main/AndroidManifest.xml`).

For example, to handle text, URLs, and other text-based content, add the following intent filter:

`[](#%5F%5Fcodelineno-4-1)<intent-filter>
[](#%5F%5Fcodelineno-4-2)    <action android:name="android.intent.action.SEND" />
[](#%5F%5Fcodelineno-4-3)    <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-4-4)    <data android:mimeType="text/plain" />
[](#%5F%5Fcodelineno-4-5)</intent-filter>
`

To handle a single image, add the following intent filter:

`[](#%5F%5Fcodelineno-5-1)<intent-filter>
[](#%5F%5Fcodelineno-5-2)    <action android:name="android.intent.action.SEND" />
[](#%5F%5Fcodelineno-5-3)    <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-5-4)    <data android:mimeType="image/*" />
[](#%5F%5Fcodelineno-5-5)</intent-filter>
`

To handle multiple images, add the following intent filter:

`[](#%5F%5Fcodelineno-6-1)<intent-filter>
[](#%5F%5Fcodelineno-6-2)    <action android:name="android.intent.action.SEND_MULTIPLE" />
[](#%5F%5Fcodelineno-6-3)    <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-6-4)    <data android:mimeType="image/*" />
[](#%5F%5Fcodelineno-6-5)</intent-filter>
`

You can also add additional intent filters for other MIME types as needed, such as `application/pdf` for PDF files or `video/*` for videos.

**Attention**: Make sure to add these intent filters inside the `<activity>` tag of your main activity, typically `MainActivity`. Also, make sure the activity has the `android:exported="true"` attribute set, which allows other apps to send intents to it. The `android:launchMode="singleTask"` attribute is recommended to prevent multiple instances of your app from being created when receiving shared content.

Here's an example of how your `AndroidManifest.xml` might look like:

`[](#%5F%5Fcodelineno-7-1)<activity
[](#%5F%5Fcodelineno-7-2)    android:name=".MainActivity"
[](#%5F%5Fcodelineno-7-3)    android:exported="true"
[](#%5F%5Fcodelineno-7-4)    android:launchMode="singleTask">
[](#%5F%5Fcodelineno-7-5)    <intent-filter>
[](#%5F%5Fcodelineno-7-6)        <action android:name="android.intent.action.SEND" />
[](#%5F%5Fcodelineno-7-7)        <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-7-8)        <data android:mimeType="text/plain" />
[](#%5F%5Fcodelineno-7-9)    </intent-filter>
[](#%5F%5Fcodelineno-7-10)    <intent-filter>
[](#%5F%5Fcodelineno-7-11)        <action android:name="android.intent.action.SEND" />
[](#%5F%5Fcodelineno-7-12)        <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-7-13)        <data android:mimeType="image/*" />
[](#%5F%5Fcodelineno-7-14)    </intent-filter>
[](#%5F%5Fcodelineno-7-15)    <intent-filter>
[](#%5F%5Fcodelineno-7-16)        <action android:name="android.intent.action.SEND" />
[](#%5F%5Fcodelineno-7-17)        <category android:name="android.intent.category.DEFAULT" />
[](#%5F%5Fcodelineno-7-18)        <data android:mimeType="video/*" />
[](#%5F%5Fcodelineno-7-19)    </intent-filter>
[](#%5F%5Fcodelineno-7-20)</activity>
`

#### Proguard[¶](#proguard "Permanent link")

If you are using Proguard, you need to add the following rules to your `proguard-rules.pro` file:

`[](#%5F%5Fcodelineno-8-1)-keep class io.capawesome.capacitorjs.plugins.** { *; }
`

#### Variables[¶](#variables "Permanent link")

If needed, you can define the following project variable in your app's `variables.gradle` file to change the default version of the dependency:

* `$androidxExifInterfaceVersion` version of `androidx.exifinterface:exifinterface` (default: `1.4.2`)

This can be useful if you encounter dependency conflicts with other plugins in your project.

### iOS[¶](#ios "Permanent link")

On iOS, it's not possible to receive shared content directly in the main app. Instead, you need to create a share extension that can handle the shared content and then communicate it back to your main app. This involves setting up a URL scheme and configuring the share extension to handle the shared content. The communication between the share extension and the main app is done using URL schemes, which allows the share extension to open the main app with the shared content as parameters in the URL.

#### URL Scheme[¶](#url-scheme "Permanent link")

To enable your app to be opened by the share extension, you need to set up a URL scheme in your iOS app. This is done by adding a URL type in your app's `Info.plist` file. Add the following code to your `Info.plist` file:

`[](#%5F%5Fcodelineno-9-1)<key>CFBundleURLTypes</key>
[](#%5F%5Fcodelineno-9-2)<array>
[](#%5F%5Fcodelineno-9-3)    <dict>
[](#%5F%5Fcodelineno-9-4)        <key>CFBundleURLSchemes</key>
[](#%5F%5Fcodelineno-9-5)        <array>
[](#%5F%5Fcodelineno-9-6)            <string>YOUR_URL_SCHEME</string>
[](#%5F%5Fcodelineno-9-7)        </array>
[](#%5F%5Fcodelineno-9-8)    </dict>
[](#%5F%5Fcodelineno-9-9)</array>
`

**Attention**: Replace `YOUR_URL_SCHEME` with your desired URL scheme (e.g. `myapp`). This will allow your app to be opened with URLs like `myapp://?text=Hello%20World`.

#### Share Extension[¶](#share-extension "Permanent link")

To enable your app to receive shared content from other apps on iOS, you need to create a share extension. First, you need to add a new target to your Xcode project:

1. Open your Xcode project.
2. Go to `File` \> `New` \> `Target...`.
3. Select `Share Extension` from the list of templates.
4. Name your extension `AppShare` and click `Finish`.

This will create a new target in your Xcode project with the necessary files for a share extension. If you see a prompt to activate the new scheme, choose "Don't Activate". There is one file called `MainInterface.storyboard` that you should delete **via Xcode**, as we will not need it.

After this, you need to configure the share extension to handle the shared content. Open the `Info.plist` file of your share extension **in a text editor of your choice** and replace its content with the following:

`[](#%5F%5Fcodelineno-10-1)<?xml version="1.0" encoding="UTF-8"?>
[](#%5F%5Fcodelineno-10-2)<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
[](#%5F%5Fcodelineno-10-3)<plist version="1.0">
[](#%5F%5Fcodelineno-10-4)<dict>
[](#%5F%5Fcodelineno-10-5)    <key>NSExtension</key>
[](#%5F%5Fcodelineno-10-6)    <dict>
[](#%5F%5Fcodelineno-10-7)        <key>NSExtensionAttributes</key>
[](#%5F%5Fcodelineno-10-8)        <dict>
[](#%5F%5Fcodelineno-10-9)            <key>NSExtensionActivationRule</key>
[](#%5F%5Fcodelineno-10-10)            <dict>
[](#%5F%5Fcodelineno-10-11)                <key>NSExtensionActivationDictionaryVersion</key>
[](#%5F%5Fcodelineno-10-12)                <integer>2</integer>
[](#%5F%5Fcodelineno-10-13)                <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
[](#%5F%5Fcodelineno-10-14)                <integer>1</integer>
[](#%5F%5Fcodelineno-10-15)                <key>NSExtensionActivationSupportsText</key>
[](#%5F%5Fcodelineno-10-16)                <true/>
[](#%5F%5Fcodelineno-10-17)                <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
[](#%5F%5Fcodelineno-10-18)                <integer>10</integer>
[](#%5F%5Fcodelineno-10-19)                <key>NSExtensionActivationSupportsFileWithMaxCount</key>
[](#%5F%5Fcodelineno-10-20)                <integer>10</integer>
[](#%5F%5Fcodelineno-10-21)                <key>NSExtensionActivationSupportsImageWithMaxCount</key>
[](#%5F%5Fcodelineno-10-22)                <integer>10</integer>
[](#%5F%5Fcodelineno-10-23)                <key>NSExtensionActivationSupportsMovieWithMaxCount</key>
[](#%5F%5Fcodelineno-10-24)                <integer>10</integer>
[](#%5F%5Fcodelineno-10-25)                <key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
[](#%5F%5Fcodelineno-10-26)                <integer>1</integer>
[](#%5F%5Fcodelineno-10-27)            </dict>
[](#%5F%5Fcodelineno-10-28)        </dict>
[](#%5F%5Fcodelineno-10-29)        <key>NSExtensionPrincipalClass</key>
[](#%5F%5Fcodelineno-10-30)        <string>AppShare.ShareViewController</string>
[](#%5F%5Fcodelineno-10-31)        <key>NSExtensionPointIdentifier</key>
[](#%5F%5Fcodelineno-10-32)        <string>com.apple.share-services</string>
[](#%5F%5Fcodelineno-10-33)    </dict>
[](#%5F%5Fcodelineno-10-34)</dict>
[](#%5F%5Fcodelineno-10-35)</plist>
`

Feel free to adjust the `NSExtensionActivationRule` keys to match the types of content you want to support. The example above supports text, web URLs, files, images, and movies.

Next, you need to update the `ShareViewController.swift` file in your share extension target and replace its content with the following code:

`[](#%5F%5Fcodelineno-11-1)import MobileCoreServices
[](#%5F%5Fcodelineno-11-2)import Social
[](#%5F%5Fcodelineno-11-3)import UIKit
[](#%5F%5Fcodelineno-11-4)import UniformTypeIdentifiers
[](#%5F%5Fcodelineno-11-5)
[](#%5F%5Fcodelineno-11-6)struct SharedFileData {
[](#%5F%5Fcodelineno-11-7)    let uri: String
[](#%5F%5Fcodelineno-11-8)    let name: String?
[](#%5F%5Fcodelineno-11-9)    let mimeType: String?
[](#%5F%5Fcodelineno-11-10)}
[](#%5F%5Fcodelineno-11-11)
[](#%5F%5Fcodelineno-11-12)class ShareViewController: UIViewController {
[](#%5F%5Fcodelineno-11-13)    private let appGroupIdentifier = "group.<YOUR_APP_IDENTIFIER>"
[](#%5F%5Fcodelineno-11-14)    private let urlScheme = "<YOUR_URL_SCHEME>"
[](#%5F%5Fcodelineno-11-15)
[](#%5F%5Fcodelineno-11-16)    override func viewDidAppear(_ animated: Bool) {
[](#%5F%5Fcodelineno-11-17)        super.viewDidAppear(animated)
[](#%5F%5Fcodelineno-11-18)        self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
[](#%5F%5Fcodelineno-11-19)    }
[](#%5F%5Fcodelineno-11-20)
[](#%5F%5Fcodelineno-11-21)    override func viewDidLoad() {
[](#%5F%5Fcodelineno-11-22)        super.viewDidLoad()
[](#%5F%5Fcodelineno-11-23)        Task {
[](#%5F%5Fcodelineno-11-24)            processSharedContent()
[](#%5F%5Fcodelineno-11-25)        }
[](#%5F%5Fcodelineno-11-26)    }
[](#%5F%5Fcodelineno-11-27)
[](#%5F%5Fcodelineno-11-28)    private func openURL(_ url: URL) {
[](#%5F%5Fcodelineno-11-29)        var responder: UIResponder? = self
[](#%5F%5Fcodelineno-11-30)        while responder != nil {
[](#%5F%5Fcodelineno-11-31)            if let application = responder as? UIApplication {
[](#%5F%5Fcodelineno-11-32)                application.open(url, options: [:], completionHandler: nil)
[](#%5F%5Fcodelineno-11-33)                return
[](#%5F%5Fcodelineno-11-34)            }
[](#%5F%5Fcodelineno-11-35)            responder = responder?.next
[](#%5F%5Fcodelineno-11-36)        }
[](#%5F%5Fcodelineno-11-37)    }
[](#%5F%5Fcodelineno-11-38)
[](#%5F%5Fcodelineno-11-39)    private func sharedContainerURL(for fileName: String) -> URL? {
[](#%5F%5Fcodelineno-11-40)        guard let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier) else {
[](#%5F%5Fcodelineno-11-41)            return nil
[](#%5F%5Fcodelineno-11-42)        }
[](#%5F%5Fcodelineno-11-43)        return containerURL.appendingPathComponent(fileName)
[](#%5F%5Fcodelineno-11-44)    }
[](#%5F%5Fcodelineno-11-45)
[](#%5F%5Fcodelineno-11-46)    private func removeFileIfExists(at url: URL) throws {
[](#%5F%5Fcodelineno-11-47)        if FileManager.default.fileExists(atPath: url.path) {
[](#%5F%5Fcodelineno-11-48)            try FileManager.default.removeItem(at: url)
[](#%5F%5Fcodelineno-11-49)        }
[](#%5F%5Fcodelineno-11-50)    }
[](#%5F%5Fcodelineno-11-51)
[](#%5F%5Fcodelineno-11-52)    private func copyFileToSharedContainer(_ sourceURL: URL) -> String? {
[](#%5F%5Fcodelineno-11-53)        let fileName = sourceURL.lastPathComponent
[](#%5F%5Fcodelineno-11-54)        guard let destinationURL = sharedContainerURL(for: fileName) else {
[](#%5F%5Fcodelineno-11-55)            return nil
[](#%5F%5Fcodelineno-11-56)        }
[](#%5F%5Fcodelineno-11-57)
[](#%5F%5Fcodelineno-11-58)        do {
[](#%5F%5Fcodelineno-11-59)            try removeFileIfExists(at: destinationURL)
[](#%5F%5Fcodelineno-11-60)            try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
[](#%5F%5Fcodelineno-11-61)            return destinationURL.absoluteString
[](#%5F%5Fcodelineno-11-62)        } catch {
[](#%5F%5Fcodelineno-11-63)            print("Error copying file to shared container: \(error)")
[](#%5F%5Fcodelineno-11-64)            return nil
[](#%5F%5Fcodelineno-11-65)        }
[](#%5F%5Fcodelineno-11-66)    }
[](#%5F%5Fcodelineno-11-67)
[](#%5F%5Fcodelineno-11-68)    private func copyImageToSharedContainerWithFixedOrientation(_ sourceURL: URL) -> String? {
[](#%5F%5Fcodelineno-11-69)        let fileName = sourceURL.lastPathComponent
[](#%5F%5Fcodelineno-11-70)        guard let destinationURL = sharedContainerURL(for: fileName) else {
[](#%5F%5Fcodelineno-11-71)            return nil
[](#%5F%5Fcodelineno-11-72)        }
[](#%5F%5Fcodelineno-11-73)
[](#%5F%5Fcodelineno-11-74)        do {
[](#%5F%5Fcodelineno-11-75)            try removeFileIfExists(at: destinationURL)
[](#%5F%5Fcodelineno-11-76)
[](#%5F%5Fcodelineno-11-77)            if let fixedImageData = loadImageDataWithFixedOrientation(from: sourceURL) {
[](#%5F%5Fcodelineno-11-78)                try fixedImageData.write(to: destinationURL)
[](#%5F%5Fcodelineno-11-79)            } else {
[](#%5F%5Fcodelineno-11-80)                try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
[](#%5F%5Fcodelineno-11-81)            }
[](#%5F%5Fcodelineno-11-82)
[](#%5F%5Fcodelineno-11-83)            return destinationURL.absoluteString
[](#%5F%5Fcodelineno-11-84)        } catch {
[](#%5F%5Fcodelineno-11-85)            print("Error copying image to shared container: \(error)")
[](#%5F%5Fcodelineno-11-86)            return nil
[](#%5F%5Fcodelineno-11-87)        }
[](#%5F%5Fcodelineno-11-88)    }
[](#%5F%5Fcodelineno-11-89)
[](#%5F%5Fcodelineno-11-90)    private func loadImageDataWithFixedOrientation(from url: URL) -> Data? {
[](#%5F%5Fcodelineno-11-91)        guard let source = CGImageSourceCreateWithURL(url as CFURL, nil),
[](#%5F%5Fcodelineno-11-92)              let cgImage = CGImageSourceCreateImageAtIndex(source, 0, nil) else {
[](#%5F%5Fcodelineno-11-93)            return nil
[](#%5F%5Fcodelineno-11-94)        }
[](#%5F%5Fcodelineno-11-95)
[](#%5F%5Fcodelineno-11-96)        let uiImage = UIImage(cgImage: cgImage)
[](#%5F%5Fcodelineno-11-97)        let fixedImage = normalizeImageOrientation(uiImage)
[](#%5F%5Fcodelineno-11-98)
[](#%5F%5Fcodelineno-11-99)        let fileExtension = url.pathExtension.lowercased()
[](#%5F%5Fcodelineno-11-100)        if fileExtension == "jpg" || fileExtension == "jpeg" {
[](#%5F%5Fcodelineno-11-101)            return fixedImage.jpegData(compressionQuality: 0.9)
[](#%5F%5Fcodelineno-11-102)        } else {
[](#%5F%5Fcodelineno-11-103)            return fixedImage.pngData()
[](#%5F%5Fcodelineno-11-104)        }
[](#%5F%5Fcodelineno-11-105)    }
[](#%5F%5Fcodelineno-11-106)
[](#%5F%5Fcodelineno-11-107)
[](#%5F%5Fcodelineno-11-108)
[](#%5F%5Fcodelineno-11-109)    private func normalizeImageOrientation(_ image: UIImage) -> UIImage {
[](#%5F%5Fcodelineno-11-110)        if let fixedImage = image.fixedOrientation() {
[](#%5F%5Fcodelineno-11-111)            return fixedImage
[](#%5F%5Fcodelineno-11-112)        }
[](#%5F%5Fcodelineno-11-113)
[](#%5F%5Fcodelineno-11-114)        return image
[](#%5F%5Fcodelineno-11-115)    }
[](#%5F%5Fcodelineno-11-116)
[](#%5F%5Fcodelineno-11-117)    private func extractFileMetadata(from url: URL) -> (name: String, mimeType: String?) {
[](#%5F%5Fcodelineno-11-118)        let fileName = url.lastPathComponent
[](#%5F%5Fcodelineno-11-119)        let mimeType = getMimeType(from: url)
[](#%5F%5Fcodelineno-11-120)        return (fileName, mimeType.isEmpty ? nil : mimeType)
[](#%5F%5Fcodelineno-11-121)    }
[](#%5F%5Fcodelineno-11-122)
[](#%5F%5Fcodelineno-11-123)    private func getMimeType(from url: URL) -> String {
[](#%5F%5Fcodelineno-11-124)        let fileExtension = url.pathExtension as CFString
[](#%5F%5Fcodelineno-11-125)        guard let extUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, nil)?.takeUnretainedValue() else {
[](#%5F%5Fcodelineno-11-126)            return ""
[](#%5F%5Fcodelineno-11-127)        }
[](#%5F%5Fcodelineno-11-128)        guard let mimeUTI = UTTypeCopyPreferredTagWithClass(extUTI, kUTTagClassMIMEType) else {
[](#%5F%5Fcodelineno-11-129)            return ""
[](#%5F%5Fcodelineno-11-130)        }
[](#%5F%5Fcodelineno-11-131)        return mimeUTI.takeRetainedValue() as String
[](#%5F%5Fcodelineno-11-132)    }
[](#%5F%5Fcodelineno-11-133)
[](#%5F%5Fcodelineno-11-134)    private func buildAppURL(textValues: [String], fileValues: [SharedFileData], title: String) -> URL {
[](#%5F%5Fcodelineno-11-135)        var urlComponents = URLComponents(string: "\(urlScheme)://?")!
[](#%5F%5Fcodelineno-11-136)        var queryItems: [URLQueryItem] = []
[](#%5F%5Fcodelineno-11-137)
[](#%5F%5Fcodelineno-11-138)        if !title.isEmpty {
[](#%5F%5Fcodelineno-11-139)            queryItems.append(URLQueryItem(name: "title", value: title))
[](#%5F%5Fcodelineno-11-140)        }
[](#%5F%5Fcodelineno-11-141)
[](#%5F%5Fcodelineno-11-142)        queryItems.append(contentsOf: textValues.filter { !$0.isEmpty }.map {
[](#%5F%5Fcodelineno-11-143)            URLQueryItem(name: "text", value: $0)
[](#%5F%5Fcodelineno-11-144)        })
[](#%5F%5Fcodelineno-11-145)
[](#%5F%5Fcodelineno-11-146)        for (index, file) in fileValues.enumerated() {
[](#%5F%5Fcodelineno-11-147)            queryItems.append(URLQueryItem(name: "fileUri\(index)", value: file.uri))
[](#%5F%5Fcodelineno-11-148)            if let name = file.name {
[](#%5F%5Fcodelineno-11-149)                queryItems.append(URLQueryItem(name: "fileName\(index)", value: name))
[](#%5F%5Fcodelineno-11-150)            }
[](#%5F%5Fcodelineno-11-151)            if let mimeType = file.mimeType {
[](#%5F%5Fcodelineno-11-152)                queryItems.append(URLQueryItem(name: "fileMimeType\(index)", value: mimeType))
[](#%5F%5Fcodelineno-11-153)            }
[](#%5F%5Fcodelineno-11-154)        }
[](#%5F%5Fcodelineno-11-155)
[](#%5F%5Fcodelineno-11-156)        urlComponents.queryItems = queryItems.isEmpty ? nil : queryItems
[](#%5F%5Fcodelineno-11-157)        return urlComponents.url!
[](#%5F%5Fcodelineno-11-158)    }
[](#%5F%5Fcodelineno-11-159)
[](#%5F%5Fcodelineno-11-160)    private func sendData(with textValues: [String], fileValues: [SharedFileData], title: String) {
[](#%5F%5Fcodelineno-11-161)        let url = buildAppURL(textValues: textValues, fileValues: fileValues, title: title)
[](#%5F%5Fcodelineno-11-162)        openURL(url)
[](#%5F%5Fcodelineno-11-163)    }
[](#%5F%5Fcodelineno-11-164)
[](#%5F%5Fcodelineno-11-165)    private func processImageAttachment(_ attachment: NSItemProvider, dispatchGroup: DispatchGroup, completion: @escaping (SharedFileData?) -> Void) {
[](#%5F%5Fcodelineno-11-166)        dispatchGroup.enter()
[](#%5F%5Fcodelineno-11-167)        attachment.loadItem(forTypeIdentifier: UTType.image.identifier, options: nil) { [weak self] (item, _) in
[](#%5F%5Fcodelineno-11-168)            defer { dispatchGroup.leave() }
[](#%5F%5Fcodelineno-11-169)            guard let self = self else { 
[](#%5F%5Fcodelineno-11-170)                completion(nil)
[](#%5F%5Fcodelineno-11-171)                return 
[](#%5F%5Fcodelineno-11-172)            }
[](#%5F%5Fcodelineno-11-173)
[](#%5F%5Fcodelineno-11-174)            if let url = item as? URL {
[](#%5F%5Fcodelineno-11-175)                if let sharedPath = self.copyImageToSharedContainerWithFixedOrientation(url) {
[](#%5F%5Fcodelineno-11-176)                    let metadata = self.extractFileMetadata(from: url)
[](#%5F%5Fcodelineno-11-177)                    completion(SharedFileData(uri: sharedPath, name: metadata.name, mimeType: metadata.mimeType))
[](#%5F%5Fcodelineno-11-178)                    return
[](#%5F%5Fcodelineno-11-179)                }
[](#%5F%5Fcodelineno-11-180)            } else if let image = item as? UIImage {
[](#%5F%5Fcodelineno-11-181)                let fixedImage = self.normalizeImageOrientation(image)
[](#%5F%5Fcodelineno-11-182)                if let data = fixedImage.pngData() {
[](#%5F%5Fcodelineno-11-183)                    let base64String = data.base64EncodedString()
[](#%5F%5Fcodelineno-11-184)                    completion(SharedFileData(uri: "data:image/png;base64,\(base64String)", name: nil, mimeType: "image/png"))
[](#%5F%5Fcodelineno-11-185)                    return
[](#%5F%5Fcodelineno-11-186)                }
[](#%5F%5Fcodelineno-11-187)            }
[](#%5F%5Fcodelineno-11-188)
[](#%5F%5Fcodelineno-11-189)            completion(nil)
[](#%5F%5Fcodelineno-11-190)        }
[](#%5F%5Fcodelineno-11-191)    }
[](#%5F%5Fcodelineno-11-192)
[](#%5F%5Fcodelineno-11-193)    private func processMovieAttachment(_ attachment: NSItemProvider, dispatchGroup: DispatchGroup, completion: @escaping (SharedFileData?) -> Void) {
[](#%5F%5Fcodelineno-11-194)        dispatchGroup.enter()
[](#%5F%5Fcodelineno-11-195)        attachment.loadItem(forTypeIdentifier: UTType.movie.identifier, options: nil) { [weak self] (item, _) in
[](#%5F%5Fcodelineno-11-196)            defer { dispatchGroup.leave() }
[](#%5F%5Fcodelineno-11-197)            guard let self = self else { 
[](#%5F%5Fcodelineno-11-198)                completion(nil)
[](#%5F%5Fcodelineno-11-199)                return 
[](#%5F%5Fcodelineno-11-200)            }
[](#%5F%5Fcodelineno-11-201)
[](#%5F%5Fcodelineno-11-202)            if let url = item as? URL {
[](#%5F%5Fcodelineno-11-203)                if let sharedPath = self.copyFileToSharedContainer(url) {
[](#%5F%5Fcodelineno-11-204)                    let metadata = self.extractFileMetadata(from: url)
[](#%5F%5Fcodelineno-11-205)                    completion(SharedFileData(uri: sharedPath, name: metadata.name, mimeType: metadata.mimeType))
[](#%5F%5Fcodelineno-11-206)                    return
[](#%5F%5Fcodelineno-11-207)                }
[](#%5F%5Fcodelineno-11-208)            }
[](#%5F%5Fcodelineno-11-209)
[](#%5F%5Fcodelineno-11-210)            completion(nil)
[](#%5F%5Fcodelineno-11-211)        }
[](#%5F%5Fcodelineno-11-212)    }
[](#%5F%5Fcodelineno-11-213)
[](#%5F%5Fcodelineno-11-214)    private func processPlainTextAttachment(_ attachment: NSItemProvider, dispatchGroup: DispatchGroup, completion: @escaping (String?) -> Void) {
[](#%5F%5Fcodelineno-11-215)        dispatchGroup.enter()
[](#%5F%5Fcodelineno-11-216)        attachment.loadItem(forTypeIdentifier: UTType.plainText.identifier, options: nil) { (item, _) in
[](#%5F%5Fcodelineno-11-217)            defer { dispatchGroup.leave() }
[](#%5F%5Fcodelineno-11-218)
[](#%5F%5Fcodelineno-11-219)            if let text = item as? String {
[](#%5F%5Fcodelineno-11-220)                completion(text)
[](#%5F%5Fcodelineno-11-221)            } else {
[](#%5F%5Fcodelineno-11-222)                completion(nil)
[](#%5F%5Fcodelineno-11-223)            }
[](#%5F%5Fcodelineno-11-224)        }
[](#%5F%5Fcodelineno-11-225)    }
[](#%5F%5Fcodelineno-11-226)
[](#%5F%5Fcodelineno-11-227)    private func processURLAttachment(_ attachment: NSItemProvider, dispatchGroup: DispatchGroup, completion: @escaping (String?) -> Void) {
[](#%5F%5Fcodelineno-11-228)        dispatchGroup.enter()
[](#%5F%5Fcodelineno-11-229)        attachment.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) { (item, _) in
[](#%5F%5Fcodelineno-11-230)            defer { dispatchGroup.leave() }
[](#%5F%5Fcodelineno-11-231)
[](#%5F%5Fcodelineno-11-232)            if let url = item as? URL {
[](#%5F%5Fcodelineno-11-233)                completion(url.absoluteString)
[](#%5F%5Fcodelineno-11-234)            } else {
[](#%5F%5Fcodelineno-11-235)                completion(nil)
[](#%5F%5Fcodelineno-11-236)            }
[](#%5F%5Fcodelineno-11-237)        }
[](#%5F%5Fcodelineno-11-238)    }
[](#%5F%5Fcodelineno-11-239)
[](#%5F%5Fcodelineno-11-240)    private func processSharedContent() {
[](#%5F%5Fcodelineno-11-241)        guard let extensionContext = extensionContext,
[](#%5F%5Fcodelineno-11-242)              let item = extensionContext.inputItems.first as? NSExtensionItem,
[](#%5F%5Fcodelineno-11-243)              let attachments = item.attachments else {
[](#%5F%5Fcodelineno-11-244)            self.extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
[](#%5F%5Fcodelineno-11-245)            return
[](#%5F%5Fcodelineno-11-246)        }
[](#%5F%5Fcodelineno-11-247)
[](#%5F%5Fcodelineno-11-248)        var textValues: [String] = []
[](#%5F%5Fcodelineno-11-249)        var fileValues: [SharedFileData] = []
[](#%5F%5Fcodelineno-11-250)        let title = item.attributedTitle?.string ?? item.attributedContentText?.string ?? ""
[](#%5F%5Fcodelineno-11-251)        let dispatchGroup = DispatchGroup()
[](#%5F%5Fcodelineno-11-252)
[](#%5F%5Fcodelineno-11-253)        for attachment in attachments {
[](#%5F%5Fcodelineno-11-254)            if attachment.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
[](#%5F%5Fcodelineno-11-255)                processImageAttachment(attachment, dispatchGroup: dispatchGroup) { fileData in
[](#%5F%5Fcodelineno-11-256)                    if let fileData = fileData {
[](#%5F%5Fcodelineno-11-257)                        fileValues.append(fileData)
[](#%5F%5Fcodelineno-11-258)                    }
[](#%5F%5Fcodelineno-11-259)                }
[](#%5F%5Fcodelineno-11-260)            }
[](#%5F%5Fcodelineno-11-261)
[](#%5F%5Fcodelineno-11-262)            if attachment.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
[](#%5F%5Fcodelineno-11-263)                processMovieAttachment(attachment, dispatchGroup: dispatchGroup) { fileData in
[](#%5F%5Fcodelineno-11-264)                    if let fileData = fileData {
[](#%5F%5Fcodelineno-11-265)                        fileValues.append(fileData)
[](#%5F%5Fcodelineno-11-266)                    }
[](#%5F%5Fcodelineno-11-267)                }
[](#%5F%5Fcodelineno-11-268)            }
[](#%5F%5Fcodelineno-11-269)
[](#%5F%5Fcodelineno-11-270)            if attachment.hasItemConformingToTypeIdentifier(UTType.plainText.identifier) {
[](#%5F%5Fcodelineno-11-271)                processPlainTextAttachment(attachment, dispatchGroup: dispatchGroup) { text in
[](#%5F%5Fcodelineno-11-272)                    if let text = text {
[](#%5F%5Fcodelineno-11-273)                        textValues.append(text)
[](#%5F%5Fcodelineno-11-274)                    }
[](#%5F%5Fcodelineno-11-275)                }
[](#%5F%5Fcodelineno-11-276)            }
[](#%5F%5Fcodelineno-11-277)
[](#%5F%5Fcodelineno-11-278)            if attachment.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
[](#%5F%5Fcodelineno-11-279)                processURLAttachment(attachment, dispatchGroup: dispatchGroup) { urlString in
[](#%5F%5Fcodelineno-11-280)                    if let urlString = urlString {
[](#%5F%5Fcodelineno-11-281)                        textValues.append(urlString)
[](#%5F%5Fcodelineno-11-282)                    }
[](#%5F%5Fcodelineno-11-283)                }
[](#%5F%5Fcodelineno-11-284)            }
[](#%5F%5Fcodelineno-11-285)        }
[](#%5F%5Fcodelineno-11-286)
[](#%5F%5Fcodelineno-11-287)        dispatchGroup.notify(queue: .main) { [weak self] in
[](#%5F%5Fcodelineno-11-288)            self?.sendData(with: textValues, fileValues: fileValues, title: title)
[](#%5F%5Fcodelineno-11-289)        }
[](#%5F%5Fcodelineno-11-290)    }
[](#%5F%5Fcodelineno-11-291)}
[](#%5F%5Fcodelineno-11-292)
[](#%5F%5Fcodelineno-11-293)extension UIImage {
[](#%5F%5Fcodelineno-11-294)
[](#%5F%5Fcodelineno-11-295)    private func applyRotationTransform(for orientation: UIImage.Orientation, to transform: CGAffineTransform, size: CGSize) -> CGAffineTransform {
[](#%5F%5Fcodelineno-11-296)        var result = transform
[](#%5F%5Fcodelineno-11-297)
[](#%5F%5Fcodelineno-11-298)        switch orientation {
[](#%5F%5Fcodelineno-11-299)        case .down, .downMirrored:
[](#%5F%5Fcodelineno-11-300)            result = result.translatedBy(x: size.width, y: size.height)
[](#%5F%5Fcodelineno-11-301)            result = result.rotated(by: .pi)
[](#%5F%5Fcodelineno-11-302)        case .left, .leftMirrored:
[](#%5F%5Fcodelineno-11-303)            result = result.translatedBy(x: size.width, y: 0)
[](#%5F%5Fcodelineno-11-304)            result = result.rotated(by: .pi / 2.0)
[](#%5F%5Fcodelineno-11-305)        case .right, .rightMirrored:
[](#%5F%5Fcodelineno-11-306)            result = result.translatedBy(x: 0, y: size.height)
[](#%5F%5Fcodelineno-11-307)            result = result.rotated(by: -.pi / 2.0)
[](#%5F%5Fcodelineno-11-308)        case .up, .upMirrored:
[](#%5F%5Fcodelineno-11-309)            break
[](#%5F%5Fcodelineno-11-310)        @unknown default:
[](#%5F%5Fcodelineno-11-311)            break
[](#%5F%5Fcodelineno-11-312)        }
[](#%5F%5Fcodelineno-11-313)
[](#%5F%5Fcodelineno-11-314)        return result
[](#%5F%5Fcodelineno-11-315)    }
[](#%5F%5Fcodelineno-11-316)
[](#%5F%5Fcodelineno-11-317)    private func applyMirrorTransform(for orientation: UIImage.Orientation, to transform: CGAffineTransform, size: CGSize) -> CGAffineTransform {
[](#%5F%5Fcodelineno-11-318)        var result = transform
[](#%5F%5Fcodelineno-11-319)
[](#%5F%5Fcodelineno-11-320)        switch orientation {
[](#%5F%5Fcodelineno-11-321)        case .upMirrored, .downMirrored:
[](#%5F%5Fcodelineno-11-322)            result = result.translatedBy(x: size.width, y: 0)
[](#%5F%5Fcodelineno-11-323)            result = result.scaledBy(x: -1, y: 1)
[](#%5F%5Fcodelineno-11-324)        case .leftMirrored, .rightMirrored:
[](#%5F%5Fcodelineno-11-325)            result = result.translatedBy(x: size.height, y: 0)
[](#%5F%5Fcodelineno-11-326)            result = result.scaledBy(x: -1, y: 1)
[](#%5F%5Fcodelineno-11-327)        case .up, .down, .left, .right:
[](#%5F%5Fcodelineno-11-328)            break
[](#%5F%5Fcodelineno-11-329)        @unknown default:
[](#%5F%5Fcodelineno-11-330)            break
[](#%5F%5Fcodelineno-11-331)        }
[](#%5F%5Fcodelineno-11-332)
[](#%5F%5Fcodelineno-11-333)        return result
[](#%5F%5Fcodelineno-11-334)    }
[](#%5F%5Fcodelineno-11-335)
[](#%5F%5Fcodelineno-11-336)    private func drawRect(for orientation: UIImage.Orientation, size: CGSize) -> CGRect {
[](#%5F%5Fcodelineno-11-337)        switch orientation {
[](#%5F%5Fcodelineno-11-338)        case .left, .leftMirrored, .right, .rightMirrored:
[](#%5F%5Fcodelineno-11-339)            return CGRect(x: 0, y: 0, width: size.height, height: size.width)
[](#%5F%5Fcodelineno-11-340)        default:
[](#%5F%5Fcodelineno-11-341)            return CGRect(x: 0, y: 0, width: size.width, height: size.height)
[](#%5F%5Fcodelineno-11-342)        }
[](#%5F%5Fcodelineno-11-343)    }
[](#%5F%5Fcodelineno-11-344)
[](#%5F%5Fcodelineno-11-345)    func fixedOrientation() -> UIImage? {
[](#%5F%5Fcodelineno-11-346)        guard imageOrientation != .up else {
[](#%5F%5Fcodelineno-11-347)            return self.copy() as? UIImage
[](#%5F%5Fcodelineno-11-348)        }
[](#%5F%5Fcodelineno-11-349)
[](#%5F%5Fcodelineno-11-350)        guard let cgImage = self.cgImage,
[](#%5F%5Fcodelineno-11-351)              let colorSpace = cgImage.colorSpace,
[](#%5F%5Fcodelineno-11-352)              let context = CGContext(data: nil,
[](#%5F%5Fcodelineno-11-353)                                    width: Int(size.width),
[](#%5F%5Fcodelineno-11-354)                                    height: Int(size.height),
[](#%5F%5Fcodelineno-11-355)                                    bitsPerComponent: cgImage.bitsPerComponent,
[](#%5F%5Fcodelineno-11-356)                                    bytesPerRow: 0,
[](#%5F%5Fcodelineno-11-357)                                    space: colorSpace,
[](#%5F%5Fcodelineno-11-358)                                    bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
[](#%5F%5Fcodelineno-11-359)            return nil
[](#%5F%5Fcodelineno-11-360)        }
[](#%5F%5Fcodelineno-11-361)
[](#%5F%5Fcodelineno-11-362)        var transform = CGAffineTransform.identity
[](#%5F%5Fcodelineno-11-363)        transform = applyRotationTransform(for: imageOrientation, to: transform, size: size)
[](#%5F%5Fcodelineno-11-364)        transform = applyMirrorTransform(for: imageOrientation, to: transform, size: size)
[](#%5F%5Fcodelineno-11-365)
[](#%5F%5Fcodelineno-11-366)        context.concatenate(transform)
[](#%5F%5Fcodelineno-11-367)        context.draw(cgImage, in: drawRect(for: imageOrientation, size: size))
[](#%5F%5Fcodelineno-11-368)
[](#%5F%5Fcodelineno-11-369)        guard let newCGImage = context.makeImage() else { return nil }
[](#%5F%5Fcodelineno-11-370)        return UIImage(cgImage: newCGImage, scale: 1, orientation: .up)
[](#%5F%5Fcodelineno-11-371)    }
[](#%5F%5Fcodelineno-11-372)}
`

**Attention**: Replace `<YOUR_URL_SCHEME>` with the URL scheme you defined in your main app's `Info.plist` file (e.g. `myapp`) and `<YOUR_APP_IDENTIFIER>` with your app identifier (e.g. `com.example.app`). Make sure to keep the `group.` prefix for the app group identifier.

Finally, you need to modify the `AppDelegate.swift` file of your main app target to handle the URLs opened by the share extension. Add the missing import and the following code to the `application(_:open:options:)` method:

`[](#%5F%5Fcodelineno-12-1)// If you are using CocoaPods, add the following import:
[](#%5F%5Fcodelineno-12-2)+ import CapawesomeTeamCapacitorShareTarget
[](#%5F%5Fcodelineno-12-3)// Or if you are using Swift Package Manager, add the following import:
[](#%5F%5Fcodelineno-12-4)// import ShareTargetPlugin
[](#%5F%5Fcodelineno-12-5)
[](#%5F%5Fcodelineno-12-6)func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
[](#%5F%5Fcodelineno-12-7)+    // Handle share target URLs
[](#%5F%5Fcodelineno-12-8)+    let _ = ShareTargetPlugin.handleOpenUrl(url)
[](#%5F%5Fcodelineno-12-9)+
[](#%5F%5Fcodelineno-12-10)    // Called when the app was launched with a url. Feel free to add additional processing here,
[](#%5F%5Fcodelineno-12-11)    // but if you want the App API to support tracking app url opens, make sure to keep this call
[](#%5F%5Fcodelineno-12-12)    return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
[](#%5F%5Fcodelineno-12-13)}
`

**Attention**: If you are using **Swift Package Manager** instead of CocoaPods, replace `import CapawesomeTeamCapacitorShareTarget` with `import ShareTargetPlugin`.

#### Capabilities[¶](#capabilities "Permanent link")

If you want to receive not only text but also files (e.g., images, videos) from other apps, you need to enable the "App Groups" capability for both your main app and the share extension. This allows both targets to share files in a common container. To do this, follow these steps:

1. Open your Xcode project.
2. Select your app target.
3. Go to the "Signing & Capabilities" tab.
4. Click the "+" button to add a new capability.
5. Select "App Groups" from the list.
6. Create a new app group using the format `group.<YOUR_APP_IDENTIFIER>` (e.g., `group.com.example.app`).
7. Repeat the same steps for your share extension target, ensuring that both targets use the same app group identifier.

If you don't want to receive files, you can skip this step.

## Configuration[¶](#configuration "Permanent link")

No configuration required for this plugin.

## Web[¶](#web "Permanent link")

To use this plugin on the web, you need to set up a **Progressive Web App (PWA)** with a web manifest and service worker that handles share targets.

### Manifest[¶](#manifest "Permanent link")

To allow your PWA to act as a share target, you need to add a `share_target` configuration to your web manifest (`manifest.json`):

`[](#%5F%5Fcodelineno-13-1){
[](#%5F%5Fcodelineno-13-2)  "share_target": {
[](#%5F%5Fcodelineno-13-3)    "action": "/_share-target",
[](#%5F%5Fcodelineno-13-4)    "method": "POST",
[](#%5F%5Fcodelineno-13-5)    "enctype": "multipart/form-data",
[](#%5F%5Fcodelineno-13-6)    "params": {
[](#%5F%5Fcodelineno-13-7)      "title": "title",
[](#%5F%5Fcodelineno-13-8)      "text": "text", 
[](#%5F%5Fcodelineno-13-9)      "url": "url",
[](#%5F%5Fcodelineno-13-10)      "files": [
[](#%5F%5Fcodelineno-13-11)        {
[](#%5F%5Fcodelineno-13-12)          "name": "files",
[](#%5F%5Fcodelineno-13-13)          "accept": ["*/*"]
[](#%5F%5Fcodelineno-13-14)        }
[](#%5F%5Fcodelineno-13-15)      ]
[](#%5F%5Fcodelineno-13-16)    }
[](#%5F%5Fcodelineno-13-17)  }
[](#%5F%5Fcodelineno-13-18)}
`

For more information on setting up the share target for your PWA, refer to the [Web Share Target documentation](https://developer.mozilla.org/en-US/docs/Web/Manifest/share%5Ftarget).

### Service Worker[¶](#service-worker "Permanent link")

Since service workers are the only way to intercept network requests in a PWA, you'll need to create one to handle the share target requests. Just create a file named `sw.js` in your project's root directory and add the following code:

`` [](#%5F%5Fcodelineno-14-1)self.addEventListener('fetch', event => {
[](#%5F%5Fcodelineno-14-2)  const url = new URL(event.request.url);
[](#%5F%5Fcodelineno-14-3)
[](#%5F%5Fcodelineno-14-4)  if (event.request.method === 'POST' && url.pathname === '/_share-target') {
[](#%5F%5Fcodelineno-14-5)    event.respondWith(handleShareTarget(event.request));
[](#%5F%5Fcodelineno-14-6)  } else if (url.pathname.startsWith('/_share-file/')) {
[](#%5F%5Fcodelineno-14-7)    event.respondWith(handleFileRequest(event.request));
[](#%5F%5Fcodelineno-14-8)  }
[](#%5F%5Fcodelineno-14-9)});
[](#%5F%5Fcodelineno-14-10)
[](#%5F%5Fcodelineno-14-11)async function handleFileRequest(request) {
[](#%5F%5Fcodelineno-14-12)  try {
[](#%5F%5Fcodelineno-14-13)    const url = new URL(request.url);
[](#%5F%5Fcodelineno-14-14)    const fileId = url.pathname.substring(13); // Remove '/_share-file/' prefix
[](#%5F%5Fcodelineno-14-15)    const cache = await caches.open('share-target-files');
[](#%5F%5Fcodelineno-14-16)    const cacheKey = `/${fileId}`;
[](#%5F%5Fcodelineno-14-17)
[](#%5F%5Fcodelineno-14-18)    const response = await cache.match(cacheKey);
[](#%5F%5Fcodelineno-14-19)    if (response) {
[](#%5F%5Fcodelineno-14-20)      return response;
[](#%5F%5Fcodelineno-14-21)    } else {
[](#%5F%5Fcodelineno-14-22)      return new Response('File not found', { status: 404 });
[](#%5F%5Fcodelineno-14-23)    }
[](#%5F%5Fcodelineno-14-24)  } catch (error) {
[](#%5F%5Fcodelineno-14-25)    console.error('Error serving file:', error);
[](#%5F%5Fcodelineno-14-26)    return new Response('Internal error', { status: 500 });
[](#%5F%5Fcodelineno-14-27)  }
[](#%5F%5Fcodelineno-14-28)}
[](#%5F%5Fcodelineno-14-29)
[](#%5F%5Fcodelineno-14-30)async function handleShareTarget(request) {
[](#%5F%5Fcodelineno-14-31)  try {
[](#%5F%5Fcodelineno-14-32)    const formData = await request.formData();
[](#%5F%5Fcodelineno-14-33)    const title = formData.get('title') || '';
[](#%5F%5Fcodelineno-14-34)    const text = formData.get('text') || '';
[](#%5F%5Fcodelineno-14-35)    const url = formData.get('url') || '';
[](#%5F%5Fcodelineno-14-36)    const files = formData.getAll('files');
[](#%5F%5Fcodelineno-14-37)
[](#%5F%5Fcodelineno-14-38)    const texts = [];
[](#%5F%5Fcodelineno-14-39)    if (text) texts.push(text);
[](#%5F%5Fcodelineno-14-40)    if (url) texts.push(url);
[](#%5F%5Fcodelineno-14-41)
[](#%5F%5Fcodelineno-14-42)    const shareData = {
[](#%5F%5Fcodelineno-14-43)      title: title,
[](#%5F%5Fcodelineno-14-44)      texts: texts.length > 0 ? texts : undefined,
[](#%5F%5Fcodelineno-14-45)      files: undefined,
[](#%5F%5Fcodelineno-14-46)    };
[](#%5F%5Fcodelineno-14-47)
[](#%5F%5Fcodelineno-14-48)    if (files.length > 0) {
[](#%5F%5Fcodelineno-14-49)      const sharedFiles = [];
[](#%5F%5Fcodelineno-14-50)      const cache = await caches.open('share-target-files');
[](#%5F%5Fcodelineno-14-51)
[](#%5F%5Fcodelineno-14-52)      for (const file of files) {
[](#%5F%5Fcodelineno-14-53)        if (file instanceof File && file.size > 0) {
[](#%5F%5Fcodelineno-14-54)          const fileId = `share-file-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
[](#%5F%5Fcodelineno-14-55)          const cacheKey = `/${fileId}`;
[](#%5F%5Fcodelineno-14-56)
[](#%5F%5Fcodelineno-14-57)          const response = new Response(file, {
[](#%5F%5Fcodelineno-14-58)            headers: {
[](#%5F%5Fcodelineno-14-59)              'Content-Type': file.type,
[](#%5F%5Fcodelineno-14-60)              'Content-Length': file.size.toString(),
[](#%5F%5Fcodelineno-14-61)              'X-File-Name': file.name || 'unknown',
[](#%5F%5Fcodelineno-14-62)            }
[](#%5F%5Fcodelineno-14-63)          });
[](#%5F%5Fcodelineno-14-64)          await cache.put(cacheKey, response);
[](#%5F%5Fcodelineno-14-65)
[](#%5F%5Fcodelineno-14-66)          sharedFiles.push({
[](#%5F%5Fcodelineno-14-67)            uri: `/_share-file/${fileId}`,
[](#%5F%5Fcodelineno-14-68)            name: file.name || undefined,
[](#%5F%5Fcodelineno-14-69)            mimeType: file.type || undefined,
[](#%5F%5Fcodelineno-14-70)          });
[](#%5F%5Fcodelineno-14-71)        }
[](#%5F%5Fcodelineno-14-72)      }
[](#%5F%5Fcodelineno-14-73)
[](#%5F%5Fcodelineno-14-74)      if (sharedFiles.length > 0) {
[](#%5F%5Fcodelineno-14-75)        shareData.files = sharedFiles;
[](#%5F%5Fcodelineno-14-76)      }
[](#%5F%5Fcodelineno-14-77)    }
[](#%5F%5Fcodelineno-14-78)
[](#%5F%5Fcodelineno-14-79)    const redirectUrl = new URL('/', self.location.origin);
[](#%5F%5Fcodelineno-14-80)
[](#%5F%5Fcodelineno-14-81)    if (shareData.title) {
[](#%5F%5Fcodelineno-14-82)      redirectUrl.searchParams.set('title', shareData.title);
[](#%5F%5Fcodelineno-14-83)    }
[](#%5F%5Fcodelineno-14-84)
[](#%5F%5Fcodelineno-14-85)    if (shareData.texts && shareData.texts.length > 0) {
[](#%5F%5Fcodelineno-14-86)      shareData.texts.forEach((text, index) => {
[](#%5F%5Fcodelineno-14-87)        redirectUrl.searchParams.set(`text${index}`, text);
[](#%5F%5Fcodelineno-14-88)      });
[](#%5F%5Fcodelineno-14-89)    }
[](#%5F%5Fcodelineno-14-90)
[](#%5F%5Fcodelineno-14-91)    if (shareData.files && shareData.files.length > 0) {
[](#%5F%5Fcodelineno-14-92)      shareData.files.forEach((file, index) => {
[](#%5F%5Fcodelineno-14-93)        redirectUrl.searchParams.set(`fileUri${index}`, file.uri);
[](#%5F%5Fcodelineno-14-94)        if (file.name) {
[](#%5F%5Fcodelineno-14-95)          redirectUrl.searchParams.set(`fileName${index}`, file.name);
[](#%5F%5Fcodelineno-14-96)        }
[](#%5F%5Fcodelineno-14-97)        if (file.mimeType) {
[](#%5F%5Fcodelineno-14-98)          redirectUrl.searchParams.set(`fileMimeType${index}`, file.mimeType);
[](#%5F%5Fcodelineno-14-99)        }
[](#%5F%5Fcodelineno-14-100)      });
[](#%5F%5Fcodelineno-14-101)    }
[](#%5F%5Fcodelineno-14-102)
[](#%5F%5Fcodelineno-14-103)    return Response.redirect(redirectUrl.href, 303);
[](#%5F%5Fcodelineno-14-104)  } catch (error) {
[](#%5F%5Fcodelineno-14-105)    console.error('Error handling share target:', error);
[](#%5F%5Fcodelineno-14-106)    return Response.redirect('/', 303);
[](#%5F%5Fcodelineno-14-107)  }
[](#%5F%5Fcodelineno-14-108)}
 ``

Now, register your service worker in your main JavaScript file:

`[](#%5F%5Fcodelineno-15-1)if ('serviceWorker' in navigator) {
[](#%5F%5Fcodelineno-15-2)  navigator.serviceWorker.register('/sw.js');
[](#%5F%5Fcodelineno-15-3)}
`

## Usage[¶](#usage "Permanent link")

`[](#%5F%5Fcodelineno-16-1)import { Capacitor } from '@capacitor/core';
[](#%5F%5Fcodelineno-16-2)import { ShareTarget } from '@capawesome-team/capacitor-share-target';
[](#%5F%5Fcodelineno-16-3)
[](#%5F%5Fcodelineno-16-4)const addListener = async () => {
[](#%5F%5Fcodelineno-16-5)    await ShareTarget.addListener('shareReceived', (event) => {
[](#%5F%5Fcodelineno-16-6)        console.log('Share received:', event);
[](#%5F%5Fcodelineno-16-7)
[](#%5F%5Fcodelineno-16-8)        // Handle shared files
[](#%5F%5Fcodelineno-16-9)        if (event.files) {
[](#%5F%5Fcodelineno-16-10)          event.files.forEach(async (file) => {
[](#%5F%5Fcodelineno-16-11)            const webPath = Capacitor.convertFileSrc(file.uri);
[](#%5F%5Fcodelineno-16-12)            const response = await fetch(webPath);
[](#%5F%5Fcodelineno-16-13)            const blob = await response.blob();
[](#%5F%5Fcodelineno-16-14)            // Process the file...
[](#%5F%5Fcodelineno-16-15)          });
[](#%5F%5Fcodelineno-16-16)        }
[](#%5F%5Fcodelineno-16-17)    });
[](#%5F%5Fcodelineno-16-18)};
`

## API[¶](#api "Permanent link")

* [addListener('shareReceived', ...)](#addlistenersharereceived-)
* [removeAllListeners()](#removealllisteners)
* [Interfaces](#interfaces)

### addListener('shareReceived', ...)[¶](#addlistenersharereceived "Permanent link")

`[](#%5F%5Fcodelineno-17-1)addListener(eventName: 'shareReceived', listenerFunc: (event: ShareReceivedEvent) => void) => Promise<PluginListenerHandle>
`

Called when a share is received.

| Param            | Type                                                       |
| ---------------- | ---------------------------------------------------------- |
| **eventName**    | 'shareReceived'                                            |
| **listenerFunc** | (event: [ShareReceivedEvent](#sharereceivedevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### removeAllListeners()[¶](#removealllisteners "Permanent link")

`[](#%5F%5Fcodelineno-18-1)removeAllListeners() => Promise<void>
`

Remove all listeners for this plugin.

**Since:** 0.1.0

---

### Interfaces[¶](#interfaces "Permanent link")

#### PluginListenerHandle[¶](#pluginlistenerhandle "Permanent link")

| Prop       | Type                |
| ---------- | ------------------- |
| **remove** | () => Promise<void> |

#### ShareReceivedEvent[¶](#sharereceivedevent "Permanent link")

| Prop      | Type           | Description                       | Since |
| --------- | -------------- | --------------------------------- | ----- |
| **title** | string         | The title of the shared content.  | 0.1.0 |
| **texts** | string\[\]     | The text content that was shared. | 0.1.0 |
| **files** | SharedFile\[\] | The files that were shared.       | 0.2.0 |

#### SharedFile[¶](#sharedfile "Permanent link")

| Prop         | Type   | Description                                                                                                                                                                                                            | Since |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **mimeType** | string | The mime type of the shared file.                                                                                                                                                                                      | 0.2.0 |
| **name**     | string | The name of the shared file with or without extension.                                                                                                                                                                 | 0.2.0 |
| **uri**      | string | The URI of the shared file. On **Android** and **iOS**, this will contain the file paths or base64 encoded data URLs of the shared files. On **Web**, this will contain cached file URLs that can be fetched directly. | 0.2.0 |

## Troubleshooting[¶](#troubleshooting "Permanent link")

##### `Unable to find compatibility version string for object version XX`[¶](#unable-to-find-compatibility-version-string-for-object-version-xx "Permanent link")

When creating a share extension, you might encounter the following error when building your app:

`[](#%5F%5Fcodelineno-19-1)Unable to find compatibility version string for object version 70
`

This error is typically caused by an updated `objectVersion` value in the `project.pbxproj` file of your Xcode project. To resolve this issue, you need to manually revert the `objectVersion` value to a previous version that is compatible with your Xcode version.

## Changelog[¶](#changelog "Permanent link")

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/share-target/CHANGELOG.md).

## Breaking Changes[¶](#breaking-changes "Permanent link")

See [BREAKING.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/share-target/BREAKING.md).

## License[¶](#license "Permanent link")

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/share-target/LICENSE).

May 17, 2026 

 Back to top 