App Fixer beta now available! 💥

app fixer
I’ve just released the first beta 0.1 version of App Fixer over on my software distribution site, Sqwarq.com.

App Fixer aims to help you remove corrupt preference files and window Saved States that can sometimes cause apps to crash on launch or during normal operation. Traditionally, we have to go hunting through the user library hoping to identify the correct files to remove. Now, App Fixer does it for you.

If you have an app that won’t launch or that’s behaving badly, or you just want to start with a clean slate by removing user defaults/preferences (I’m looking at you Photoshop!), App Fixer will do it for you in a click.

Grab a free copy of the beta from here: http://sqwarq.com/appfixer

:)


About these ads

change the Dock position

dock position
One of Yosemite’s minor irritations is the removal of the Dock position menu item from the Apple menu.

Now we’re supposed to go hunting around on the Dock for the tiny Dock item separator and control-click it to get the menu, or open up System Preferences > Dock. All too fiddly for my taste.

The following script will rotate the Dock position through left, bottom and right. Just copy the code below and paste straight into a Script Editor document. Hit the Run button to see it in action. Then, save the script to your ~/Library/Scripts folder. Use FastScripts or set up a Service with Automator (example here) to create a hotkey.

Now you can change the Dock position with ease. :)

tell application "System Events"
 tell dock preferences
   set x to screen edge
   if x is left then
    set properties to {screen edge:bottom}
   else if x is bottom then
    set properties to {screen edge:right}
   else
    set properties to {screen edge: left}
   end if
  end tell
end tell

how to remove Dropbox green blobs

Screen Shot 2014-10-24 at 15.32.36

If like me, you’re not impressed with Dropbox drawing huge green blobs all over your Finder windows without even asking, here’s a great tip from Zackary Corbett for getting rid of them. Run the following line in Terminal:

pluginkit -e ignore -i com.getdropbox.dropbox.garcon

And you’ll be blessed with some visual peace and quiet:

Screen Shot 2014-10-24 at 15.33.25

If you want to reverse the effect and enjoy the green blobs again, use this line:

pluginkit -e use -i com.getdropbox.dropbox.garcon

Thanks Zachary :)




how to troubleshoot your mac with FT2

FastTasks 2
Macs are famously reliable beasts, but we often make changes to our machines that can cause unexpected behaviours such as the dreaded spinning “beachball” (i.e., slow response times), excessive fan noise, and crashes.

This is where Apple Support Communities comes in handy, a place where I spent the best part of my spare time for 2 years helping thousands of people solve problems with their macs. With a few rare exceptions of internal hardware malfunction, the majority of problems I’ve encountered with macs involve changes made to the mac by installing or removing third-party software (sometimes unwittingly).

There was a time when people seeking help on ASC were first told to go through a lengthy process of collecting arcane information from various deep and mysterious places on their computer before ASC support volunteers could help determine the problem. Fortunately, there’s now a number of free utilities available that will collect some or all of that information for you automatically, including etrecheck (by ASC member Etresoft), AdMedic (by ASC member Thomas Reed) and my own FastTasks 2.

In this post, I’m going to assume you’re using FastTasks 2, for a couple of reasons (aside from the obvious one that its my own app!). First, aside from having a system profiler, FT2 provides other functions that are useful in troubleshooting, whose use I’ll indicate below. Secondly, unlike other analysers, FT2 not only profiles your system configuration at the time you run it, it can also show you what’s changed over time (see Step 5 below), making detection of new problems even faster and easier. For that reason, it’s a good idea to run FT2 when your system is trouble-free so that you have a log of a known ‘good’ configuration. However, I’m going to assume for most of this post that you don’t have a log of a known good state, and walk you through a series of steps that you can use to trackdown troublemakers.

To get started, download FT2 from here, and then proceed to Step 1.

*Note if your problem is with Safari, you can go straight to Step 10.

If your problem is with internet connections / networking, that’s a vast issue too large for this post, but try the advice here first. If that doesn’t work, the FT2’s Profile view contains a lot of information about your network configuration. Click the FT2 menu, choose ‘Analyser > Check now’, and click the Profile tab. Then follow the general advice in Step 11 below.

If your problem involves unusual behaviour of system hardware (keyboard lights, fans, system volume, etc) follow Step 3 of this post first.


Step 1. Put a block behind the rear wheel…
The first rule of troubleshooting is not ‘You don’t talk about troubleshooting’ but ‘You don’t do anything until you have a backup stashed away’. Fat fingers and a hasty desire for a cure can lead all of us to make mistakes when following procedures, and the last thing you want to do is accidentally delete some file or resource that is irreplaceable. So, back up first, and cure yourself of the tendency to rush for a solution. Troubleshooting takes time, and troubleshooting without a backup is like changing a wheel on your car without putting a block behind the rear wheel. Don’t get crushed by your own rush to get back on the road!


