dougscripts.com

January 26 2012 - 10:22 am

Sync a Wi-Fi iPhone Once a Day With launchd

A while back, I retired my iPhone 3GS to the bedside table after buying an iPhone 4. I use the 3GS pretty much as a glorified clock radio-iPod Touch. I have a few radio apps on it and the Digital Clock app. I also have it set to sync and back up over Wi-Fi to my main iMac so I manually initiate a sync when I need to update Podcasts and apps and what have you.

This manual syncing has become tiresome. (I mean, if I used a traditional clock radio, I wouldn't have to update its content manually, right?)

It's simple enough to write an AppleScript to sync a connected iPhone but I want the script to run on a regular basis without me having to fire it. I like to listen to Podcasts in the evening so sometime during dinner would be a good time to update the 3GS with any Podcasts that have arrived during the day. For this, I can create a launchd agent to fire the AppleScript that syncs the 3GS in the background. Here's how to get all that to swing:

First, the script.

Because my iPhone 3GS is set to sync via Wi-Fi, it's always mounted in the iTunes Source list on the iMac (when iTunes is active of course). A script will need to make sure iTunes is running, target the specific iPhone (or iPad for that matter), and update it:

if not checkItunesIsActive() then return

tell application "iTunes"

try

set src to (some source whose name contains "3GS")

tell src to update

end try

end tell

to checkItunesIsActive()

tell application id "sevs" to return (exists (some process whose name is "iTunes"))

end checkItunesIsActive

(You can copy and paste the above script to your AppleScript Editor, or click the little script icon button to open it in AppleScript Editor.)

The call to the checkItunesIsActive() handler can be left out if you want iTunes to launch if it isn't running when the script fires. But if iTunes has a lot of startup stuff to do the script may never get to do its thing.

The script gets a reference to the iPhone to target by using a distinctive part of its name. In this case, the iPhone I'm targeting is named "Doug's iPhone3GS" so I'm using the "3GS" as a distinguishing mark. You will have to change this for your device. Make sure to use a piece of the name that isn't in any other device's name.

The update command will initiate a sync. The whole schmear is in a try block so that if something can't be done (because, for example, the device isn't connected) the script will fail gracefully.

Save the script using the File Format "Script" named "Sync My Device" in your [username]/Library/iTunes/Scripts/ folder. (Remember to make the "Library" folder visible by Option-clicking the Finder's "Go" menu and selecting "Library" from the drop down menu.)

Now for the launchd agent.

I've discussed launchd before in a previous project that updated expired podcasts. I'll be borrowing a little from that project here. Essentially, I'll be creating a launchd agent that runs a job that fires the script in the background.

1) Launch your favorite text editor. TextEdit will do if you don't have BBEdit, TextWrangler or something comparable. Copy the following into a new document (after some slight modifications this will be saved as the launchd agent):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Disabled</key>
	<false/>
	<key>Label</key>
	<string>com.YOURUSERNAME.SyncMyDeviceAgent</string>
	<key>Program</key>
	<string>/usr/bin/osascript</string>
	<key>ProgramArguments</key>
	<array>
		<string>osascript</string>
		<string>/Users/YOURUSERNAME/Library/iTunes/Scripts/Sync My Device.scpt</string>
	</array>
	<key>StartCalendarInterval</key>
	<dict>
		<key>Hour</key>
		<integer>18</integer>
		<key>Minute</key>
		<integer>0</integer>
	</dict>
</dict>
</plist>

If using TextEdit, click the "Format" menu and make sure that the document is plain text and not rich text.

2) Change the two occurences of "YOURUSERNAME" to your user name. This is the same as the name of your Home folder.

3) I've set the time for the job to run as 6:00PM by virtue of entering an Hour of 18 and a Minute of 0. You can of course set your own time the same way.

4) Save the document as "com.YOURUSERNAME.SyncMyDeviceAgent.plist" (change that YOURUSERNAME again) in your [startupdisk]/Library/LaunchAgents/ folder. Note: this is the root-level public Library folder on the startup drive and not the user Library folder in your Home folder or the /System/Library/ folder! If there is no LaunchAgents folder there then create one and save the file in it. You will probably need to authenticate in order to save the file to this location.

5) Restart your computer, or logout and then login again so that your system registers the agent.

Yer done. If you've followed these instructions correctly, your device will update everyday at the same time without you having to do a thing. You may want to set up your Podcasts to update regularly, too, using the tools in this project.

(In an earlier version of this article I referred to my iPhone 3GS as a 3G, inadvertently dropping the "S". The iPhone 3G cannot run iOS 5 and cannot connect wirelessly. Sorry for any confusion.)

An update to this article describes how to sync more than one connected device.

Site contents © 2001 - 2024 (that's right: 2001) Doug Adams and weblished by Doug Adams. Contact support AT dougscripts DOT com. About.
All rights reserved. Privacy.
AppleScript, iTunes, iPod, iPad, and iPhone are registered trademarks of Apple Inc. This site has no direct affiliation with Apple, Inc.
The one who says "it cannot be done" should not be interrupting the one who is doing it.