Finish macOS Share Extension

This commit is contained in:
Maurice Parker 2020-08-14 10:25:55 -05:00
parent ee033398c1
commit eccfd5e15b
6 changed files with 115 additions and 24 deletions

View File

@ -8,6 +8,8 @@
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ShareViewController" customModule="NetNewsWire_Share_Extension" customModuleProvider="target">
<connections>
<outlet property="folderPopUpButton" destination="AZO-uN-Q3y" id="p9m-qP-eZO"/>
<outlet property="nameTextField" destination="HzY-aJ-Kyc" id="9Ql-Io-Cnk"/>
<outlet property="view" destination="1" id="2"/>
</connections>
</customObject>
@ -82,7 +84,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KT5-nj-VPk">
<rect key="frame" x="6" y="51" width="50" height="16"/>
<rect key="frame" x="6" y="53" width="50" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Folder:" id="qp4-R2-aO5">
<font key="font" metaFont="systemBold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -122,6 +124,7 @@ Gw
<constraint firstAttribute="bottom" secondItem="1uM-r7-H1c" secondAttribute="bottom" constant="10" id="4wH-De-nMF"/>
<constraint firstItem="1uM-r7-H1c" firstAttribute="top" secondItem="AZO-uN-Q3y" secondAttribute="bottom" constant="20" id="AEF-ge-ntA"/>
<constraint firstItem="6li-eA-JHO" firstAttribute="baseline" secondItem="HzY-aJ-Kyc" secondAttribute="baseline" id="B7x-4H-WTn"/>
<constraint firstItem="KT5-nj-VPk" firstAttribute="centerY" secondItem="AZO-uN-Q3y" secondAttribute="centerY" id="D7z-Lm-SzG"/>
<constraint firstItem="NVE-vN-dkz" firstAttribute="centerY" secondItem="1uM-r7-H1c" secondAttribute="centerY" id="HYN-DC-DWc"/>
<constraint firstItem="AZO-uN-Q3y" firstAttribute="trailing" secondItem="HzY-aJ-Kyc" secondAttribute="trailing" id="Hwv-Q7-40h"/>
<constraint firstItem="HzY-aJ-Kyc" firstAttribute="leading" secondItem="6li-eA-JHO" secondAttribute="trailing" constant="8" id="ItU-bg-BAi"/>
@ -130,7 +133,6 @@ Gw
<constraint firstItem="AZO-uN-Q3y" firstAttribute="leading" secondItem="HzY-aJ-Kyc" secondAttribute="leading" id="YcI-jO-fZR"/>
<constraint firstItem="1uM-r7-H1c" firstAttribute="leading" secondItem="NVE-vN-dkz" secondAttribute="trailing" constant="8" id="a8N-vS-Ew9"/>
<constraint firstItem="RbV-Vs-snd" firstAttribute="centerX" secondItem="1" secondAttribute="centerX" id="a8c-Qc-hKw"/>
<constraint firstItem="KT5-nj-VPk" firstAttribute="baseline" secondItem="AZO-uN-Q3y" secondAttribute="baseline" id="fDO-8h-qR5"/>
<constraint firstItem="KT5-nj-VPk" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="8" id="hpi-b1-IGI"/>
<constraint firstItem="RbV-Vs-snd" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="lDo-dF-3At"/>
<constraint firstItem="NVE-vN-dkz" firstAttribute="width" secondItem="1uM-r7-H1c" secondAttribute="width" id="qPo-ky-Fcw"/>

View File

@ -35,7 +35,12 @@
<key>NSExtensionAttributes</key>
<dict>
<key>NSExtensionActivationRule</key>
<string>TRUEPREDICATE</string>
<dict>
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
<integer>1</integer>
</dict>
<key>NSExtensionJavaScriptPreprocessingFile</key>
<string>SafariExt</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.share-services</string>

View File

@ -8,7 +8,7 @@
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.$(ORGANIZATION_IDENTIFIER).NetNewsWire-Evergreen</string>
<string>group.$(ORGANIZATION_IDENTIFIER).NetNewsWire</string>
</array>
</dict>
</plist>

View File