Step 2. Start with the obvious…
Launch FastTasks and wait for the system analyser to finish loading. You’ll see the analyser presents you with an ‘Issues’ page. This page lists any files or apps that are installed on your computer which have, in my experience, been known to cause problems for some users. If your system is clean of these files or apps, the page will be empty, like mine:

Issues

If anything is listed in the ‘Issues’ page, your first step is to deal with these as detailed below. If not, you can go straight to Step 3 now.

Depending on the issue, (click on an item in the FT2 window and press the ‘Info’ button), uninstall, delete or move to a temporary folder on your Desktop any items listed in the Issues page. You can open each item in the Finder either by double-clicking it in the FT2 window, or selecting it and clicking the ‘Reveal’ button.

If anything listed in the Analyser as a ‘Performance’ issue has been installed from outside of the App Store, check the Developer’s web pages to see if there is an uninstaller and, if so, use that. If not, move the App or files to the Trash, but do not empty it. At the end of this step, if it turns out that app or file is not the culprit, and you still want to use it for some reason, you can drag it back out of the Trash.

After dealing with anything in the ‘Issues’ list, restart your mac and see if the problem behaviour is solved.


Step 3. Wipe the board…
If you didn’t have any issues, click the FT2 icon in the menu bar and note the system information in the lower half of the menu. Look at the ‘Uptime’ stat. This shows how long since you last rebooted your machine. If the problem behaviour has only been noticed since the last reboot, then restart your machine now, and test again.

Uptime

More often than not, most unexpected or strange behaviour that comes out of nowhere can be solved by a system reboot.


Step 4. Check the disk
Click the FT2 icon and note the system information in the lower half of the menu. Look at the empty/full icon and the stats below it on disk usage (you can choose to have one of these shown in the menu bar all the time if you wish, as well as change the color of the icon. In the menu, choose Preferences > Menu Bar Icon). You should have got a warning from FT2 if your disk is gettting critically full, but even if your disk is only 70% or so full, you could find your machine slowing down when Spotlight is indexing or if you’re doing any operation that requires a lot of disk activity. My recommendation for a speedy machine is to keep disk usage below 60% if possible (I rarely let my own disk ever get above 50%).

While we’re thinking about the disks, let’s just check the S.M.A.R.T status of the Internal boot disk. With the FT2 window open (if not, click ‘Analyser > Check now’), click the ‘Profile’ tab. Scroll down right to the bottom of the page and check that the S.M.A.R.T status says ‘verified’. If it doesn’t, there’s your problem: you need to replace your hard disk ASAP.

SMART


Step 5. Reverse gear…
If you’ve ran FT2 before, anything that’s changed since the last time you ran it will be highlighted in the view (you’ll also see the yellow warning triangle at the top).


Screen Shot 2014-10-22 at 21.26.22For example, in the screenshot above, note how FT2 records that the Ghostery extension has installed an update of itself in the background!

If you haven’t run FT2 before, go to Step 6. If you’ve run FT2 before but no changes are indicated, look through the logs by using the back and forward arrows on either side of the ‘Run’ button. For convenience, you can click the ‘Console’ button, then type ‘added’ into Console’s search bar, making a note of anything shown, then type ‘removed’, again making a note of any changes.

Whether you find changes in the Console, logs, or indicated in FT2’s current Profile view, the process is the same. For any change indicated, you need to reverse it. That means, anything added should be removed, and anything removed should be replaced from a backup. However, it’s important to be methodical, so deal with one change at a time, restarting the system and checking for the problem again after reversing each change. If that doesn’t solve it, move on to the next change and repeat.

There’s such a high chance that you’ll discover the cause of the problem this way that its the best argument for running FT2 on a regular basis and before you hit trouble. Trouble always starts with some change…

If you’re still encountering problems, go to Step 6.


Step 6. The root of all Evil…
Well, maybe not all, but without doubt the overwhelming cause of problems I’ve dealt with on ASC were caused by login items. These are things that automatically run when you log in to your account. Any app or script that’s in your Login Items that causes problems to your system will affect your system from the start of your session and often right through till you log out (often regardless of whether you quit the app in mid-session).

With FT2’s Analyser window open, click the ‘Profile’ tab. At the very top of the page, check what and how many items are in your Login Items. You really don’t want more than four or five items in here in any case, or you’ll notice a real lag betweeen when you log in and when your system is ready to be used. Keep only the essential things in here (yes, I’d say FT2 is one of them, see the end of this Step).

However, even one app can cause problems if it’s the wrong app. To troubleshoot Login Items, click the FT2 menu and choose ‘Login Items > Remove All’. Click ‘OK’ to confirm. When you see the notification that Login Items are empty, restart your mac and test for the problem.

loginitems

