Archive for Uncategorized

So I Deleted a Calendar on my iPhone

I didn’t expect it would be difficult to delete a calendar from my iPhone, but it was.

I recently upgraded to iPhone OS 3.0 (took me a while, I know), and began using the built-in calendar functionality to sync with Google Calendar. I had previously been using an application called “NemusSync”, so now I had too copies of my google calendar information displayed in the calendar application. I wanted to get rid of the old one, but there doesn’t appear to be a UI for it, and doing a Google search on how to delete an iphone calendar wasn’t immediately helpful.

This method works for jailbroken phones, and is probably more involved than you want it to be, but it is what I did. It requires SSH, Python, and the sqlite3 module (all installed via Cydia).

Also, I’m only hiding the extra calendar – the data is still on the phone, but I don’t have enough data there that I’m worried about it – you could use the same method to actually delete the data from the database if you want.

Here we go, with comment lines beginning with ‘#’:

# connect to your phone, enter password when prompted

# start the Python interpreter
/var/root# python
Python 2.5.1 (r251:54863, xx/xx/xx, xx:xx:xx)
[GCC 4.2.1 (Based on Apple Inc. build 5555)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

# import the SQLITE db module, and connect to the database
>>> import sqlite3
>>> name='/private/var/mobile/Library/Calendar/Calendar.sqlitedb'
>>> c = sqlite3.connect( name )
>>> def printall( x ):
... i = 0
... for r in x.fetchall():
... i+= 1
... print i, r
>>> printall( c.execute( 'select * from Calendar' ))
1 (1, 1, u'Default', 0, 1, 0, -1, -1, -1, None, None, None, None, None, None, None)
2 (2, 1, u'local', 0, 0, 0, 127, 127, 127, 1, None, 0, None, None, None, None)
3 (3, 1, u'', 0, 0, 0, 163, 41, 41, 1, None, None, None, None, None, None)
4 (4, 2, u'', 0, 0, 0, 163, 41, 41, 0, None, 0, u'', u'MY_ID', None, None)

>>> printall( c.execute( 'update calendar set hidden=1 where rowid=3'))
>>> c.commit()

And that should hide the old calendar from the Calendar application.

Note that I did have to explore the database and figure out how to inspect the schema of the sqlite database to find the table and column names. Preserving that information here for the collective memory…

>>> c.execute( '''show tables''' )
Traceback (most recent call last):
File "", line 1, in
sqlite3.OperationalError: near "show": syntax error

# shoot, no "show tables". ...googling... OK:
>>> printall( c.execute( 'select name from sqlite_master where type="table";'))
1 (u'_SqliteDatabaseProperties',)
2 (u'Store',)
3 (u'sqlite_sequence',)
4 (u'Alarm',)
5 (u'AlarmChanges',)
6 (u'Recurrence',)
7 (u'RecurrenceChanges',)
8 (u'OccurrenceCache',)
9 (u'OccurrenceCacheDays',)
10 (u'GCalAccounts',)
11 (u'GCalCalendars',)
12 (u'GCalState',)
13 (u'GCalEvents',)
14 (u'Calendar',)
15 (u'CalendarChanges',)
16 (u'Event',)
17 (u'EventChanges',)
18 (u'EventExceptionDate',)
19 (u'Task',)
20 (u'TaskChanges',)
21 (u'Attendee',)
22 (u'AttendeeChanges',)
23 (u'Participant',)

# Calendar looks good...
>>> printall( c.execute( "describe calendar" ))
Traceback (most recent call last):
File "", line 1, in
sqlite3.OperationalError: near "describe": syntax error

# dang, no "describe TABLE". ...googling... OK
>>> printall( c.execute( "PRAGMA table_info(Calendar)" ))
1 (0, u'ROWID', u'INTEGER', 0, None, 1)
2 (1, u'store_id', u'INTEGER', 0, None, 0)
3 (2, u'title', u'TEXT', 0, None, 0)
4 (3, u'read_only', u'INTEGER', 0, None, 0)
5 (4, u'hidden', u'INTEGER', 0, None, 0)
6 (5, u'immutable', u'INTEGER', 0, None, 0)
7 (6, u'color_r', u'INTEGER', 0, None, 0)
8 (7, u'color_g', u'INTEGER', 0, None, 0)
9 (8, u'color_b', u'INTEGER', 0, None, 0)
10 (9, u'color_is_display', u'INTEGER', 0, None, 0)
11 (10, u'type', u'TEXT', 0, None, 0)
12 (11, u'supported_entity_types', u'INTEGER', 0, None, 0)
13 (12, u'external_id', u'TEXT', 0, None, 0)
14 (13, u'external_mod_tag', u'TEXT', 0, None, 0)
15 (14, u'external_id_tag', u'TEXT', 0, None, 0)
16 (15, u'external_rep', u'BLOB', 0, None, 0)

# that "hidden" column looks useful...

Comments (2)

So I Found a Windows SSHFS

It’s from Japan, and is called Dokan SSHFS. It works well.

Some limitations – it will mount the remote filesystem as a drive, so you need to assign a drive letter to each remote filesystem you want to mount. It saves connection info, but not your password or key passphrase. When you type those, it will display them in cleartext, so be aware.

This beats the WinSCP periodic update model for my use cases – however, it does mean that saving files can be slow, depending on your network bandwidth and latency.

For Unix/Linux, you can use the original SSHFS, as I described in another blog post.

Comments (5)

So I Took a Screenshot on my G1…Here’s the Howto

So I compared my iPhone and my G1, and included notes on how to take a G1 screenshot, but it turns out there was another step: installing the appropriate drivers, and enabling debug on the G1.

So, to take G1 screenshots:

  1. Turn on USB debugging on the G1: Settings | Applications | Development | USB debugging
  2. Download and install the Android SDK
  3. Download and unzip the Android USB device drivers (for Windows – for Linux, see the additional instructions on the DevelopAndDebug page).
  4. Connect the device via USB, and choose “Install from a list or specified location” and choose where you unzipped the file. If you’ve already gone through this and Windows doesn’t prompt you anymore, you’ll need to open Control Panel | Administrative Tools | Computer Management | Device Manager, go down to Other Devices and choose the Android phone, then right click Properties, and choose Update Driver, then browse to the specific location…
  5. From the Android SDK, start tools/ddms.bat
  6. Your G1 should appear as the only device in the left-hand side.
  7. You can then press Ctrl-S (Device | Screen Capture) to capture a screenshot.
    G1 screenshot
  8. Breathe a sigh of relief

Comments (11)

So I used sshfs to Mount a Remote Filesystem

This is the one Linux way to edit files remotely as if they were local. For a Windows approach, see my post on WinSCP. There’s also a Windows sshfs called Dokan SSHFS.

sshfs is a user-space Linux filesystem that makes an ssh connection look like a local filesystem.

It’s trivial to use:

  1. As root (or using sudo) add your user to the ‘fuse’ group:

    # adduser butler fuse
    Adding user `butler' to group `fuse' ...
    Adding user butler to group fuse

  2. Start a new shell as the desired user (to get the updated group list), make a mount point, and start sshfs. Note that sshfs will prompt you to accept the remote key (not shown) if this user hasn’t previously connected to this remote account.

    $ mkdir soi
    $ sshfs soi's password:
    $ ls soi/images
    changeDirectories.jpg keepRemoteSynced.jpg updatingFiles.jpg
    directoriesSynced.jpg session.jpg watchForChanges.jpg
    firstSession.jpg updateFiles.jpg

  3. Read and update files as if they were local – but with some transfer lag…

If you don’t want to deal with the lag every time you read or write the file, you’ll probably want to use scp or rsync to copy the files over when you need them on the remote machine – and you’ll probably want to use ssh-agent and ssh-add to set up key-based authentication, so you don’t have to type your password every time. You can even put the scp or rsync calls in your Makefile…

Comments (2)

So I used WinSCP to Keep a Remote Directory Up-to-Date

Mononofu reminded me I hadn’t talked about how to keep remote directories in sync. This is the windows version. For a Linux version, see my post on sshfs.

So, to work on files locally on Windows, but have them automatically copied to a remote directory, use WinSCP.

  1. Download WinSCP 4.17 and install it
  2. Run WinSCP
  3. Enter info to connect to the remote host (like your iphone)Session parameters
  4. On your first connect, WinSCP won’t recognize the key of the remote system, so just accept it. If you see this prompt later, it either means your remote system got a new key (e.g., reflashed the phone and re-jailbroke it), or somebody could be trying to intercept your communications. Prompt to accept remote host key
  5. Change directories to the local and remote directories you want to keep synced. Change directories
  6. Choose Commands | Keep Remote Directory up to Date (Ctrl-U). Keep Remote Directory up to Date (Ctrl-U)
  7. Choose options for synchronization, and do a full synchronization to get things started. Watch for changes
  8. Make changes to the files on your local machine. Update local files
  9. WinSCP notices the changes and pushes them to the remote machine. Updating files
  10. The directories are kept in sync. Directories synced

Comments (5)

So I built an iPhone application in xCode without $99

I’m developing for the iPhone, and I even got a Macbook, but I don’t really want to start my $99/year until I’m ready to publish something to the AppStore. So, how do you develop with xCode for the iPhone, without an Apple Developer certificate?

  1. Download and install xCode and the SDK from the iPhone developer center. Run the installer.
  2. Create a self-signed certificate on your mac.

    Start Keychain Access: Open Finder, Utilities (shift-command-U), Keychain Access. Then Keychain Access, Certificate Assistant, Create a Certificate. Enter the name “iPhone Developer”, Self Signed Root, and check Let me override defaults. Continue, and Continue again – that you’re creating a self-signed certificate.

    Serial number 1 should be fine, make the validity period longer so you don’t have to mess with this again (3650 days sounds good…), and choose Certificate Type: Code Signing. Continue, enter an email address, I put “iPhone Developer” in the certificate information here, too, and then just hit Continue until it creates the certificate.

  3. Download a project of your choice from the Apple iPhone developer pages (I grabbed WhichWayIsUp). Open the .dmg and copy the files (or the .zip and extract the files) into a directory you can edit (I put it under $HOME/Documents).
  4. Open the xcode project file (or the project file from xcode).
  5. Turn off built-in code signing: open Project settings (Project | Project settings). Choose the Build tab. In the Code Signing section, for Any iPhone OS Device, erase the name “iPhone Developer” and leave it blank.
  6. The jailbroken iPhone still needs the code to be marked as “signed” (or the application gets killed on startup), so add a custom build step to sign the executable (you’ll need to do this for each project – and I haven’t found where to update it after adding it…):

    Download and place it in $HOME/bin. Make it executable (chmod 755 $HOME/bin/

    Add the build step to execute

    Project | New Build Phase | New Run Script Build Phase

    Add the following script code (note that you need to update $HOME/bin depending on where you put You may also want to update the text):

    export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
    if [ "${PLATFORM_NAME}" == "iphoneos" ]; then
    	codesign -f -s "iPhone developer" --resource-rules "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/ResourceRules.plist" \
  7. Choose the iPhone as the Active SDK: Project | Set Active SDK | Device – iPhone OS 2.1
  8. Build the project (command-B). If prompted, allow the use of the iPhone Developer key to sign the code. (I choose Always allow).
  9. Copy the built file to the iphone (update text as needed): scp -r ~/Documents/WhichWayIsUp/build/Debug-iphoneos/ root@miphone:/Applications
  10. Refresh the Springboard cache. You can do this in several different ways. Pick one:
    • Install or update an application via Cydia or AppStore
    • Use the Cydia application “Respring”
    • In the Cydia package “BossPrefs” touch the Power icon, then “Fast Respring”

  11. Your application should show up in the Springboard. Run it, and enjoy. (Or be disappointed that the box in WhichWayIsUp doesn’t rotate smoothly, but only switches to vertical/horizontal. *sigh*)

Much of the detail of this process and the script came from Sylvain Munaut – Thanks! Note that I did not need to install the binary patches he lists at the end of his process.

Comments (11)

So I read the new Apple iPhone SDK Agreement

It’s much better than the old one.

Apple removed the non-communicate clauses (except you still can’t be first to disclose pre-release information).

Of interest, they also removed the “can only use the SDK on Apple-labeled hardware” clause. I had privately speculated that the tying of the Apple Market to Mac OS to Apple-labeled hardware would be a violation of anti-trust law – leveraging one monopoly to promote another monopoly (“tying”).

It looks like Apple has rescinded this tying arrangement, but retains the Mac OS license restriction to only use Mac OS on Apple-labeled hardware. I’ll have to address that sometime in another post, but I believe that restriction is invalid, as a monopoly tying arrangement in a contract of adhesion.

Leave a Comment

So I opened the Mac menus with the keyboard

I bought a used Macbook off eBay, to do iphone development. And ’cause I’ve been interested in the platform for a while.

Never used a Mac much before, and I’m trying to find all the keyboard shortcuts to keep my finger off the trackpad…

How do I access the menus with just the keyboard? Lifehacker gives the tip that you can do it with ctrl-f2 for the menu, and ctrl-f3 for the Dock. However on my Macbook, those affect sound & display, so you have to do ctrl-fn-f2 and ctrl-fn-f3. Contortionist, and it just opens the Apple (System) menu and you use arrow keys from there, but at least I don’t have to use the trackpad…

Comments (1)