How do I open the "Share Menu" preferences on OSX? - macos

Much like Safari, trying to implement a button that when clicked opens System Preferences > Extensions > Share Menu pane.
I have tried:
NSURL *URL = [NSURL URLWithString:#"x-apple.systempreferences:com.apple.preferences.extensions?Share_Menu"];
[[NSWorkspace sharedWorkspace] openURL:URL];
However it seems like that is not working on newer versions, any ideas?

You can use Scripting Bridge to do something like this:
SBSystemPreferencesApplication *systemPrefs =
[SBApplication applicationWithBundleIdentifier:#"com.apple.systempreferences"];
[systemPrefs activate];
SBElementArray *panes = [systemPrefs panes];
SBSystemPreferencesPane *notificationsPane = nil;
for (SBSystemPreferencesPane *pane in panes) {
if ([[pane id] isEqualToString:#"com.apple.preferences.extensions"]) {
notificationsPane = pane;
break;
}
}
[systemPrefs setCurrentPane:notificationsPane];
SBElementArray *anchors = [notificationsPane anchors];
for (SBSystemPreferencesAnchor *anchor in anchors) {
if ([anchor.name isEqualToString:#"Extensions"]) {
[anchor reveal];
}
}
Of course you need to add the ScriptingBridge framework to your project and a Scripting Bridge header file for system preferences. More details on how to use Scripting Bridge you can find in the developer documentation from Apple.
Hope this helps

Since macOS Ventura (13.0) you can call the URL
x-apple.systempreferences:com.apple.preferences.extensions?Sharing

Related

Can I get YouTube to appear in the share sheet of my OS X app?

According to Apple documentation, YouTube is not included in the available sharing services, and indeed when I look at the Share Menu extensions in System Preferences I do not see it there.
Presenting the sharing sheet in my own app using NSSharingServicePicker as follows does not include YouTube either.
NSSharingServicePicker *sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:#[movieFileURL]];
[sharingServicePicker showRelativeToRect:myView.bounds ofView:myView preferredEdge:NSMinYEdge];
However when using the share sheet in QuickTime Player or iMovie, YouTube is an option, as shown below. Is there any way to get YouTube to appear as an option in my app or have Apple just added YouTube to these apps specifically without adding it to the operating system wide list?
It seems that the YouTube sharing option is not available at the operating system level and that QuickTime Player and iMovie implement it themselves. If you implement the sharing mechanism yourself (e.g. using Google's Objective C API) you can create a sharing menu containing YouTube as follows (this assumes that you have a NSSharingService subclass called YouTubeSharingService):
- (void)addSharingMenuItemsToMenu:(NSMenu *)menu {
// Get the sharing services for the file.
NSMutableArray *services = [[NSSharingService sharingServicesForItems:#[self.fileURL]] mutableCopy];
[services addObject:[YouTubeSharingService new]];
// Create menu items for the sharing services.
for (NSSharingService *service in services) {
NSMenuItem *menuItem = [[NSMenuItem alloc] init];
menuItem.title = service.menuItemTitle;
menuItem.image = service.image;
menuItem.representedObject = service;
menuItem.target = self;
menuItem.action = #selector(executeSharingService:);
[menu addItem:menuItem];
}
}
- (void)executeSharingService:(id)sender {
if ([sender isKindOfClass:[NSMenuItem class]]) {
NSMenuItem *menuItem = sender;
if ([menuItem.representedObject isKindOfClass:[NSSharingService class]]) {
NSSharingService *sharingService = menuItem.representedObject;
[sharingService performWithItems:#[self.fileURL]];
}
}
}

UIDocumentInteractionController - MailCompose not dismissing in iOS8

I have a very strange (& serious) problem.
My app uses a UIDocumentInteractionController to share a PDF document.
When the user selects the "Mail" option in the controller's pop-up the MailCompose window is opened.
But, neither the Send nor Cancel button in this window causes the MailCompose window to be dismissed, meaning the user gets stuck and has to kill the app. The mail does go out though.
Here's the catch:
This happens only in iOS8 (both versions released so far) and only on apps installed via the AppStore. That EXACT same version of the app, when running on my device via USB debugging works fine.
Here's some code:
-(void)sharePDF:(id)sender
{
#try
{
NSURL *fileURL = [NSURL fileURLWithPath:currentFileObject.LocalPath];
if(fileURL)
{
//UIDocumentInteractionController
NSString *newPath;
#try
{
//Create a copy of the file for sharing with a friendly name
if (currentFileObject.isSpecialReport)
{
newPath = [svc saveReport:[NSData dataWithContentsOfURL:fileURL] ToFile:[NSString stringWithFormat:#"%#.pdf", currentFileObject.ReportName]];
}
else
{
newPath = [svc saveReport:[NSData dataWithContentsOfURL:fileURL] ToFile:[NSString stringWithFormat:#"%#.pdf", currentFileObject.PatientFullName]];
}
}
#catch (NSException *exception) {
return;
}
NSURL *newURL = [NSURL fileURLWithPath:newPath];
self.docController = [UIDocumentInteractionController interactionControllerWithURL:newURL];
self.docController.delegate = self;
if (currentFileObject.isSpecialReport)
{
self.docController.name = [NSString stringWithFormat:#"Pathology - %#", currentFileObject.ReportName];
}
else
{
self.docController.name = [NSString stringWithFormat:#"Pathology - %#", currentFileObject.PatientFullName];
}
[self.docController presentOptionsMenuFromBarButtonItem:btnShare animated:YES];
}
}
#catch (NSException *exception) {
return;
}
}
I do not implement any of the delegate methods since non of them are required, I also do not make use of the preview functionality.
What's most puzzling to me is that the app from the AppStore behaves differently than my local one although the code is identical. My next step is to use the new beta developer tools (Test Flight) to re-publish the app, hoping that I can replicate the problem.
EDIT: I found a similar question on SO here: Cannot dismiss email sheet invoked from UIDocumentInteractionController in iOS 8
After reading that post I think it worth mentioning that I submitted the app to the AppStore via XCode 5 (the last version before XCode 6). Can that really be a factor here? Does Apple not use the same version on their side as the version in which the app was originally built?
I think this is a bug in iOS 8, and if it's still not working for you, I don't think Apple are likely to fix it. I'd upgrade to Xcode 6 and see if that fixes it for you. (It did for us, as you've discovered).

Add a button to open an URL (Preferences Bundle)

I'm trying to add a button in my Preferences Bundle to open an URL in Safari (or in the Pref Bundle).
I'm looking this: https://github.com/hbang/NotiQuiet/blob/master/prefs/ADNQListController.m
But I don't understand the else, if eccc...
I want just a button (for example "My website") that open www.mywebsite.com
Thanks all!
Add the following dictionary to your preferences plist:
{
action = link;
cell = PSButtonCell;
label = "Google";
}
And the following method to your bundle:
- (void)link {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"https://www.google.com"]];
}

NSSharingService on mountain lion without sharing window

On mountain lion, I try the new sharing possiblities with the NSSharingService class of AppKit.framework
Everything goes fine with this kind of code
NSArray* array = #[ #"myText", [NSImage imageNamed:#"myImageFile"] ];
NSSharingService* sharingServiceFB = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnFacebook];
[sharingServiceFB performWithItems:array];
But I'd like to do the same without the sharing window generated by the performWithItems function.
As I'm considering that the user of my application don't want to confirm that he want to send the message as he already have choosen that.
I don't see any "direct posting" function in this class.
Does it need to be done an other way ?
There is no way to do this other than implementing Facebook's API yourself, but if you don't mind the window appearing for half a second:
- (void)whatever {
NSArray* array = #[ #"myText", [NSImage imageNamed:#"myImageFile"] ];
NSSharingService* sharingServiceFB = [NSSharingService sharingServiceNamed:NSSharingServiceNamePostOnFacebook];
[sharingServiceFB performWithItems:array];
[self performSelector:#selector(pressReturn) withObject:nil afterDelay:0.5];
}
- (void)pressReturn {
CGEventRef keypress = CGEventCreateKeyboardEvent(NULL, 36, TRUE);
CGEventPost(kCGHIDEventTap, keypress);
}
Your users might not like it though...

How to show the share button in Mountain Lion?

Mountain Lion offers a built-in sharing button that reveals a menu of sharing services appropriate for the app:
How can I insert it in my app?
To add the share button on Mountain Lion:
1) Add a NSButton called, for example, shareButton.
2) Add the standard image for this button:
[shareButton setImage:[NSImage imageNamed:NSImageNameShareTemplate]];
[shareButton sendActionOn:NSLeftMouseDownMask];
3) Into the "on click action", present the NSSharingServicePicker:
NSSharingServicePicker *sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:urls];
sharingServicePicker.delegate = self;
[sharingServicePicker showRelativeToRect:[sender bounds]
ofView:sender
preferredEdge:NSMinYEdge];
4) Eventually, implement the NSSharingServicePickerDelegate methods to customize the picker’s available services.
In Swift, I've used this:
extension NSSharingService {
class func shareContent ( content: [AnyObject], button: NSButton ) {
let sharingServicePicker = NSSharingServicePicker (items: content )
sharingServicePicker.showRelativeToRect(button.bounds, ofView: button, preferredEdge: NSRectEdge.MaxY)
}
}
Note that if you're trying to add this button via Interface Builder:
Select the button
Switch to Attributes inspector
Delete the button Title
Insert: NSShareTemplate as the Image name.
It doesn't look right to me in XCode, but works fine when run.
PS - This appears to be a case where you need to use the System Icon string value (NSShareTemplate) instead of the constant (NSImageNameShareTemplate).

Resources