If the problem is not solved, go to Step 7. If the problem is solved, you can try adding each of your login items back in one at a time to ascertain which item caused the problem. Better still, just keep your login items empty and enjoy faster start up times.

The exception to the above advice is to consider keeping FT2 in your Login Items. The reason is that every time you login in, FT2 will run a background profile check and store that in its logs. That’s a vital tool for solving troubleshooting problems in the future (see Step 5 above), and one of FT2’s most useful features (however, if you don’t want FT2 to start on login, choose ‘Preferences > Start at Login’ and click to remove the tick).


Step 7. Digging deeper…

First, a note about .DS_Store files: In this and the remaining steps, you can ignore any file called .DS_Store shown in the profiler. These are hidden files generated by the Finder and can be ignored (likewise, you can delete them, the system will just recreate them when it needs to).

If you’ve got this far and your problem persists, it’s time to start looking further down the profile list. The next item in the profile view is User Launch Daemons. Notice that FT2 handily shows you where you can find this directory. To use that info, highlight the path shown (omit the closing bracket), then control-click, and choose ‘Services > Reveal in Finder’, to open the directory.

I do NOT recommend deleting files from here directly. Instead, you need to identify which apps these files belong to and uninstall them. After uninstalling, check back in Launch Agents to see if the uninstaller has cleaned up the file. If it hasn’t, you can then delete it (but be sure you’re deleting the correct file).

If the file doesn’t appear to belong to an app or you’re in doubt about its parentage, then move it (don’t delete it) to your Desktop. As with Login Items in the previous step, you need to be methodical here, and test each item after you remove or uninstall it with a reboot. Doing so means you can firmly determine which apps and files are OK and which are suspect.


Step 8: and deeper…
If your problems remain after working through all the User Launch Daemons, scroll much further down the list until you find Domain Library Launch Agents and Domain Library Launch Daemons and Domain Library StartUpItems. For each, you need to follow the procedure in Step 7: in other words, start by identifying the parent app of the file in the directory, uninstall it, check its cleaned up the file in the directory (if not, move it to your desktop) and re-test.


Step 9: Problems, problems, problems…
Still not got to the bottom of it? Then we need some more info. The best thing to do right now is determine whether the problem only affects your user account or all users on your system. Knowing this will provide a better focus for continued efforts.

To do that, go to  > System Preferences > Users & Groups and click the padlock and supply an Admin password to open it. You’ll now be able to click the little ‘+’ button just above the padlock and create an extra Admin account.

After creating the account, restart the mac, log in to the new account and see if the problem affects that account too. Once you’ve determined that, log back into your normal account and go to Step 11 below.


Step 10: Safari and the internet
Problems with Safari and internet connections are a realm all to themselves and too vast to be discussed here except in general terms.

If the problem appears to be peculiar to Safari, then the first thing to do is open FT2 Analyser and click on the ‘Profile’ page. Scroll down to Safari Extensions and take a look at what’s in there. Anything you don’t recognize or anything new since things were hunky dory? If so, focus on that first.

To deal with Extensions, don’t delete things from the directory itself. Instead, open Safari, and from the menu bar choose “Safari > Preferences” and navigate to the ‘Extensions’ tab.

Start by disabling ALL extensions. Now restart Safari. Problem solved? If yes, then start turning one extension back on at a time, until you discover which one is causing the problem. Uninstall the culprit.

If the problem persists after disabling all extensions, go back to FT2’s Profile view and scroll down till you get to User Library Internet Plug-Ins. If there is anything in here (you can ignore .DS_Store), then select the path shown for the directory (omiting the word ‘path:’ and the closing bracket), right-click and choose ‘Services > Reveal in Finder’. Move anything in the folder to your Desktop. Restart the mac and test.

If the problem is solved, try moving each item back to the Internet Plug-Ins folder, one at a time, restarting and testing after each move until you determine the culprit.

If the problem is not solved, return any items you moved to the Desktop back to the Internet Plug-Ins folder. Then, check to see whether other browsers are affected (if you don’t have it already, it’s always a good idea to keep a copy of Firefox on you mac, just to use as a control for Safari tests if nothing else). Make a note of the answer, then follow the instructions in Step 9 above, then go to Step 11 below.


Step 11: What to do next…
I hope this post has helped solve your problems, but if it hasn’t don’t panic. Your best resource is Apple Support Communities. Though I’m no longer active there (my spare time is used for software development these days), there are many hands on deck and people with all sorts of specialist knowledge about different areas frequent the boards. The key is to make sure you describe the problem as fully as you can and to post information from FT2’s system profiler (use the ‘Copy’ button). Be sure to mention the results of your tests so that people have got enough information to help you.

Also, please be polite to those who respond to you – ASC is staffed by volunteers, not Apple employees, just spending time to help others out. Finally, please don’t email troubleshooting problems to me personally. You’ll get a faster and better response by using the full resources of the support community.

