We can't find the internet
Attempting to reconnect
Airlist for iPhone and iPad has a very powerful share extension thanks to SwiftUI.
But the share extension API is still only available in AppKit. So how do you do it in SwiftUI? Follow below…
Setting up a share extension
Start by adding the share extension to your project
File → New → Target → Share Extension … then press Activate
During this process a new ShareViewController.swift
, MainInterface.storyboard
and Info.plist
will be created for you.
In order to build the Share Extension with SwiftUI you will need to customize the ShareViewController.
First, replace the ShareViewController
code with the below.
import SwiftUI
import UIKit
class ShareViewController: UIViewController {
@IBOutlet var container: UIView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
}
Setting up SwiftUI View
Next, it’s time to setup your SwiftUI View. Let’s begin with something simple.
struct SwiftUIView {
@State public var incoming_text: String
var body: some View {
Text(incoming_text)
}
}
Then, back in ShareViewController
add the below to viewDidLoad
to capture the incoming information from the share sheet.
// in ShareViewController
override func viewDidLoad() {
super.viewDidLoad()
// this gets the incoming information from the share sheet
if let item = extensionContext?.inputItems.first as? NSExtensionItem {
if let attachments = item.attachments {
for attachment: NSItemProvider in attachments {
if attachment.hasItemConformingToTypeIdentifier("public.text") {
attachment.loadItem(forTypeIdentifier: "public.text", options: nil, completionHandler: { text, _ in
// text variable is the text from the share sheet...
})
}
}
}
}
}
Next add the code which will embed your SwiftUI View into the ShareViewController
.
// this will add your SwiftUI View to the UIViewController
let childView = UIHostingController(rootView: AirlistShareView(name: text as! String, note: ""))
self.addChild(childView)
childView.view.frame = self.container.bounds
self.container.addSubview(childView.view)
childView.didMove(toParent: self)
The final viewDidLoad
should look like this.
// in ShareViewController
override func viewDidLoad() {
super.viewDidLoad()
// this gets the incoming information from the share sheet
if let item = extensionContext?.inputItems.first as? NSExtensionItem {
if let attachments = item.attachments {
for attachment: NSItemProvider in attachments {
if attachment.hasItemConformingToTypeIdentifier("public.text") {
attachment.loadItem(forTypeIdentifier: "public.text", options: nil, completionHandler: { text, _ in
// text variable is the text from the share sheet...
let childView = UIHostingController(rootView: SwiftUIView(incoming_text: text as! String))
self.addChild(childView)
childView.view.frame = self.container.bounds
self.container.addSubview(childView.view)
childView.didMove(toParent: self)
})
}
}
}
}
}
Now go to safari in your iOS simulator and load a website. Select some text → share. Click your app’s icon and you should see your SwiftUI View!
Communicating between ShareController and your SwiftUI View
Next you’ll want to be able to communicate between the ShareViewController
and your SwiftUI View. To do this, we will use NSNotifications
.
// at the end of viewDidLoad
NotificationCenter.default.addObserver(forName: NSNotification.Name("close"), object: nil, queue: nil) { _ in
self.close()
}
// add this function to UIShareViewController
func close() {
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
}
// in your SwiftUI View
func close() {
NotificationCenter.default.post(name: NSNotification.Name("close"), object: nil)
}
Then, to close your share extension using SwiftUI, simply call close()
.
We hate spam too. You’ll only receive periodic important Airlist information. Unsubscribe anytime.
We’re also posting regular and in-depth updates on twitter.