Implementing React Native Share Extension : The Ultimate Guide




In today's interconnected digital world, seamless sharing of content across apps has become a fundamental aspect of user experience. Whether it's sharing an interesting article, a captivating image, or a snippet of text, users expect to effortlessly transfer content between their favorite applications.



React Native, with its versatility and cross-platform capabilities, provides an excellent framework for building mobile apps that cater to these expectations. One powerful feature that React Native offers is the ability to implement Share Extensions Or Share Menu, allowing apps to receive content from other applications and integrate it seamlessly into their workflows.


In this comprehensive guide, we'll delve into the intricacies of implementing Share Extensions in React Native. From setting up your project to handling shared content, we'll walk you through each step of the process, equipping you with the knowledge to enhance your app's functionality and user experience.


Whether you're a seasoned React Native developer looking to expand your app's capabilities or a newcomer eager to explore the world of cross-app content sharing, this guide is designed to provide you with the insights and techniques you need to succeed.

 Below is a step-by-step guide on how to implement a Share Extension or Share Menu in React Native

 Create a new React Native project

 npx react-native init YourProjectName

Install required package


npm i --save react-native-share-menu
cd ios
pod install


Add Share Extension Target to Xcode Project


Right-click on the project name in the project navigator and select "New Target".Choose "Share Extension" from the list of templates.Name your Share Extension target and click "Finish".


















                


Next, Open the ShareViewController.swift  and replace this code below

    import UIKit
    import Social
    import SafariServices
    import MobileCoreServices
    class ShareViewController: SLComposeServiceViewController {
    override func isContentValid() -> Bool {
    // Do validation of contentText and/or NSExtensionContext attachments here
    return true
    }
    override func viewDidLoad() {
    didSelectPost()
    }
    override func didSelectPost() {
    if let item = extensionContext?.inputItems.first as? NSExtensionItem {
    if let attachments = item.attachments {
    for attachment: NSItemProvider in attachments {
    if attachment.hasItemConformingToTypeIdentifier("public.url") {
    attachment.loadItem(forTypeIdentifier: "public.url", options: nil, completionHandler: { (url, error) in
    if let shareURL = url as? NSURL {
    // Do stuff with your URL now.
    let url = NSURL(string: "schema://share/\(shareURL)")
    let selectorOpenURL = sel_registerName("openURL:")
    let context = NSExtensionContext()
    context.open(url! as URL, completionHandler: nil)
    var responder = self.parent as UIResponder?
    while (responder != nil){
    if responder?.responds(to: selectorOpenURL) == true{
    responder?.perform(selectorOpenURL, with: url)
    }
    responder = responder!.next
    }
    }
    self.extensionContext?.completeRequest(returningItems: [], completionHandler:nil)
    //super.didSelectCancel()
    })
    }
    if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) {
    attachment.loadItem(forTypeIdentifier: (kUTTypeImage as String), options: nil, completionHandler: { (item, error) in
    if let resultURL = item as? NSURL {
    // if let itemImage = item as? UIImage{
    let url = NSURL(string: "test.app.link://page1/\(resultURL)")
    let selectorOpenURL = sel_registerName("openURL:")
    let context = NSExtensionContext()
    context.open(url! as URL, completionHandler: nil)
    var responder = self.parent as UIResponder?
    while (responder != nil){
    if responder?.responds(to: selectorOpenURL) == true{
    responder?.perform(selectorOpenURL, with: url)
    }
    responder = responder!.next
    }
    }
    self.extensionContext?.completeRequest(returningItems: [], completionHandler:nil)
    //super.didSelectCancel()
    })
    }
    }
    }
    }
    // self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
    }

    override func didSelectCancel() {
    super.didSelectCancel()
    }

  }


Configure AppDelegate.m


Next, In Xcode edit AppDelegate.m and add the following lines


    #import <React/RCTLinkingManager.h> //Add this line
    @implementation AppDelegate
    //Add this code below
    - (BOOL)application:(UIApplication *)application
    openURL:(NSURL *)url
    options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
    {
    return [RCTLinkingManager application:application openURL:url options:options];
    }


Configure Share Extension



Navigate to ShareExtension target in Xcode. Open Info.plist and add the following keys:





<?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>NSAppTransportSecurity</key>
        <dict>
            <key>Allow Arbitraty Loads</key>
            <true/>
        </dict>
        <key>NSExtension</key>
        <dict>
            <key>NSExtensionAttributes</key>
            <dict>
                <key>NSExtensionActivationRule</key>
                <string>SUBQUERY(extensionItems,$extensionItem,SUBQUERY($extensionItem.attachments,$attachment,SUBQUERY($attachment.registeredTypeIdentifiers, $uti, $uti UTI-CONFORMS-TO "public.url" AND NOT $uti UTI-CONFORMS-TO "public.file-url").@count &gt;= 1).@count &gt;= 1).@count &gt;= 1</string>
            </dict>
            <key>NSExtensionMainStoryboard</key>
            <string>MainInterface</string>
            <key>NSExtensionPointIdentifier</key>
            <string>com.apple.share-services</string>
        </dict>
    </dict>
</plist>



Example



const linking = {
    prefixes: ['myapp://', 'https://yoururl.com'],

    // Custom function to get the URL which was used to open the app
    async getInitialURL() {

      // As a fallback, you may want to do the default deep link handling
      const url = await Linking.getInitialURL();
      //console.log(url);
      return url;
    },

    // Custom function to subscribe to incoming links
    subscribe(listener: any) {
      // Listen to incoming links from Firebase Dynamic Links


      // Listen to incoming links from deep linking
      const linkingSubscription = Linking.addEventListener('url', async ({ url }) => {
        listener(url);
        console.log(url,url.split('/')[5],'roc')


        if (url.split('/').pop()) {
           console.log(url.split('/')[5],'url')
         
        }

      });

      return () => {
        // Clean up the event listeners
        // unsubscribeFirebase();
        linkingSubscription.remove();
      };
    },

    config: {
      // Deep link configuration
    },
  };






In this ultimate guide, we've explored the intricate process of implementing Share Extensions in React Native, empowering your application with the ability to seamlessly interact with content from other apps. From inception to execution, we've navigated through each step, providing insights and techniques to ensure success in integrating this powerful feature.

By following the steps outlined in this guide, you've equipped yourself with the knowledge and tools necessary to enhance your app's functionality and user experience. Share Extensions offer a gateway to a more connected digital ecosystem, allowing users to effortlessly share content across applications with ease.

As you embark on your journey to implement Share Extensions in your React Native application, remember the importance of thorough testing and optimization. Pay attention to user experience and ensure that the integration seamlessly blends into your app's workflow.

With Share Extensions, you're not just enabling content sharing; you're fostering connectivity and collaboration in the digital realm. Embrace the possibilities, innovate with confidence, and watch as your app flourishes in the ever-evolving landscape of mobile technology.


Happy Coding ✌

Previous Post Next Post

Contact Form