Good luck! :)

make your own Trash Watcher utility

Trash watcher 2

So twice in the last couple of weeks, I’ve found that something funny has been going on with Xcode, source control and Dropbox. The weird behaviour is that both times a whole load of my Xcode projects got moved to the Trash without my knowledge or permission. Fortunately, I noticed in both cases, and while I haven’t got to the bottom of the problem yet, I thought the first thing I’d better do is a bit of defensive scripting!

With that in mind, I created this little Trash Watcher utility to warn me anytime something is moved to the Trash. It’s quick and easy to make, and you can customise it to do various other things apart from give a warning if you like (for example, you could make it delete files of a certain kind, size or date automatically).

Start by opening the AppleScript editor (or Script Editor on 10.10), and paste the following lines into it:


on adding folder items to this_folder after receiving added_items

set listOfFiles to {}
repeat with i from 1 to the count of added_items
set a_file to item i of added_items as text
set stripTrashPath to offset of "Trash" in a_file
set a_file to text (stripTrashPath + 6) thru -1 of a_file
set a_file to a_file & "
"
set end of listOfFiles to a_file
end repeat

display dialog "The following items were moved to Trash: " & return & return & listOfFiles buttons {"OK", "View"} default button "View" cancel button {"OK"} with title "Trash Alert" with icon 0
set btn to button returned of the result
if (btn = "View") then
tell application "Finder" to open the trash
end if
end adding folder items to

 

Here’s what the code does. The first and last lines define a Folder actions handler, where the variables ‘this_folder’ and ‘added_items’ will be replaced by the name of the folder you attach this script too (we’ll do that in a minute), namely the Trash folder, and the items that have been moved to the Trash.

The next line, declares an empty list, so that we can populate it later with just the names of the items, rather than their full path adddress.

Then comes the repeat block. This first determines how many items there are to be added and then iterates over them, applying the five ‘set’ commands on each file. Those five commands are all doing one thing: stripping the path from the item name down to just the item name itself so that we can display it nicely in the display dialog command that follows.

Note that the display dialog command adds a couple of buttons, and collects the result as to which button you pressed. Notice that “OK” (typically an action button) is used to dismiss or cancel the dialog. “View” opens the Trash folder in the event that you want to check or remove the items that have been added.

With the Script editor active, make sure your script compiles by pressing ‘Command-K’, but don’t try to run it yet. We need to attach save the script in the right place first, and then attach it to the Trash folder.

With Script editor still active, press ‘Command-S’ to bring up the ‘Save’ dialog box. Give it a descriptive name like ‘TrashWatcher.scpt’ or similar. Do not click ‘Save’, but instead press, ‘Command-Shif-G’ on your keyboard and enter this location into the box that pops up:

~/Library

and click ‘Go’. In the resulting window, scroll down to the Scripts folder and look inside it. If there is already a folder called ‘Folder Action Scripts’ then save the script in there. If not, click ‘New Folder’ in the bottom left of the window, and create a ‘Folder Action Scripts’ folder (be sure to get the name exactly right).

With the script saved in ~/Library/Scripts/Folder Action Scripts/, right click on any folder in a Finder window and choose ‘Services > Folder Action Setup’ from the contextual menu.

Folder Actions Setup

This will open a new dialog box with a list of scripts to choose from. Choose the TrashWatcher.scpt (or whatever you happened to call it) and click “Attach”. In the remaining panel, make sure the Trash folder is selected and no other.

That’s pretty much it; your TrashWatcher folder is set up, so move something to the Trash and make sure it fires. Everything OK? Hmm, maybe, but we need a few refinements. For one thing, every now and again OS X will move the .DS_Store files to the Trash, and we don’t want to know about these. Also, it would be good if the file name actually indicated whether it was file or a folder that was being moved. In fact, it does so already (Folders are indicated by a colon), but it would perhaps be clearer and more orthodox if folders were followed by a forward slash, as they are usually indicated that way in path names. To achieve both of these, refine the script above to look as follows, remembering to compile, save and test it (by moving something to the Trash, not from running in the Script Editor).


final script

Finally, with a bit of imagination and experimentation, you could add various other conditions to this script. For example, you could have it immediately delete files that are of a certain size or certain kind as soon as they are placed in the trash (tip: you’ll need to use Finder’s “empty the Trash” command after testing each file for whatever criterion you want to use). I’ll leave those as exercises for the reader, but feel free to post your scripts in the comments if you’re particularly pleased with some variation you’ve come up with!

Happy Scripting!

how to fix the “Shellshock” security flaw

shellshock update bash

Apple have today released updates to Bash for Lion, Mountain Lion and Mavericks. All users are recommended to update to Bash version 3.2.53(1) to patch the recently found “Shellshock” exploit.

At the time of writing the update for 10.9 wasn’t coming through OS X’s built in ‘Software Update’. The updates are available for download and install here:

