Reputation: 4286
How do I add the Share submenu in a Mac app? An example is Safari > File > Share. I poked at the Apple SharingServices sample code, but it does not include a working menu item.
Right now I have a button that displays a picker of available sharing services when tapped:
NSMutableArray *shareItems = [NSMutableArray arrayWithObject:[self.noteSynopsisView string]];
NSSharingServicePicker *sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:shareItems];
sharingServicePicker.delegate = self;
[sharingServicePicker showRelativeToRect:[self.shareButton bounds] ofView:self.shareButton preferredEdge:NSMaxYEdge];
I've also defined a Share submenu item under the File menu for my MainWindow.xib.
As I understand it, the NSSharingService list is being generated on the fly. So I can't really predefine the services to the menu item I have created in Interface Builder.
Thanks for your help.
Upvotes: 15
Views: 3489
Reputation: 51
Swift version:
extension NSSharingServicePicker {
class func menu(forSharingItems items: [AnyHashable]) -> NSMenu? {
let sharingServices = NSSharingService.sharingServices(forItems: items)
if sharingServices.isEmpty {
return nil
}
let menu = NSMenu()
for service in sharingServices {
let item = MenuItem(label: service.title, action: #selector(_openSharingService), target: self, userInfo: ["sharingItems": items])
item.image = service.image
item.representedObject = service
item.target = self
menu.addItem(item)
}
return menu
}
@objc class private func _openSharingService(sender: MenuItem) {
guard let items = sender.userInfo["sharingItems"] as? [AnyHashable], let service = sender.representedObject as? NSSharingService else {
return
}
service.perform(withItems: items)
}
}
class MenuItem: NSMenuItem {
var userInfo: [String : Any] = [:]
init(label: String, action: Selector?, target: AnyObject?, userInfo: [String : Any]) {
self.userInfo = userInfo
super.init(title: label, action: action, keyEquivalent: "")
}
required init(coder decoder: NSCoder) {
super.init(coder: decoder)
}
}
Upvotes: 3
Reputation: 1074
I find the gist can help you easily create a submenu of proper services. https://gist.github.com/eternalstorms/4132533
It's a NSSharingServicePicker category.
Upvotes: 7
Reputation: 969
Look at NSSharingService's +sharingServicesForItems:. In a -validateMenuItem: method you could create a submenu using the -title and -image of the NSSharingServices it returns. Associate each service with each menu item, and point the action of each menu item at this:
- (IBAction)shareFromService:(id)sender {
[[sender representedObject] performWithItems: arrayOfItemsToShare];
}
It's really quite simple. Apple did a good job on this one.
Upvotes: 17