Share extensions was introduced in iOS 8. Share extension is useful for sharing content like images, videos, text, etc. in your app from any app. Before iOS8, to share the content, it was done by first copying the content and then open an app in which we want to share and then perform share action. But by using share extension in iOS app, there is no need to open an app to share any content.
Implement Share Extension with Steps
CallKit is a new framework and is available in iOS 10 and later. Used to implement VoIP functionality, call blocking, and identification in your app. Apps can use CallKit to receive incoming calls and outgoing calls using the native call UI.
First you need to create an app, in which you share content from other app.
Now create share extension, go to File->New->Target.
Select Share Extension from Application Extension. Provide a name of your Extension.
Now XCode will ask you to active the scheme, Click on Active button.
It will include following list of file in your project folder.
Enable App Groups.
- Select project target and go to Capabilities.
- Select development team and turn on App Group
- Now list of app groups will be shown. Select your app group.
- Now select extension from target and do the same to enable app group in share extension.
- Now app is configured and ready to share content.
Now build and run your extension by choosing extension from active scheme as following.
It will ask to select an app to run, here we will select Photos and press Run.
- It will directly open photos.
- Now select any photo from photos and click on share button.
- If you don’t get extension name, then click on more and enable extension from list.
Now click on that and get following screen.
Composer sheet is available with content and image. Click on the Post button. But nothing happens. Now if you want to handle delegate method, when user click on post button, respected content will be shared to your application you have to go through the extension classes.
Extension Classes
- When Share extension is added by default ShareViewController.swift, and MainInterface.storyboard is created.
- By default ShareViewController.swift inherits SLComposeServiceViewController, that have it’s UI for share extension.
- If you want your own UI design, then you can inherit UIViewController instead of SLComposeServiceViewController in ShareViewController.swift file.
Following steps describe line of code that you have to write in your share extension class files ShareViewController.swift.
isContentValid: This method is used to validate the content like sharing text length, etc.
override func isContentValid() -> Bool { // Do validation of contentText and/or NSExtensionContext attachments here return true }
didSelectPost: This method is called when user press the post button. This is the place where you can do sharing. The method completeRequestReturningItems([], completionHandler:) must be called for uploading task, so host app can do stuff without blocking main thread.
override func didSelectPost() { if let item = self.extensionContext?.inputItems[0] as? NSExtensionItem{ for ele in item.attachments!{ let itemProvider = ele as! NSItemProvider if itemProvider.hasItemConformingToTypeIdentifier("public.jpeg"){ NSLog("itemprovider: %@", itemProvider) itemProvider.loadItem(forTypeIdentifier: "public.jpeg", options: nil, completionHandler: { (item, error) in var imgData: Data! if let url = item as? URL{ imgData = try! Data(contentsOf: url) } if let img = item as? UIImage{ imgData = UIImagePNGRepresentation(img) } let dict: [String : Any] = ["imgData" : imgData, "name" : self.contentText] let userDefault = UserDefaults.standard userDefault.addSuite(named: "group.yudiz.shareKitDemo") userDefault.set(dict, forKey: "img") userDefault.synchronize() }) } } } self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) }
Make change in info.plist in your share extension for share image.
<key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationSupportsImageWithMaxCount</key> <integer>1</integer> </dict> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.share-services</string> </dict>
Setting this property extension is shown when only one image is selected. We can set this property to hide or show extension when more than one image is selected.
Show shared content in your app
Add following code in your ViewController to get shared image and text.
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let userDefault = UserDefaults.standard userDefault.addSuite(named: "group.yudiz.shareKitDemo") if let dict = userDefault.value(forKey: "img") as? NSDictionary{ let data = dict.value(forKey: "imgData") as! Data let str = dict.value(forKey: "name") as! String self.imgView.image = UIImage(data: data) self.lblText.text = str userDefault.removeObject(forKey: "img") userDefault.synchronize() } }
Check image sharing
Run your project (Select your app as a target not the extension).
First time image and text gets empty.
Now stop app and run your extension, select photos app. Photos app now opened. Select any photo, tap on share button. Select your app extension form activityViewController, if your app is now listed then go to More and switch on your extension to share.
Now tap on your extension, add some text and press on Post button.
Close Photos app and open your app, you will see selected photo and entered text in your app now.
I hope you find this blog very helpful while working on Share Extension.
Thank you.