http://support.apple.com/kb/DL1767 – OS X Lion
http://support.apple.com/kb/DL1768 – OS X Mountain Lion
http://support.apple.com/kb/DL1769 – OS X Mavericks





return the difference between two strings

FastTasks 2 Profiler
If you’ve ever looked at trying to compare and evaluate two strings in Objective-C, you’ll find a whole host of methods to help you out. What you won’t find, however, is a method that will actually return the substring (or substrings) that belongs to one but not the other of the two strings you’re comparing.

I spent some time trying to figure out how to do this last week for one of my apps, and finally decided the best way was to break the strings down into arrays and then compare the arrays by removing items that belonged to one not the other.

I chose a fairly simple equivalence test based on length, and then set out to determine which was the longer of the two, before removing all the objects of the shorter one from the longer one. Here’s how I did it:

 


-(NSString *)getDifference: (NSString *)aString and:(NSString *)anotherString {

int i = aString.length;
int j = anotherString.length;
NSString *result, *longest, *shortest;

if (i == j) {
result = @"";
return result;
}

if (i > j) {
longest = aString;
shortest = anotherString;
} else {
longest = anotherString;
shortest = aString;
}

NSArray *fa = [longest componentsSeparatedByString: @" " ];
NSArray *sa = [shortest componentsSeparatedByString: @" "];
NSMutableArray *remainder = [NSMutableArray arrayWithArray:fa];
[remainder removeObjectsInArray:sa];
result = [remainder componentsJoinedByString:@" "];
return result;

}

Here’s an example of how to call the method:


NSString *t1 = @"Mary had a little lamb";
NSString *t2 = @"Mary had a little lamb yesterday";

NSString *changes = [self getDifference:t1 and t2];
NSLog(@"%@", changes); //"yesterday"

This method is pretty basic as it stands. For one thing, the length equivalence test will certainly fail under some conditions of change; for another, you’d need to extend it to return items that are in the shorter string but not the longer (though that wouldn’t be that difficult). Nonetheless, the core of the method could be used as a basis for something far more robust. For example, this vastly more complex set of match patch and diff libraries appear to be essentially based on the same principle of breaking strings down into NSMutableArray’s and adding and removing objects, but with a vast army of conditions and other checks built in to improve reliability.

Still, the basic method I’ve posted above is the core idea I’m using in the new system profiler feature coming in the 1.5 release of FastTasks 2 (see the screenshot above), and at least at this stage of beta testing, seems to be doing the job it was designed for quite nicely.

applescript: make your own battery health meter

main
A couple of weeks ago, I posted about how to extract numbers from strings. That led one reader to wonder what use they could make of such a handler. That sounded like an invitation for a little AppleScript tutorial, so in this post we’re going to build our own, colourful and highly useful battery health meter. In the process we’ll not only use the numbersInString handler I posted last time, but learn how to make our AppleScript displays a little more colourful by adding images, and we’ll take a quick look at some very useful Bash utilities that will do some of the heavy lifting for our little app. So, open up your AppleScript editor and let’s get started!

Step 1. Grab the returnNumbersInString(inputString) handler I posted here, and paste the code into a new, blank AppleScript editor window. Hit ‘cmd-K’ to turn it into ‘pretty text’ and check that it compiles OK.

Step 2. Underneath that, hit return a couple of times to create some white space, and define a new handler like this:

on powerstats()
set iconAC to ""
display dialog iconAC & "Power Source: " with icon 1
end powerstats

Hit ‘Cmd-K’ again to compile, then underneath our new powerstats handler, hit return to make some space again and type

powerstats()

Hit ‘cmd-R’ this time, which will build and run our code at the same time, and you should get the nice if not terribly useful result as so:

icon1

Believe it or not, that’s all it takes to get the core of our app, and all that remains now is to fill out the powerstats() handler and the display dialog command with the details.

Step 3: You might have been wondering what that ‘iconAC’ variable at the beginning of the display dialog command was doing, since all we did was set it to an empty string with “”. That was a placeholder. Let’s put something in it.

First, place the cursor between the two quote marks in the line that reads

set iconAC to ""

Now, either use the keyboard shortcut control+command+spacebar, or open the Character Viewer from the Keyboard menu bar (check the System Preferences > Keyboard | Keyboard: Show Keyboard & Character Viewers in menu bar item if necessary). Pick an image you like to represent AC Power. You can find the same image as I used by typing plug in the search/filter bar, but feel free to choose any image you like.

When you find the image you want, double-click it, and you should see it inserted between the quotation marks in your AppleScript. With the cursor placed immediately after the plug character but before the final quotation mark, hit the space bar three times. That’ll position it just nicely with our ‘Power Source:’ text:

icon2

