Cocoa button opens a System Preference page
Asked Answered
F

3

23

In a OSX Cocoa app, I would like a button that would open the "speech" preference pane. Is that possible? I'm just trying to save them the time to go System Preferences > Speech > Text to Speech

Faye answered 11/7, 2011 at 15:31 Comment(0)
K
22

The following is a fairly easy (and reliable) way to at least get System Preferences open to the Speech.prefPane:

- (IBAction)openSpeechPrefs:(id)sender {
    [[NSWorkspace sharedWorkspace] openURL:
     [NSURL fileURLWithPath:@"/System/Library/PreferencePanes/Speech.prefPane"]];
}

However, it won't necessarily be switched to the Text to Speech tab, but rather the last tab the user had selected.

It is possible to actually switch to the Text to Speech tab as well, but it's a bit more involved. You can use AppleScript to send commands to the System Preferences application, but using the ScriptingBridge.framework (See Scripting Bridge Programming Guide) is much faster.

You'll need to add the ScriptingBridge.framework to your project, and then use a command like the following in Terminal to generate a SBSystemPreferences.h header file to work with:

sdef "/Applications/System Preferences.app" | sdp -fh --basename SBSystemPreferences -o ~/Desktop/SBSystemPreferences.h

Add that SBSystemPreferences.h header to your project, then change -openSpeechPrefs: to the following:

- (IBAction)openSpeechPrefs:(id)sender {
    SBSystemPreferencesApplication *systemPrefs = 
    [SBApplication applicationWithBundleIdentifier:@"com.apple.systempreferences"];

    [systemPrefs activate];

    SBElementArray *panes = [systemPrefs panes];
    SBSystemPreferencesPane *speechPane = nil;

    for (SBSystemPreferencesPane *pane in panes) {
        if ([[pane id] isEqualToString:@"com.apple.preference.speech"]) {
            speechPane = pane;
            break;
        }
    }
    [systemPrefs setCurrentPane:speechPane];

    SBElementArray *anchors = [speechPane anchors];

    for (SBSystemPreferencesAnchor *anchor in anchors) {
        if ([anchor.name isEqualToString:@"TTS"]) {
            [anchor reveal];
        }
    }
}

EDIT:

Sample project using the ScriptingBridge.framework method: http://github.com/NSGod/OpenSystemPrefsTTS

Klink answered 12/7, 2011 at 0:16 Comment(4)
I typed the sdef command in terminal, got the following error and warning: sdp: error: class "pane" inherits from undefined class "item". sdp: error: class "anchor" inherits from undefined class "item". So I cannot get the header file.Uphill
@Klink Mavericks. And I found that you would get the header though there were errors and warnings.Uphill
This method does not work for sandboxed apps. Atleast in yosemiteSussex
For Yosemite you would just do something like: x-apple.systempreferences://SpeechPrehensible
G
48

One can even select specific sub item inside a pref pane. Here is example to select Camera under Privacy pane:

NSURL *URL = [NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Camera"];
[[NSWorkspace sharedWorkspace] openURL:URL];

Some credit goes to following site: https://macosxautomation.com/system-prefs-links.html

List of URLs for reference (*updated for macOS Big Sur & Catalina & Mojave):

Accessibility Preference Pane
Main    x-apple.systempreferences:com.apple.preference.universalaccess
Display x-apple.systempreferences:com.apple.preference.universalaccess?Seeing_Display
Zoom    x-apple.systempreferences:com.apple.preference.universalaccess?Seeing_Zoom
VoiceOver   x-apple.systempreferences:com.apple.preference.universalaccess?Seeing_VoiceOver
Descriptions    x-apple.systempreferences:com.apple.preference.universalaccess?Media_Descriptions
Captions    x-apple.systempreferences:com.apple.preference.universalaccess?Captioning
Audio   x-apple.systempreferences:com.apple.preference.universalaccess?Hearing
Keyboard    x-apple.systempreferences:com.apple.preference.universalaccess?Keyboard
Mouse & Trackpad    x-apple.systempreferences:com.apple.preference.universalaccess?Mouse
Switch Control  x-apple.systempreferences:com.apple.preference.universalaccess?Switch
Dictation   x-apple.systempreferences:com.apple.preference.universalaccess?SpeakableItems

Security & Privacy Preference Pane
Main    x-apple.systempreferences:com.apple.preference.security
General x-apple.systempreferences:com.apple.preference.security?General
FileVault   x-apple.systempreferences:com.apple.preference.security?FDE
Firewall    x-apple.systempreferences:com.apple.preference.security?Firewall
Advanced    x-apple.systempreferences:com.apple.preference.security?Advanced
Privacy x-apple.systempreferences:com.apple.preference.security?Privacy
Privacy-Camera x-apple.systempreferences:com.apple.preference.security?Privacy_Camera
Privacy-Microphone  x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone
Privacy-Automation  x-apple.systempreferences:com.apple.preference.security?Privacy_Automation
Privacy-AllFiles    x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles
Privacy-Accessibility   x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility
Privacy-Assistive   x-apple.systempreferences:com.apple.preference.security?Privacy_Assistive
Privacy-Location Services   x-apple.systempreferences:com.apple.preference.security?Privacy_LocationServices
Privacy-SystemServices  x-apple.systempreferences:com.apple.preference.security?Privacy_SystemServices
Privacy-Advertising x-apple.systempreferences:com.apple.preference.security?Privacy_Advertising
Privacy-Contacts    x-apple.systempreferences:com.apple.preference.security?Privacy_Contacts
Privacy-Diagnostics & Usage x-apple.systempreferences:com.apple.preference.security?Privacy_Diagnostics
Privacy-Calendars   x-apple.systempreferences:com.apple.preference.security?Privacy_Calendars
Privacy-Reminders   x-apple.systempreferences:com.apple.preference.security?Privacy_Reminders
Privacy-Facebook    x-apple.systempreferences:com.apple.preference.security?Privacy_Facebook
Privacy-LinkedIn    x-apple.systempreferences:com.apple.preference.security?Privacy_LinkedIn
Privacy-Twitter x-apple.systempreferences:com.apple.preference.security?Privacy_Twitter
Privacy-Weibo   x-apple.systempreferences:com.apple.preference.security?Privacy_Weibo
Privacy-Tencent Weibo   x-apple.systempreferences:com.apple.preference.security?Privacy_TencentWeibo

macOS Catalina 10.15:
Privacy-ScreenCapture   x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture
Privacy-DevTools    x-apple.systempreferences:com.apple.preference.security?Privacy_DevTools
Privacy-InputMonitoring x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent
Privacy-DesktopFolder   x-apple.systempreferences:com.apple.preference.security?Privacy_DesktopFolder
Privacy-DocumentsFolder x-apple.systempreferences:com.apple.preference.security?Privacy_DocumentsFolder
Privacy-DownloadsFolder x-apple.systempreferences:com.apple.preference.security?Privacy_DownloadsFolder
Privacy-NetworkVolume   x-apple.systempreferences:com.apple.preference.security?Privacy_NetworkVolume
Privacy-RemovableVolume x-apple.systempreferences:com.apple.preference.security?Privacy_RemovableVolume
Privacy-SpeechRecognition   x-apple.systempreferences:com.apple.preference.security?Privacy_SpeechRecognition

macOS Big Sur 10.11/10.16:
Privacy-Bluetooth   x-apple.systempreferences:com.apple.preference.security?Privacy_Bluetooth
Privacy-Music   x-apple.systempreferences:com.apple.preference.security?Privacy_Media
Privacy-Home    x-apple.systempreferences:com.apple.preference.security?Privacy_HomeKit

macOS Monterey 12.0:
Privacy-DoNotDisturb    x-apple.systempreferences:com.apple.preference.security?Privacy_Focus

macOS Ventura 13.0:
Privacy-AppBundles    x-apple.systempreferences:com.apple.preference.security?Privacy_AppBundles
Privacy-ListenEvent    x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent


Dictation & Speech Preference Pane
Dictation   x-apple.systempreferences:com.apple.preference.speech?Dictation
Text to Speech  x-apple.systempreferences:com.apple.preference.speech?TTS
Sharing Preference Pane
Main    x-apple.systempreferences:com.apple.preferences.sharing
Screen Sharing  x-apple.systempreferences:com.apple.preferences.sharing?Services_ScreenSharing
File Sharing    x-apple.systempreferences:com.apple.preferences.sharing?Services_PersonalFileSharing
Printer Sharing x-apple.systempreferences:com.apple.preferences.sharing?Services_PrinterSharing
Remote Login    x-apple.systempreferences:com.apple.preferences.sharing?Services_RemoteLogin
Remote Management   x-apple.systempreferences:com.apple.preferences.sharing?Services_ARDService
Remote Apple Events x-apple.systempreferences:com.apple.preferences.sharing?Services_RemoteAppleEvent
Internet Sharing    x-apple.systempreferences:com.apple.preferences.sharing?Internet
Bluetooth Sharing   x-apple.systempreferences:com.apple.preferences.sharing?Services_BluetoothSharing

Software update x-apple.systempreferences:com.apple.preferences.softwareupdate?client=softwareupdateapp

Paswords x-apple.systempreferences:com.apple.Passwords-Settings.extension?Options

All this is possible thanks to key in Info.plist in preferencePane + CFBundleURLTypes (CFBundleURLSchemes) x-apple.systempreferences (Info.plist) in System Preferences.app

NSPrefPaneAllowsXAppleSystemPreferencesURLScheme

As of 10.15 some of the keys are located in PrivacyTCCServices.plist (Security.prefPane)

As of 10.14 Mojave some Privacy keys ceased to exists. Mojave privacy list:enter image description here

Catalina privacy list: enter image description here

Gardia answered 7/1, 2018 at 17:43 Comment(5)
Thanks! Is there a way to open Software Update panel to the "Automatic updates" info button (i) in macOS Ventura as well by any chance? Thanks for your help.Incense
@marek-h is this allowed in the AppStore? If not is there an approved way?Spade
@Spade Yes all is approved and widely usedGardia
@MarekH Where from did you got this information? Is there exist information about Sonoma?Disassemble
@Disassemble This was in 2018 by reverse engineering. Steps are included. macOS has changed since so internally Ventura/Sonoma is different as they use new system preferencesGardia
K
22

The following is a fairly easy (and reliable) way to at least get System Preferences open to the Speech.prefPane:

- (IBAction)openSpeechPrefs:(id)sender {
    [[NSWorkspace sharedWorkspace] openURL:
     [NSURL fileURLWithPath:@"/System/Library/PreferencePanes/Speech.prefPane"]];
}

However, it won't necessarily be switched to the Text to Speech tab, but rather the last tab the user had selected.

It is possible to actually switch to the Text to Speech tab as well, but it's a bit more involved. You can use AppleScript to send commands to the System Preferences application, but using the ScriptingBridge.framework (See Scripting Bridge Programming Guide) is much faster.

You'll need to add the ScriptingBridge.framework to your project, and then use a command like the following in Terminal to generate a SBSystemPreferences.h header file to work with:

sdef "/Applications/System Preferences.app" | sdp -fh --basename SBSystemPreferences -o ~/Desktop/SBSystemPreferences.h

Add that SBSystemPreferences.h header to your project, then change -openSpeechPrefs: to the following:

- (IBAction)openSpeechPrefs:(id)sender {
    SBSystemPreferencesApplication *systemPrefs = 
    [SBApplication applicationWithBundleIdentifier:@"com.apple.systempreferences"];

    [systemPrefs activate];

    SBElementArray *panes = [systemPrefs panes];
    SBSystemPreferencesPane *speechPane = nil;

    for (SBSystemPreferencesPane *pane in panes) {
        if ([[pane id] isEqualToString:@"com.apple.preference.speech"]) {
            speechPane = pane;
            break;
        }
    }
    [systemPrefs setCurrentPane:speechPane];

    SBElementArray *anchors = [speechPane anchors];

    for (SBSystemPreferencesAnchor *anchor in anchors) {
        if ([anchor.name isEqualToString:@"TTS"]) {
            [anchor reveal];
        }
    }
}

EDIT:

Sample project using the ScriptingBridge.framework method: http://github.com/NSGod/OpenSystemPrefsTTS

Klink answered 12/7, 2011 at 0:16 Comment(4)
I typed the sdef command in terminal, got the following error and warning: sdp: error: class "pane" inherits from undefined class "item". sdp: error: class "anchor" inherits from undefined class "item". So I cannot get the header file.Uphill
@Klink Mavericks. And I found that you would get the header though there were errors and warnings.Uphill
This method does not work for sandboxed apps. Atleast in yosemiteSussex
For Yosemite you would just do something like: x-apple.systempreferences://SpeechPrehensible
U
0

For the guys who run into the same issue that I mentioned in the comment, just go to the ~/Desktop (cos I specify this position) and you'll see the SBSystemPreferences.h has been created.

However, in this header, some class declarations are missing. So you have to add this declarations explicitly.

In my case, class "item" is undefined. So add this: @class SBSystemPreferencesItem;

Then compile it and see what's still missing, which declaration needs to be added.

Uphill answered 29/10, 2013 at 3:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.