@ -7,14 +7,17 @@
//
import Cocoa
import os.log
class ShareViewController: NSViewController {
@IBOutlet weak var nameTextField: NSTextField!
@IBOutlet weak var folderPopUpButton: NSPopUpButton!
private var url: URL?
private var extensionContainers: ExtensionContainers?
private var flattenedContainers: [ExtensionContainer]!
private var selectedContainer: ExtensionContainer?
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "ShareViewController")
override var nibName: NSNib.Name? {
return NSNib.Name("ShareViewController")
}
@ -23,14 +26,38 @@ class ShareViewController: NSViewController {
super.loadView()
extensionContainers = ExtensionContainersFile.read()
flattenedContainers = extensionContainers?.flattened ?? [ExtensionContainer]()
if let extensionContainers = extensionContainers {
selectedContainer = ShareDefaultContainer.defaultContainer(containers: extensionContainers)
}
buildFolderPopupMenu()
var provider: NSItemProvider? = nil
// Try to get the URL if it is passed in
// Try to get any HTML that is maybe passed in
for item in self.extensionContext!.inputItems as! [NSExtensionItem] {
for itemProvider in item.attachments! {
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypePropertyList as String) {
provider = itemProvider
}
}
}
if provider != nil {
provider!.loadItem(forTypeIdentifier: kUTTypePropertyList as String, options: nil, completionHandler: { [weak self] (pList, error) in
if error != nil {
return
}
guard let dataGraph = pList as? NSDictionary else {
return
}
guard let results = dataGraph["NSExtensionJavaScriptPreprocessingResultsKey"] as? NSDictionary else {
return
}
if let url = URL(string: results["url"] as! String) {
self?.url = url
}
})
return
}
// Try to get the URL if it is passed in as a URL
for item in self.extensionContext!.inputItems as! [NSExtensionItem] {
for itemProvider in item.attachments! {
if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
@ -44,24 +71,27 @@ class ShareViewController: NSViewController {
if error != nil {
return
}
guard let url = urlCoded as? URL else {
if let url = urlCoded as? URL {
self?.url = url
return
}
self?.url = url
if let urlData = urlCoded as? Data {
self?.url = URL(dataRepresentation: urlData, relativeTo: nil)
}
})
}
}
@IBAction func send(_ sender: AnyObject?) {
guard let url = url, let selectedContainer = selectedContainer, let containerID = selectedContainer.containerID else {
guard let url = url, let selectedContainer = selectedContainer(), let containerID = selectedContainer.containerID else {
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
return
}
// let name = contentText.isEmpty ? nil : contentText
// let request = ExtensionFeedAddRequest(name: name, feedURL: url, destinationContainerID: containerID)
// ExtensionFeedAddRequestFile.save(request)
let name = nameTextField.stringValue.isEmpty ? nil : nameTextField.stringValue
let request = ExtensionFeedAddRequest(name: name, feedURL: url, destinationContainerID: containerID)
ExtensionFeedAddRequestFile.save(request)
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
@ -72,3 +102,55 @@ class ShareViewController: NSViewController {
}
}
private extension ShareViewController {
func buildFolderPopupMenu() {
let menu = NSMenu(title: "Folders")
menu.autoenablesItems = false
guard let extensionContainers = extensionContainers else {
folderPopUpButton.menu = nil
return
}
let defaultContainer = ShareDefaultContainer.defaultContainer(containers: extensionContainers)
var defaultMenuItem: NSMenuItem? = nil
for account in extensionContainers.accounts {
let menuItem = NSMenuItem(title: account.name, action: nil, keyEquivalent: "")
menuItem.representedObject = account
if account.disallowFeedInRootFolder {
menuItem.isEnabled = false
}
menu.addItem(menuItem)
if defaultContainer?.containerID == account.containerID {
defaultMenuItem = menuItem
}
for folder in account.folders {
let menuItem = NSMenuItem(title: folder.name, action: nil, keyEquivalent: "")
menuItem.indentationLevel = 1
menuItem.representedObject = folder
menu.addItem(menuItem)
if defaultContainer?.containerID == folder.containerID {
defaultMenuItem = menuItem
}
}
}
folderPopUpButton.menu = menu
folderPopUpButton.select(defaultMenuItem)
}
func selectedContainer() -> ExtensionContainer? {
return folderPopUpButton.selectedItem?.representedObject as? ExtensionContainer
}
}

View File

@ -73,7 +73,6 @@
5108F6D22375EED2001ABC45 /* TimelineCustomizerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D12375EED2001ABC45 /* TimelineCustomizerViewController.swift */; };
5108F6D42375EEEF001ABC45 /* TimelinePreviewTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */; };
5108F6D823763094001ABC45 /* TickMarkSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5108F6D723763094001ABC45 /* TickMarkSlider.swift */; };
510C415F24E5CDE3008226FD /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 510C415E24E5CDE3008226FD /* icon.icns */; };
510C416124E5CDE3008226FD /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 510C416024E5CDE3008226FD /* ShareViewController.swift */; };
510C416424E5CDE3008226FD /* ShareViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 510C416224E5CDE3008226FD /* ShareViewController.xib */; };
510C416924E5CDE3008226FD /* NetNewsWire Share Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 510C415C24E5CDE3008226FD /* NetNewsWire Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@ -654,6 +653,8 @@
51EF0F902279C9500050506E /* AccountsAddViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF0F8F2279C9500050506E /* AccountsAddViewController.swift */; };
51EF0F922279CA620050506E /* AccountsAddTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51EF0F912279CA620050506E /* AccountsAddTableCellView.swift */; };
51EFDA1A24E6159C0085C3D6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849C64671ED37A5D003D8FC0 /* Assets.xcassets */; };
51EFDA1B24E6D16A0085C3D6 /* SafariExt.js in Resources */ = {isa = PBXBuildFile; fileRef = 515D4FCB2325815A00EE1167 /* SafariExt.js */; };
51EFDA1D24E6E27E0085C3D6 /* icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 51EFDA1C24E6E27E0085C3D6 /* icon.icns */; };
51F85BEB22724CB600C787DC /* About.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 51F85BEA22724CB600C787DC /* About.rtf */; };
51F85BEF2272520B00C787DC /* Thanks.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 51F85BEE2272520B00C787DC /* Thanks.rtf */; };
51F85BF12272524100C787DC /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 51F85BF02272524100C787DC /* Credits.rtf */; };
@ -1474,7 +1475,6 @@
5108F6D32375EEEF001ABC45 /* TimelinePreviewTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinePreviewTableViewController.swift; sourceTree = "<group>"; };
5108F6D723763094001ABC45 /* TickMarkSlider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TickMarkSlider.swift; sourceTree = "<group>"; };
510C415C24E5CDE3008226FD /* NetNewsWire Share Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "NetNewsWire Share Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
510C415E24E5CDE3008226FD /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = "<group>"; };
510C416024E5CDE3008226FD /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
510C416324E5CDE3008226FD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/ShareViewController.xib; sourceTree = "<group>"; };
510C416524E5CDE3008226FD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -1757,6 +1757,7 @@
51EF0F8D2279C9260050506E /* AccountsAdd.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AccountsAdd.xib; sourceTree = "<group>"; };
51EF0F8F2279C9500050506E /* AccountsAddViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddViewController.swift; sourceTree = "<group>"; };
51EF0F912279CA620050506E /* AccountsAddTableCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsAddTableCellView.swift; sourceTree = "<group>"; };
51EFDA1C24E6E27E0085C3D6 /* icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = icon.icns; sourceTree = "<group>"; };
51F805D32428499E0022C792 /* NetNewsWire-dev.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "NetNewsWire-dev.entitlements"; sourceTree = "<group>"; };
51F805ED24284C1C0022C792 /* NetNewsWire-dev.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "NetNewsWire-dev.entitlements"; sourceTree = "<group>"; };
51F85BEA22724CB600C787DC /* About.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = About.rtf; sourceTree = "<group>"; };
@ -2269,7 +2270,7 @@
510C415D24E5CDE3008226FD /* ShareExtension */ = {
isa = PBXGroup;
children = (
510C415E24E5CDE3008226FD /* icon.icns */,
51EFDA1C24E6E27E0085C3D6 /* icon.icns */,
510C416024E5CDE3008226FD /* ShareViewController.swift */,
510C416224E5CDE3008226FD /* ShareViewController.xib */,
510C416524E5CDE3008226FD /* Info.plist */,
@ -2384,7 +2385,6 @@
51A9A5E52380C8B20033AADF /* ShareFolderPickerFolderCell.xib */,
513C5CEA232571C2003D4054 /* MainInterface.storyboard */,
513C5CED232571C2003D4054 /* Info.plist */,
515D4FCB2325815A00EE1167 /* SafariExt.js */,
515D4FCD2325909200EE1167 /* NetNewsWire_iOS_ShareExtension.entitlements */,
);
path = ShareExtension;
@ -2600,6 +2600,7 @@
51B5C85A23F22A7A00032075 /* ShareExtension */ = {
isa = PBXGroup;
children = (
515D4FCB2325815A00EE1167 /* SafariExt.js */,
51B5C87623F22B8200032075 /* ExtensionContainers.swift */,
51B5C87C23F2346200032075 /* ExtensionContainersFile.swift */,
51B5C87A23F2317700032075 /* ExtensionFeedAddRequest.swift */,
@ -4076,8 +4077,9 @@
buildActionMask = 2147483647;
files = (
510C416424E5CDE3008226FD /* ShareViewController.xib in Resources */,
51EFDA1D24E6E27E0085C3D6 /* icon.icns in Resources */,
51EFDA1A24E6159C0085C3D6 /* Assets.xcassets in Resources */,
510C415F24E5CDE3008226FD /* icon.icns in Resources */,
51EFDA1B24E6D16A0085C3D6 /* SafariExt.js in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};