OK, we’re going to set the other images we need in the same way. So, now place the cursor after the quote marks on the ‘set iconAC ‘ line, and hit return to create a space between that line and the display dialog line.

Now add the following lines, but do not include the words in orange like #battery after each set of quote marks. I’ve included those here just as search tips to help you find appropriate characters in the Character Viewer. As before, put the cursor between each set of quote marks and use the suggested orange words to find the images. Of course, you can use any image you like, but don’t forget to add the three spaces after the ASCII image.

set iconBatt to ""    #battery
set iconCharge to ""    #voltage
set iconTime to ""    #clock
set iconHealth to ""    #clover
set iconCycles to ""    #cyclone
set iconWarning to ""    #warning

Now we’re going to update our Display Dialog command so that we get the images at the beginning of a new line. We do that by adding

& return &

between each variable. Also, we don’t need all the images (iconBatt and iconAC are alternatives, and the warning sign appears elsewhere), so we’ll just add the ones we know will always be displayed. Finally, we’ll add an extra

return &

between iconTime and iconHealth to create some space. Update your Display Dialog command so that it now looks like this:

display dialog iconAC & "Power Source: " & return & iconCharge & return & iconTime & return & return & iconHealth & return & iconCycles with icon 1

When you hit ‘cmd-R’ it should now give you this:

iconsAll

Step 4: Ok, we’re done with the images, but not quite with the Display Dialog command. We need some more static text in there, so edit the command to look like the following:

display dialog iconAC & "Power Source: " & return & iconCharge & "Current Charge: " & return & iconTime & return & return & iconHealth & "Battery Health: " & return & iconCycles & "Cycles: " with icon 1

Be careful to ensure you close every quote and add an ampersand between every term and every return, or your code won’t compile correctly. Feel free to cut and paste it from above if necessary, but you should now have something like this:

add static text

This is all the ‘static text’ — text that will appear every time we run the script. As you can see, there’s some parts missing, as they will need to be added depending on the state of our battery.

Step 5: Coding time! We need to get our data for the battery before we can do much else, and for that we’re going to use a couple of unix utilities. Rather than messing around in Terminal, though, we’re going to let AppleScript manage them for us using the ‘do shell script’ command. First, we’ll ask pmset for a load of information about the machines power management settings, then we’ll ask grep to narrow it down to just the bits we’re interested in. To do all that, we’ll add the following short but powerful command to our powerstats() handler. Place the cursor on a new line after all the set icon commands, but before the Display Dialog command. Then type the following:

do shell script "pmset -g everything | grep Cycles"

Now run the script again and hit the “OK” button. The dialog will look the same as before, but this time we’re interested in what is in the ‘Replies’ (not ‘Result’) panel in the lower half of the AppleScript editor:

pmset

Note you won’t see this until after you hit the “OK” button on the dialog panel. What we need to do now is capture this result in a variable so that we can start extracting some of those useful numbers, so immediately underneath this line, add:

set x to the result

set x to the result

Step 6: In order to understand what follows, temporarily add the following two log lines:

log word 1 of x

Now run the script. Run it once with the power supply connected, then again with the machine running on battery power and compare the output in the ‘Replies’ field after you’ve hit the “OK” button.

The output of the log lines is shown in the Replies field between

(* *)

and they tell you the values of the variables. “Word 1″ is the first text item in the result (exactly what delimits text items in a script depends on a built-in AppleScript variable called text item delimiters, which you can read about here).

If the AC Power is connected, word 1 should be “AC”, otherwise, it should be “No”. Similarly, word 2 should be either “charging” or “not” (sometimes the battery doesn’t charge due to a poor connection or if its more than 95% full). If AC is not connected, Word 2 should be “AC” (Word 1 and 2 together, in this case read “No AC”). However, different macs may have different power management options, so do some tests and check that you get the same results. If you don’t, you’ll need to experiment logging different words to find out which words correspond to my ‘word 1′ and word 2′. Here’s a summary again of the word numbers you need to determine for each of the values, with those on my machine given in brackets:

AC connected: word (1)? = “AC”; word (2)? = “charging” or “Not”
On battery power: word (1)? = “No”; word (2)? = “AC”

If your machine gave different results, make a note of which word number corresponds to my word 1 and word 2, and wherever I mention ‘word 1′ and ‘word 2′ in the scripting below, substitute those for the correct word numbers you found in your tests.

That these words always appear in the same position on the same machine is a very handy fact that makes it easy for us to determine whether the mac is running on battery or mains power, and in the latter case whether the battery is charging or not.

In the next step we’ll now put this information to good use in our script. First, however, remove all the log messages from the script.

Step 7: It’s time to add some more code to our powerstats() handler. Add this conditional test to your script, remembering to substitute any differences in word number you found in your logging tests:

iconWarning

This code assumes the AC is connected and sets the variable ‘charger’ to display whether the battery is charging or not. However, we need to set that variable to an empty string if the mac is running on battery power, so immediately underneath add another conditional:

