Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add my app to the share sheet action

I am trying to add my app to the share sheet. if you look a photo and you press the share button you see Facebook twitter ...

Recently i downloaded a few app from the store and they appear in the share sheet as well so i suppose it possible in some way.

Is it possible? If so how

What this question is not

  1. This is not about simply share data between apps you created. Usually a custom URL scheme is for this purpose, but only when your data source know how to use the custom scheme. But this question is about how to make your app ready for a third party app (i.e. Photos) to share standard content (photos, movies etc) to you.

  2. This is not about how to prepare your content to share on for example Facebook or Twitter. Instead, it asks how to write your own Facebook-like app so it can accept shares

like image 899
nahum Avatar asked Nov 03 '15 11:11

nahum


People also ask

How do I add an app to my favorites?

From the bottom of your screen, swipe up. Touch and hold an app. Move the app into an empty spot next to your favorites.

How do I change my share suggestions on iPhone?

Open the Share Sheet and scroll to the end of the apps panel. Here, tap on the “More” button. You'll see two sections: Favorites and Suggestions. Tap on the “Edit” button in the top-right corner.


1 Answers

Updated for Xcode 11.2.1, swift 5.2

Yes this is possible.


Create an extension

In your XCode go to File -> New -> Target then select Share Extension.

A folder and a file with extension .appex will be created in your project directory.

Folder will contains

Extension Name  --------- ShareViewController.swift
               |
                -------- Maininterface.storyboard 
               |
                -------- Info.plist

Add support for item type

In this plist give proper extensions that your app can share*.

<key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsImageWithMaxCount</key>
            <integer>10</integer>
            <key>NSExtensionActivationSupportsMovieWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
    </dict>

Delegate methods

ShareViewController file content

    override func isContentValid() -> Bool {
            // Do validation of contentText and/or NSExtensionContext attachments here
            return true
    }

    override func didSelectPost() {
             // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.

            // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
                self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
    }

    override func configurationItems() -> [Any]! {
            // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
                return []
    }

Sharing the post from your side

You're almost there. Pass the selected item into your app from disSelectPost. You can use an external code below

- ( void ) passSelectedItemsToApp
{
    NSExtensionItem * item = self.extensionContext.inputItems.firstObject;

    // Reset the counter and the argument list for invoking the app:
    m_invokeArgs = NULL;
    m_inputItemCount = item.attachments.count;

    // Iterate through the attached files
    for ( NSItemProvider * itemProvider in item.attachments )
    {
        // Check if we are sharing a JPEG
        if ( [ itemProvider hasItemConformingToTypeIdentifier: ( NSString * ) kUTTypeJPEG ] )
        {
            // Load it, so we can get the path to it
            [ itemProvider loadItemForTypeIdentifier: ( NSString * ) kUTTypeJPEG
                                             options: NULL
                                   completionHandler: ^ ( UIImage * image, NSError * error )
             {
                 static int itemIdx = 0;

                 if ( NULL != error )
                 {
                     NSLog( @"There was an error retrieving the attachments: %@", error );
                     return;
                 }

                 // The app won't be able to access the images by path directly in the Camera Roll folder,
                 // so we temporary copy them to a folder which both the extension and the app can access:
                 NSString * filePath = [ self saveImageToAppGroupFolder: image imageIndex: itemIdx ];

                 // Now add the path to the list of arguments we'll pass to the app:
                 [ self addImagePathToArgumentList: filePath ];

                 // If we have reached the last attachment, it's time to hand control to the app:
                 if ( ++itemIdx >= m_inputItemCount )
                 {
                     [ self invokeApp: m_invokeArgs ];
                 }
             } ];
        }
    }
}

Also make sure you have the extension included in your .ipa file. By opening it using .zip trick.


Debugging your extension

To debug your extension using photos app as you said. You can use the attach to process method. *Steps

1) Open Photos App

2) Attach your extension to xcode using PID or Process name

3) Share a picture or video with your app.

4) App will hit at didSelectPost method.

*Apple documentation

like image 154
Saranjith Avatar answered Sep 25 '22 19:09

Saranjith