Disable sleep mode in OS X with swift - xcode

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

Related

Mac OS X: interacting with an application programmatically

I am working on a project where I need to call methods on an existing application (my own) and use some of its functionality. For e.g. my application ThunderBolt runs on Mac OS X 10.10. It also provides a dictionary of events that can be called externally through Apple Script or some other way that I don't know yet.
My question is what are the different (and better) ways of interacting with an application programmatically on Mac OSX? If I use something like the following code in Apple Script Editor:
tell application "ThunderBolt"
set open_file to (choose file with prompt "Choose the file you wish to parse")
set theContents to read open_file as data
set retPict to (image convert theContents)
end tell
then it is going to launch ThunderBolt with a splash screen and then call "image convert". This can be done via NSAppleScript but still it would launch the application and call methods/events on it.
Is it possible to somehow create an instance of (or get a pointer to) one of the class inside the application and use that? Something similar to COM or automation on a Windows system?
If you're working on OS X 10.10, you might consider taking a look at JavaScript for Automation (JXA).
With it you can apparently build methods into your app that can be invoked from client scripts written in JS (although I'm not yet familiar with the particulars of how to handle implementation of such a thing on the app side). But many of the apps that ship as part of OS X Yosemite have such APIs built in (e.g. iTunes and Finder).
Here's a great tutorial on JXA written by Alex Guyot: http://www.macstories.net/tutorials/getting-started-with-javascript-for-automation-on-yosemite/
The JXA-Cookbook repo also appears to be a nice resource: https://github.com/dtinth/JXA-Cookbook/wiki
Here's a brief example - this script makes iTunes go back one track. Try it while iTunes is playing (by putting the text into Script Editor, with the language option set to JavaScript, and hitting the Run button):
iTunes = Application('iTunes')
state = iTunes.playerState()
// Console msgs show up in the Messages tab of the bottom view:
console.log("playerState: " + state)
iTunes.backTrack()
Alternatively, you can place the code into a .js file and run it on the command line:
$ osascript itunes-backTrack.js
playerState: playing
The way you specify the 'tell application' is the best way, in my opinion.
What do you do with your app that needs to be called? Maybe some of the functionalities can be done with Applescript? It would simplify things a lot.

Lock macbook screen from a sandboxed app

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.

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

OS X: Energy Efficient Web Service Calls in Background

What is the most energy efficient way to call a web service in the background under OS X?
On iOS I would use the fetch background mode, but I haven't seen anything similar for OS X. Right now I have an NSTimer that fires every 25 minutes, but the schedule gets messed up if the device goes to sleep while the timer is waiting to fire.
Before I write some code to deal with sleep/wake I wanted to see if OS X has a better mechanism for my use case. I have not found anything in the docs.

Notifications Center Alternate in MAC OS X 10.6

I have an application that fires notification 5-6 times a day on some specific times set by users. Right now I'm using Notification Center fo scheduling of notifications but unfortunately it's supported only in Mac OS X 10.8. Actually, I want my app available for the users of MAC OS X 10.6 too. For that I searched the internet and found a third party app GROWL. But here the problem is, if I use Growl, 1st it requires users to install it to get notifications from apps. 2nd and main problem is I dont think there is any functionality in GROWL to schedule notifications on particular time just like we have in Notifications Center to schedule by giving fireDate.
+[GrowlApplicationBridge
notifyWithTitle:(NSString *)title
description:(NSString *)description
notificationName:(NSString *)notificationName
iconData:(NSData *)iconData
priority:(signed int)priority
isSticky:(BOOL)isSticky
clickContext:(id)clickContext]
theres nothing to fire on a particular time in GROWL, can you please guide me to the right path ? how this can be done in 10.6 ??
Well I'm using NSTimer that will call a selector after every second to keep track of the time and checks whether notification time arrived or not. But I dont think its a good practice.

Resources