pwrsource

In the Display Dialog command, replace iconAC with pwrSource as indicated in the image above. This will allow the Display to change the image accordingly. At this point, compile and test your script, both with the power supply connected and disconnected, ensuring that the icon changes accordingly.

If that’s working as expected, add the variable _t to the Display Dialog command immediately after the iconTime variable. Don’t forget to add another ampersand along with it as shown:

_t
Again, compile and test your script, both on battery and AC Power.

Step 8: Time to do some math. You may remember we started the script by adding the returnNumbersInString(inputString) method, and now it’s time to use it. We want to extract all those numbers returned by the do shell script command, and currently stored as a text string in our variable, x. We’re going to need some of them as numbers because we’re going to perform some math on them to get the battery percentage health.

Start by adding the following line, which calls the handler and gets the numbers back as a list of integers:

numbersInString
Item 1 of nums should be the battery’s current charge. Test this by adding a temporary log statement immediately after the set nums line:

log "item 1 of nums is " & item 1 of nums

Run the script, hit “OK”, and examine the Replies panel. Compare the output of the do shell script statements, and it should be clear whether you’ve got back the battery percentage or not. If not, continue logging till you hit the right item number. I’m going to assume that you got item 1 (if you didn’t, replace my mention of ‘item 1′ with whatever yours was in the following lines), so let’s remove the log statement, and replace it with this:

set percentage to item 1 of nums & "%".

Now, down in the Display Dialog command, add the variable ‘percentage’ and another ampersand in the place shown:

Screen Shot 2014-08-25 at 21.24.08
Run the script and hopefully you should now see that your battery percentage is correctly shown:

show battery percentage
Looking at the display reveals we haven’t added in the Power Source variables to the Display Dialog which we defined earlier, so do that now:

pwr & charger

Step 9: The next step is to add the time, but this is tricky on several counts. First, if you examine the number returned by do shell script in the Replies panel, you’ll note the hours and minutes are colon-separated. As far as our list is concerned, that makes them two different items, so we have to get the hours and minutes separately (items 5 & 6 on my machine; use logging to check what they are on yours).

Secondly, if the minutes are between “00” and “09”, AppleScript will just return a single-digit between 1-9, cutting of the “0”. That’ll mean we’ll end up with a weird display for say “1:05″ as “1:5″. To counter that, we’ll have to test whether the minutes is less than 10 and add a “0” back in to the string if so. Also, we’ll have to add “hr”, “hrs” or “mins” depending on how much time is remaining or left to fill the charge.

As if that wasn’t enough, there’s a problem with the power manager: if you use Apple’s battery/power icon in the menu bar, you’ll notice that if you click on it straight after changing the power source, you’ll get a “Calculating Time till Full” or “Calculating Time Remaining…” message. That’s because it takes a minute or so for the power manager to update. The menu bar icon will update live, but we don’t have that luxury. Instead, we’ll add a warning later to alert users to this and ask them to run the script again after a short delay.

Woah. That’s a lot of conditions, so here goes. Add the following immediately above the Display Dialog command:

if item 5 of nums = 0 then
set hrmins to " mins"
else if item 5 of nums = 1 then
set hrmins to " hr"
else
set hrmins to " hrs"
end if
if item 5 of nums is greater than 4 then

if pwr is "AC" then
set t to "Calculating...try refresh in 2 mins"

end if

else
if item 6 of nums is less than 10 then
set theMins to item 6 of nums as string
set theMins to "0" & theMins as string
else
set theMins to item 6 of nums as integer
end if
set t to item 5 of nums & ":" & theMins & hrmins
end if

And for all that code, we only need to add one variable and an ampersand to our Display Dialog:

Step 9 v2


There is one remaining problem, which is that if you run the script immediately after changing the power source, although the message “Time to Full” or “Time Remaining” will change, the time itself may not. This is for the reason stated earlier: its inherent to the way the power manager works. We’ll do our best to help the user by adding a Refresh button later, but otherwise this is a shortcoming we’ll have to live with.

Step 10: It’s now time to get down to the real point of this script, which is to tell the user something that the battery meter in the status bar does not: the battery health and the battery cycles. The number of charge cycles the battery has been through is, naturally, given by the ‘Cycles’ figure. Battery health, however, is not data outputted natively by the power manager. Rather, it is a percentage of the Battery’s design capacity and its current ‘fully charged capacity’ or FCC. As you might expect, these two figures are represented in the do shell script output by “Design” and “FCC”, and it is largely because we need to do a mathematical operation on these that we needed the numbersInString handler.

