Issue #932
Add Share extension and Action extension respectively in Xcode. We can use the same code to both extension
SwiftUI
I usually make a ShareView
in SwiftUI with ShareViewModel
to control the logic
struct ShareView: View {
@ObservedObject var vm: ShareViewModel
var body: some View {
NavigationStack(path: $vm.routes) {
List {}
}
}
}
In ShareViewController, we can just conform to UIViewController
and add our SwiftUI view as child view controller
let vm = ShareViewModel()
let hostingController = UIHostingController(rootView: ShareView(vm: vm)
addChild(hostingController)
view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
hostingController.view.constrainEdges(to: view)
We can use this same ShareViewController
for both Share and Action extension, so add it to both targets.
Info.plist
In Share extension Info.plist, we can replace the default NSExtensionActivationRule
of TRUEPREDICATE
with the below.
I also use code instead of storyboard, so I use NSExtensionPrincipalClass
instead of MainInterface
<?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>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationDictionaryVersion</key>
<integer>2</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
</dict>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>
</dict>
</dict>
</plist>
In Action extension Info.plist, it looks like below
<?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>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<dict>
<key>NSExtensionActivationDictionaryVersion</key>
<integer>2</integer>
<key>NSExtensionActivationSupportsText</key>
<true/>
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<integer>1</integer>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionServiceAllowsFinderPreviewItem</key>
<true/>
<key>NSExtensionServiceAllowsTouchBarItem</key>
<true/>
<key>NSExtensionServiceFinderPreviewIconName</key>
<string>NSActionTemplate</string>
<key>NSExtensionServiceTouchBarBezelColorName</key>
<string>TouchBarBezel</string>
<key>NSExtensionServiceTouchBarIconName</key>
<string>NSActionTemplate</string>
</dict>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.ui-services</string>
</dict>
</dict>
</plist>
Icon
For Action extension, we need an icon to show in system Share dialog. We can add new App Icon to Media
asset catalog
Note that we need to specify this AppIcon
in Primary App Icon Set Name