Lock macbook screen from a sandboxed app - macos

I'm building a mac app that I want to distribute in the mac app store. I need this app to have a lock screen feature.
I have 2 different approaches working, the problem is, as soon as I enable sandboxing for the app (which is required for the mac app store), neither of those approaches will work.
Do you know which entitlement I need to request? Or do you know of a third approach that will work with sandboxing?
Thanks
Approach 1, using CGSession (swift):
var arguments = ["-suspend"]
var task = NSTask()
task.arguments = arguments
task.launchPath = "/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession"
task.launch()
Approach 2, using IORequestIdle (swift):
var r = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/IOResources/IODisplayWrangler")
if (r > 0) {
IORegistryEntrySetCFProperty(r, "IORequestIdle", kCFBooleanTrue)
IOObjectRelease(r)
}

Sorry to say it can't be done. the purpose of sandboxing is to prevent an app can take the whole computer.
You might try to get a temporary exception thru the channels documented in the sandboxing guide.

Related

MacOS - requesting audio/camera permission - wrong app title shown?

We are asking for permission to use audio and camera in our Mac app. In general this works OK.
But there is one quirk. If we launch our app from another app, such as from Terminal -
When the permission prompt comes up, the app that is identifed as requesting access is the top level application ie. Terminal, not our app name.
If our app is run independently from finder (etc), the correct title shows up in the permission prompt.
I thought it might be a missing CFBundleDisplayName, but that doesn't help.
void PERMISSIONS::checkAudioPermission() const
{
if (#available(macOS 10.14, *))
{
AVAuthorizationStatus audioAuthStatus =
[AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
if (audioAuthStatus != AVAuthorizationStatusAuthorized)
{
// If the user has not definitively said Yes or No, ask them to do so.
if (audioAuthStatus == AVAuthorizationStatusNotDetermined)
{
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio
completionHandler:^(BOOL granted)
{
if (granted)
Unfortunately, this is actually a vulnerability that Apple has never fixed, which could be exploited by malware. This is discussed by Patrick Wardle at his site:
https://objective-see.com/blog/blog_0x2F.html
Therefore, I highly encourage you to file a bug, so that this can be fixed.

AXUIElementCopyAttributeNames returns cannotComplete in Cocoa App but works well in playground

I'm trying to build an utility in navigating to any visible & enabled ui-element without mouse or trackpad, so I have to enumerate those elements first.
I did some research and found maybe Accessibility APIs would help me to reach my goal. Then I tried them in playground as below :
//...
let key: String = kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String
let options = [key: true]
let enabled = AXIsProcessTrustedWithOptions(options as CFDictionary)
if !enabled {
print("Not permitted")
NSApp.terminate(nil)
}
//...
let element = AXUIElementCreateApplication(pid as! pid_t)
var ans : CFArray?
let e = AXUIElementCopyAttributeNames(element, &ans)
if e == .success, let names = ans as? [String] {
print(names)
}
//...
It works well in playground. Then I created a new Cocoa App, copied codes above into it, ran it in debug mode, and AXUIElementCopyAttributeNames return an AXError - cannotComplete.
It's very sure Xcode is enabled in System Preferences > Security and Privacy > Privacy > Accessibility. AXIsProcessTrustedWithOptions always returns true seems that it's not an issue of permission.
How can I make it works? Did I miss any necessary setting?
I'm not good in English, sorry about that.
I've solved this issue by turning off App Sandbox. I'm still curious why there is not accessibility entitlement in sandbox. Given that I have no plan to put my app in Mac App Store, to turn off App Sandbox is a solution for me.
Thanks everyone.
"With App Sandbox, you can and should enable your app for accessibility, as described in Accessibility Programming Guide for OS X. However, you cannot sandbox an assistive app such as a screen reader, and you cannot sandbox an app that controls another app."
Excerpt from https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/DesigningYourSandbox/DesigningYourSandbox.html
Playgrounds are not sandboxed and that is why it worked there.

Disable sleep mode in OS X with swift

I made an OS X Application in Xcode and I want to keep my Mac from going to sleep when I have it open. I know in iOS Swift you use:
UIApplication.sharedApplication().idleTimerDisabled = true
But how do you do it with OS X Swift?
The current way is shown in Technical QA 1340. It's ostensibly about sleep and wake notifications, but check out listing 2, entitled "Preventing sleep using I/O Kit in Mac OS X 10.6 Snow Leopard". You basically use IOPMAssertionCreateWithName to enter a state whereby sleep is disallowed, then call IOPMAssertionRelease when you're done.
I don't have sample code, as I've not personally used this, but it'd be pretty straightforward to port the code in the tech note to Swift.
Update: That API was introduced in 10.6, but still works fine in the latest OS, and as far as I know is still the preferred way to do it. Works in Swift, too.
import IOKit
import IOKit.pwr_mgt
let reasonForActivity = "Reason for activity" as CFString
var assertionID: IOPMAssertionID = 0
var success = IOPMAssertionCreateWithName( kIOPMAssertionTypeNoDisplaySleep as CFString,
IOPMAssertionLevel(kIOPMAssertionLevelOn),
reasonForActivity,
&assertionID )
if success == kIOReturnSuccess {
// Add the work you need to do without the system sleeping here.
success = IOPMAssertionRelease(assertionID);
// The system will be able to sleep again.
}
If you are trying to prevent idle triggered sleep, IOCancelPowerCharge might work. But it won't work if something manually triggers the sleep

Disable NSTask Screenshot sound

I am developing a screenshot app and I use NSTask to take the screenshot, But when app take screenshot Mac OSX default screenshout sound will be played.
let theProcess = NSTask()
theProcess.launchPath = "/usr/sbin/screencapture"
theProcess.arguments = ["/Users/profile/Desktop/111.png"]
theProcess.launch()
How can I disable it just for the current task and not generally in the mac osx.
Or It's good if I be able to change the sound.
Pass the -x argument to the command:
theProcess.arguments = ["-x", "/Users/profile/Desktop/111.png"]
More options available by running screencapture --help.

Close other applications using swift

Is there a way to close running applications in swift? For instance, if the application I create needs to close safari.
Here's a Swift 5 version for closing running applications without using AppleScript (AppleScript is a perfect way but it isn't the only way), Safari is used as the example in this case:
let runningApplications = NSWorkspace.shared.runningApplications
if let safari = runningApplications.first(where: { (application) in
return application.bundleIdentifier == "com.apple.Safari" && application.bundleURL == URL(fileURLWithPath: NSWorkspace.shared.fullPath(forApplication: "Safari")!)
}) {
// option 1
safari.terminate()
// option 2
kill(safari.processIdentifier, SIGTERM)
}
SIGTERM instead of SIGKILL, referencing from here
Of course, make sure you notify the user of this activity since this may cause negative impact on the user-experience (for example, user-generated contents in the targeted application are not saved before terminating)
It is certainly possible via an applescript directly IF:
your app is not running sandboxed (note that if you plan to distribute it via the App Store, your app will be sandboxed)
OR
your app has the necessary entitlements to use applescript: com.apple.security.scripting-targets (apple needs to approve that AND you need to know which apps to target. this isn't a blanket permission)
then
https://apple.stackexchange.com/questions/60401/how-do-i-create-an-applescript-that-will-quit-an-application-at-a-specific-time
Can you execute an Applescript script from a Swift Application
if you aren't going for App Store complicity anyways, you might also use NSTask directly
scripts / code snippets:
How to force kill another application in cocoa Mac OS X 10.5
Can you execute an Applescript script from a Swift Application
short & sweet: technically yes, 'politically' maybe :D

Resources