To figure out the Battery health, we’ll divide the Design capacity by 100 to obtain 1%, then divide the FCC by this number to figure out how many percent it is of the Design capacity. That bit of math is represented by the function FCC/(design/100). In order to avoid a whole load of decimal places, we’ll also use AppleScript’s built-in round() handler to return a whole number. Finally, we’ll add the “%” sign to the string and add the ‘battHealth’ variable to the ‘Display Dialog’ command.

Here’s the code to be added, again after the last line and before the Display Dialog command (reminder: don’t forget to check using the logging technique I showed earlier that your item numbers are the same as mine, and to substitute your own for mine if they are different):

set FCC to item 3 of nums as integer
set designCap to item 4 of nums as integer
set battHealth to (FCC/(designCap/100))
set battHealth to round(battHealth)
set battHealth to battHealth & "%"

battHealth

Don’t forget to add the battHealth and ampersand to the Display Dialog, as shown above.

Step 11: Almost there. Let’s add the Cycles, which is fortunately a simple one liner:

Cycles
Does that say minus 3? Yes indeed it does! A little trick with AppleScript lists and strings is that you can count items backwards from the end using the minus sign,where -1 is the last item, -2 the item before it and so on (I thought I’d just throw that in as an extra since this command was so straightforward!). As always, check the position by using logging in your own script.

Step 12: If you run your script now you should find it’s complete. To wrap up, we want to go back to where we started, and that’s improving the look and functionality of our Display Dialog box. The first thing to do is fix the buttons. We don’t need a “Cancel” button, since the “OK” button does the job of dismissing the script, but we would like a “Refresh” button, so the user can run the script again from the dialog box. To add the the buttons, change the Display Dialog command and add a conditional statement after (not before this time) it. We’re also going to add a title for the box while we’re at it:

refresh button

final

Step 13: Your script is done, but to really finish it off, we should turn it into an app that we can run off the Dock, and to which we can add a custom icon. To create an app, choose “File > Export” and change the File Format to App. Give your script a name like “batteryPowerStat” and save it in your Applications folder.

Step 14: All you need now is an icon. You can either make your own, or you can download mine. Once you have an icns file, change its name to ‘applet.icns’ and add it to the Application bundle. To do that, control-click on your new app in the Finder, and choose ‘Show Package Contents’. Navigate to Contents > Resources, delete the file that currently exists there called ‘applet.icns’ and replace it with your custom icon.

You may need to log out and log in again before OS X flushes the old file from its memory and displays your new one.

Step 15: Only kidding! There is no step 15. :D I just wanted to stay “Congratulations”. If you made it this far, I hope you picked up a few AppleScript tricks along the way to creating your own battery health meter. If you need the complete code, you can find it on my Pastebin site here.

Enjoy! :)

FastTasks 2 update available 💥

I’ve just released an incremental update for FastTasks 2. Update 1.3 adds the ability to quickly see whether TRIM is currently on  or off for your SSD disks. Since TRIM support for non-Apple SSDs requires editing a kernel extension, TRIM is regularly disabled on non-Apple SSDs every time users update or upgrade OS X. FastTasks 2 v1.3 now lets you see TRIM status in the information section of the menu.

FastTasks 2 Trim

Get the latest release of FastTasks 2 by going directly to the FastTasks support page, or if you already have FastTasks 2 running, you can use the Preferences > Check for Update > Check now menu item. :)


UITableView doesn’t immediately reload data

awakeFromNib
Here’s a little problem and solution I ran into the other day while using UITableView. I wanted to have a master-detail set up in which the UITableView was segued to after an initial home screen.

The problem occurred whenever I added or deleted something in the UITableView, segued back to the home page and then returned to the table view. Sometimes the table would not update. Going out and back into the view a second time, however, would finally reload my data and show me the changes. Why was my app needing to load the view twice before the table would show any changes?

Logging showed me that something even weirder was going on: Every time I segued into the table view, the viewDidLoad method was being called not once, but twice. So basically, to get my updated data to show, I was actually calling viewDidLoad four times!

I worked through a whole bunch of stackexchange posts related to various problems and solutions with the reloadData method — adding delays, removing it from any edit- or insert- methods and so on, calling it on the main thread — but the problem stubbornly remained.

Then I noticed something else. In my awakeFromNib method, the call to super had somehow got pushed to the end of the method, after a bunch of other set up calls. I’m not sure how it got there, but I did remember seeing a WWDC 2014 Swift video pointing out that one difference between Objective-C and Swift was that calls to super need to be made after doing any initial set up in Swift’s case, but before for Objective-C. Since this was an Obj-C project, what was my call to super doing at the end of the method?

And as if by magic, moving [super awakeFromNib] to the beginning of my awakeFromNib method resulted in viewDidLoad only being called once, and my table view updating correctly.

Though I found quite a few threads with people having a similar problem with UITableView’s needing two calls before updating, I haven’t come across this particular solution to (or cause of) the problem. Hopefully, this post will save someone else a few hours of head scratching!

%d bloggers like this: