Set System Preferences using Objective-C - objective-c

This is probably trivial, however I couldn't find any information online: How can I set any Apple preference using code? I would like to create a little application for myself that sets certain preferences when I click a button. For instance I would like to turn off Bluetooth and Wi-Fi. As far as I know, these preferences are stored in /Users/fabian/Library/Preferences/com.apple.*.plist.
So: how can I change these preferences and make sure they are applied?

The CoreFoundation CFPreferences API allows for editing of defaults outside of the current application's defaults domain.
Note that you'll likely need administrative privileges to edit many network related defaults.

Related

Storing application settings in Moqui

I need to store and retrieve settings (with application scope). Is there anything suitable included OOTB?
My aim is to have them easy accessible from the Tools or System (for editing) menu with the ability to feed them via the gradle methods.
The entity designed for this is the UserPreference entity. There are convenience methods on the UserFacade (ec.user) for getting and setting these preferences, and they are already used for things like setting the light/dark theme, etc. There are even transitions in the apps.xml screen that can be used to set preferences, and screens that use them.

How to using ScriptingBridge in the entitlements

I wanna control 'Finder' in my app, so I can minimize Finder. I tried ScriptingBridge, but it doesn't work in Sanboxed. But it works when the app is not sandboxed. So I check the Apple's developer documents, seems that I have to set com.apple.security.scripting-targets in entitlements when I need to use ScriptingBridge in sandbox. But it doesn't say anything about the setting, so what should I do in the setting in order to control finder? Thanks in advance.
here is entitlements :
com.apple.security.scripting-targets
???????
????
Finder does not have any scripting access groups. You could add the temporary exception com.apple.security.temporary-exception.apple-events as documented here.
To find scripting targets see here: How can I know the Apple Event Access Groups used by an application?
If you'd like to distribute your app in App Store, however, you're out of luck. By scripting Finder, your app will not pass the review into the App Store.
Finder does not have any scripting access groups on purpose, because it lets you dodge sandbox file system restrictions. (As the other answer mentions, you could use the old temporary-exception.apple-events entitlement to script Finder anyway, but it won't pass store review.) Try using NSWorkspace instead, in particular the -openFile, -launchApplication, and -selectFile methods. If by "minimize" you really meant "hide", then see -[NSRunningApplication hide].

Mac Post Events to specific background windows

I am trying to create an accessibility app that will type in multiple windows at once, neither of which are owned by my app. For instance, let's say you have two Microsoft word documents open. When you hit a keystroke I want the command to go to both windows.
I have tried using Quartz events services, but it looks like it will only allow you to post to events either on a global or process level. But if two windows are running for the same process, how do I post to a specific window?
There's also the issue of the person typing in one window, while the content is being copied to the next.
Is it possible to post to a single window?
PS I know it's possible to do this in Windows
MacOS X includes a few tools which may be helpful. You should look into the Accessibility framework, Automator actions, and AppleScript. You should also be aware of application-specific solutions; in the case of Word, for example, you might look at VBA (Visual Basic for Applications). All of these tools provide ways that you can modify the content of other applications. Unfortunately, the level of support for each one varies from one application to another, and the way they're used also varies. So, it's unlikely that you'll find a single solution that works for all applications.
It's unlikely that you'll find a way to insert events directly into another process's event queue. That'd be a huge security hole, for one thing. Even if you could do that, you really wouldn't be able to target specific windows with your events. Mac applications use a responder chain that sends keystrokes to the "first responder", usually a component of the active window.

How to programmatically schedule system wake up using system preferences on a Mac?

I would like to programmatically wake up a Mac. I started off by using IOPMSchedulePowerEvent, however, that method requires admin access and privileged helpers. I've implemented and it works but is way too complicated.
I've looked around for a better approach and found that you can schedule the system to wake up by going to, System Preferences -> Energy Saver -> Schedule. Is there a way to programmatically schedule a wake up time using this method?
Thanks.
Edit: I understand the system requires admin access to schedule system wakeup and sleep time. That is ok. I would like to be able to do this programmatically. Having the user authorize the functionality is ok provided that they are only asked once. Subsequent requests to set the system wakeup time should not have to require user authorization.
Using IOPMSchedulePowerEvent is the right thing to do. However, if you create a privileged helper tool you only need to prompt the user once for his/her password. Apple's BetterAuthorizationSample code provides an example of how to do this; there's also a third-party modification, AuthorizedTasksInCocoa, which might be a bit easier to use (I haven't tried it).
I don't have a full answer for you, but this should help immensely:
http://www.opensource.apple.com/source/PowerManagement/PowerManagement-211/pmset/pmset.c
What you'll want to do is schedule a kIOPMAutoWake. Find that constant (not a variation thereof) in the code and start reading. It's not THAT long.
You can probably even use pmset directly, but that would be pretty inelegant.
As for elevating, Apple talks about it in Secure Coding Guide.
I'm pretty sure this is intended to require admin access. For example, the options in System Preferences -> Energy Saver -> Schedule are unavailable unless you're logged in as an admin or have authenticated to System Preferences as an admin. If you found a way to do it without any special privs, I'd expect Apple to regard that as a security bug, and fix it (thus breaking your program).
You can schedule wake up events with IOPMSchedulePowerEvent through the power manager. You may be able to schedule an immediate wake up. pmset is a command line wrapper for the power manager. You can also prevent sleep with IOCancelPowerChange in certain cases.
You may be able to prevent sleep or wake up by generating a mouse or key event. One way to generate events is with CGPostKeyboardEvent.
==>Normal sleep is different from clamshell closed sleep. To affect the latter you must write a kernel extension like Insomnia.

Changing provided services based on user preferences in OSX?

I would like to be able to change the OSX services that my application provides based on the current user's preferences (like adding more, changing the name,...). This basically means modifying the Info.plist (NSService key), but I don't think it is a good practice when an application modifies its own Info.plist while running, right? (At least based on few searches here). Is there any other option how to get this functionality?
I guess it should always be an external entity who does modify the Info.plist? So far I can only think about providing a system preference bundle which will do the modification in the actual app? Do you have any ideas?
Thank you
One way would be to install a service in ~/Library/Services that provides the services, and edit that application's Info.plist from your main application.
Of course, that should be an explicit action, so the user (hopefully) knows to delete the service if they delete your application. And you should document that procedure on your product's support web page, just in case they don't.
Here's a small twist to the previous recommendations, create a separate app that handles the service and bundle it within your Resources. When you want to enable the service, instead of copying the file over to ~/Library/Services, create a symbolic link within the ~/Library/Services folder that points to the app you bundled in your Resources.
This way if the user deletes your application, all that will be left behind is a symbolic link pointing to an invalid location. Does less arm than actually leaving the app behind and will have the added benefit that the service will no longer be available (since the info.plist will have been removed when the user deleted your app).