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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…