Fetch the battery status of my MacBook with Swift - macos

I want to setup a Playground to fetch the battery status of my macbook.
I have already tried the following:
import Cocoa
import IOKit
import Foundation
var blob = IOPSCopyPowerSourcesInfo()
I am currently receiving an error as below
Use of unresolved identifier 'IOPSCopyPowerSourcesInfo'

It doesn't work in a Playground, but it works in a real app.
I couldn't access the IOPowerSources.h header file with Swift and import IOKit only, though: I had to make a bridge to Objective-C.
Here's my solution:
Add IOKit.framework to your project (click + in Linked Frameworks and Libraries)
Create a new empty .m file, whatever its name. Xcode will then ask if it should make a "bridging header". Say YES.
Ignore the .m file. In the new YOURAPPNAME-Bridging-Header.h file that Xcode just created, add the line #import <IOKit/ps/IOPowerSources.h> (and don't add import IOKit in your Swift file)
You can now access most of the IOPowerSources functions.
Example:
func getBatteryStatus() -> String {
let timeRemaining: CFTimeInterval = IOPSGetTimeRemainingEstimate()
if timeRemaining == -2.0 {
return "Plugged"
} else if timeRemaining == -1.0 {
return "Recently unplugged"
} else {
let minutes = timeRemaining / 60
return "Time remaining: \(minutes) minutes"
}
}
let batteryStatus = getBatteryStatus()
print(batteryStatus)
Note: I couldn't access constants like kIOPSTimeRemainingUnlimited and kIOPSTimeRemainingUnknown so I used their raw values (-2.0 and -1.0) but it would be better to find these constants if they still exist somewhere.
Another example, with IOPSCopyPowerSourcesInfo:
let blob = IOPSCopyPowerSourcesInfo()
let list = IOPSCopyPowerSourcesList(blob.takeRetainedValue())
print(list.takeRetainedValue())
Result:
(
{
"Battery Provides Time Remaining" = 1;
BatteryHealth = Good;
Current = 0;
"Current Capacity" = 98;
DesignCycleCount = 1000;
"Hardware Serial Number" = 1X234567XX8XX;
"Is Charged" = 1;
"Is Charging" = 0;
"Is Present" = 1;
"Max Capacity" = 100;
Name = "InternalBattery-0";
"Power Source State" = "AC Power";
"Time to Empty" = 0;
"Time to Full Charge" = 0;
"Transport Type" = Internal;
Type = InternalBattery;
}
)

Related

Freeing Protobuf generated class causes a a segment fault

Hi I am utilizing Protobuf for my personal project about neural networks.
Here is my Protobuf definitions:
syntax = "proto3";
package NGNET;
message InputLayer {
string name = 1;
uint32 size = 2;
}
message ComputeLayer {
string name = 1;
uint32 size = 2;
repeated LayerLink inputs = 3;
}
message LayerLink {
InputLayer il_input = 1;
ComputeLayer cl_input = 2;
uint32 output_size = 3;
repeated float weights = 4;
}
message NNET {
string name = 1;
repeated ComputeLayer outputs = 3;
}
The network is created like this:
ComputeLayer output1 = ComputeLayer(10, "output1");
ComputeLayer output2 = ComputeLayer(10, "output2");
ComputeLayer hidden = ComputeLayer(100, "hidden");
InputLayer input1 = InputLayer(784, "input1");
InputLayer input2 = InputLayer(784, "input2");
output1.link(&hidden);
output2.link(&hidden);
hidden.link(&input1);
hidden.link(&input2);
hidden.link(&extra);
The link functions are defined as:
void ComputeLayer::link(ComputeLayer* to_link) {
NGNET::LayerLink* link = new NGNET::LayerLink();
link->set_output_size(internal->size());
link->set_allocated_cl_input(to_link->getInternal());
internal->mutable_inputs()->AddAllocated(link);
}
void ComputeLayer::link(InputLayer* to_link) {
NGNET::LayerLink* link = new NGNET::LayerLink();
link->set_output_size(internal->size());
link->set_allocated_il_input(to_link->getInternal());
internal->mutable_inputs()->AddAllocated(link);
}
Note: The getInternal() function returns a NGNET::ComputeLayer or NGNET::InputLayer
Then the outputs are liked to a NNET with:
nnet->mutable_outputs()->AddAllocated(output1->getInternal());
nnet->mutable_outputs()->AddAllocated(output2->getInternal());
When nnet is deleted the program crashes with a segment fault.
I believe this is due to the hidden layer gets deleted twice. Is there any way I can safely free the memory that was allocated ?
Thanks.
The add_allocated_*() and set_allocated_*() methods take ownership of the pointer they are given. This means that you have to make sure that no other code will delete those pointers later, because the Protobuf implementation will delete them when the message is destroyed.
If you don't want Protobuf to take ownership of these objects, you should make copies instead:
link->mutable_il_input()->CopyFrom(*to_link->getInternal());
nnet->mutable_outputs()->Add()->CopyFrom(*output2->getInternal());
Generally, unless you are doing intense memory allocation optimizations, you probably never want to call the "allocated" protobuf accessors.

does itunes fire events that other processes on the OS can listen for?

I have an app in mind that I'm considering creating that would involve knowing what song is playing in itunes.
If itunes doesn't fire events, is there a database or some way to programatically get at what is playing in itunes?
iTunes does send out Distributed notifications. You can get complete track status by observing com.apple.iTunes.playerInfo
NSDistributedNotificationCenter.defaultCenter().addObserver(self, selector: "iTunesNotification:", name: "com.apple.iTunes.playerInfo", object: nil)
func iTunesNotification (notification:NSNotification!) {
var trackInfo:NSDictionary! = notification.userInfo
println("Track Info \(trackInfo)")
}
Sample output for a track is:
Track Info {
Album = "The Very Best Of Sting & The Police";
"Album Artist" = "Sting & The Police";
"Album Rating" = 0;
"Album Rating Computed" = 1;
Artist = "Sting & The Police";
"Artwork Count" = 1;
Composer = Sting;
Genre = Rock;
"Library PersistentID" = 3465537150503037139;
Location = "file://localhost/Users/GoodSpeed/Music/iTunes/iTunes%20Media/Music/Sting%20&%20The%20Police/The%20Very%20Best%20Of%20Sting%20&%20The%20Police/17%20Roxanne.mp3";
Name = Roxanne;
PersistentID = 716102833338382931;
"Play Count" = 1;
"Play Date" = "2013-12-28 10:43:24 +0000";
"Player State" = Playing;
"Playlist PersistentID" = 5080879747404822807;
"Rating Computed" = 1;
"Skip Count" = 0;
"Store URL" = "itms://itunes.com/link?n=Roxanne&an=Sting%20%26%20The%20Police&pn=The%20Very%20Best%20Of%20Sting%20%26%20The%20Police&cn=Sting";
"Total Time" = 190458;
"Track Number" = 17;
Year = 2002;
}

Does it worth to have a ivar instead of doing Gestalt(gestaltSystemVersion, (SInt32*)&systemVersion)?

I want to support OSX 10.6 and 10.7 so I am doing some things conditionally.
some of them are done several times in very short periods of time so I wonder if there is a gain in having a ivar that will tell me the systemVersion instead of doing
SInt32 systemVersion
Gestalt(gestaltSystemVersion, (SInt32*)&systemVersion);
That will be used :
if (systemVersion >= 0x1070){ //OSX 10.7
}else{//OSX 10.6
}
I've never used Gestalt in the past. Is Gestalt doing some kind of hard stuff or is cheap to call it every time?
Gestalt is incredibly cheap, especially when compared to something like running a separate sw_vers -productVersion to figure it out. That said, it certainly wouldn't hurt to cache it as a static variable in your implementation file. You could do something like this:
MDObject.m:
enum {
MDUndeterminedVersion = 0,
MDTiger = 0x1040,
MDLeopard = 0x1050,
MDSnowLeopard = 0x1060,
MDLion = 0x1070,
MDMountainLion = 0x1080,
MDMavericks = 0x1090,
MDUnknownVersion = 0x1100 // ??
};
static SInt32 MDSystemVersion = MDUndeterminedVersion;
#implementation
+ (void)initialize {
if (MDSystemVersion == MDUndeterminedVersion) {
SInt32 MDFullSystemVersion = 0;
Gestalt(gestaltSystemVersion, &MDFullSystemVersion);
MDSystemVersion = MDFullSystemVersion & 0xfffffff0;
}
}
- (void)someMethod {
if (MDSystemVersion >= MDLion) {
} else {
}
}
#end
+initialize is called once and (usually) only once, before an instance of that class is ever created. So, it provides a convenient place to make sure the static variable is properly determined before any of the objects are actually used.

UISegemnted COntrol - selecting 3rd segment activates second segment

I have a segmented control with 3 defined segments. i am looking to capture the segment index so I can use it in an if statement to update variables accordingly as such:
-(IBAction)numPlayers:(id)sender;
{
numPlayersSegment = [(UISegmentedControl *)sender retain];
if (numPlayersSegment.selectedSegmentIndex == 0)
{
numOfPlayers = 2;
}
else if (numPlayersSegment.selectedSegmentIndex = 1)
{
numOfPlayers = 3;
}
else if (numPlayersSegment.selectedSegmentIndex = 2)
{
numOfPlayers = 4;
}
else if (numPlayersSegment.selectedSegmentIndex = -1)
{
numOfPlayers = 0;
}
NSLog(#"Players selected = %d", numPlayersSegment.selectedSegmentIndex);
However whenever I press the third segment (index 2) it returns the value of the second segment (index 1) and also highlights the 2nd segment. I can see nothing untoward in IB.
Has anybody seen this and have any suggestions.
I am using xcode 3.2.1 on snow leopard
thanks
== and = don't function the same. At a minimum you should fix that. You also don't want the added retain to sender.

Custom text macros in Xcode not getting invoked with control-dot

I created an "ObjectiveC.xctxtmacro" file in ~/Library/Application Support/Developer/Shared/Xcode/Specifications with the code bellow. I see "Hello" in Xcode's Edit>Insert Text Macros>Objective-C menu item but when I try to invoke it using control-dot, nothing happens. Any ideas?
(
{
Identifier = objc.hello;
BasedOn = objc;
IsMenuItem = YES;
Name = "Hello";
TextString = "Hello, Xcode!";
CompletionPrefix = "hello";
IncludeContexts = ("xcode.lang.objc");
}
)
You need to add an OnlyAtBOL specification to your macro.
Try this:
(
{
Identifier = objc.hello;
BasedOn = objc;
OnlyAtBOL = YES;
IsMenuItem = YES;
Name = "Hello";
TextString = "Hello, Xcode!";
CompletionPrefix = "hello";
IncludeContexts = ("xcode.lang.objc");
}
)
I am pretty new at text macros, but as far as i understand OnlyAtBOL means that this text macro will complete only when it is at the beggining of the line (YES) or not (NO).
It seems weird that it does not work without this specification, i don' t know if it' s a bug or feature :)
You might want to check this topic, since its probably the same thing you are trying to do:
http://forums.pragprog.com/forums/104/topics/3334

Resources