Archive for the ‘iPhone’ Category

iPhone Learning Application

Monday, September 21st, 2009

I’ve been working on an application for the iPhone but it’ll never be on the app store. Courses and reading are all good, but if you’re going to know how to build something you ultimately have to learn by building. So when I learn a new system I always make sample projects. This one comes from the Stanford iPhone applications course (via iTunesU) that I’m doing.

This application makes polygons with user-variable number of sides. A slider or buttons control the number of slides, other buttons control a dashed or solid line around the polygon. There are various other features for drawing and updating text, etc. (A screen capture of the app is to the right. )

An interesting extra item in this exercise was to allow the user to drag a finger on the polygon and rotate it. This is my thinking behind the software development for this one feature.

It took me a bit of reading and experimentation to figure out that the rotate operation (CGContextRotateCTM) always rotates around the origin of the UIView. In the iPhone the origin is the top left of the coordinate space. But I wanted to rotate the polygon around it’s center, not the orgin. I ended up doing this:

CGContextTranslateCTM(context, self.bounds.size.width/2, self.bounds.size.height/2);
CGContextRotateCTM(context, rotateAngle);
CGContextTranslateCTM(context, -self.bounds.size.width/2, -self.bounds.size.height/2);

This translates the center of the polygon to the coordinate space origin, rotates that space, then translates the polygon back to its starting location, but rotated now. There are other ways to do this transform and I’ll have to learn them at some point, but this seemed the best for now.

Figuring the angle to rotate was interesting too. First, I had to refresh my trig knowledge as I don’t use it much. I have several points: the center of the polygon, and the position that the user has their finger on. When I touch my finger to the polygon I get the “touchesBegan” event. Then when I drag my finger on the polygon, the app gets a series of new finger positions as “touchesMoved” events. When I lift my finger, the app gets the “touchesEnded” event. All the events have their location as a parameter.

Given these positions I needed to calculate the starting angle of the finger drag from the center of the polygon, and the successive angles as new events came in. The new angle of rotation (rotateAngle above) is the difference of those two calculated angles.

I used the right triangles as shown here in the square polygon to find the angles. The center of the square has the blue dot, the first event (”touchesBegan” event) locations is red, and the second is green (”touchesMoved” event). I used the formula of opposite side length/hypotenuse side length to find the sine, then used arcsine to find the actual angle.

Due the way I was calculating the angle, I had to adjust the sign of the angle value and it’s magnitude depending on the relative location of the center and the touch points. My calculation gave angles 0-90 degrees only. The triangle would be upright or upside down in the example here. Or it would be reversed if the touch point was to the left of the center. (All angle calculations were in radians though.)

In my code I’d be saving the cumulating angle of rotation, I initialized this to zero. The new angle of rotation was this old saved angle plus the difference of the two angles I’d calculated above. Then, I redrew the UIView to show the polygon rotated. When the “touchesEnded” event happens, then the old saved angle plus the current angle difference is saved as the new cumulative angle of rotation.

So now the polygon turns under my finger as if I were moving a real physical object mounted on a turntable.

iPhone Upgrade to OS 3.0

Wednesday, July 8th, 2009

Note: The issues here only affect iPhone developers and only those developers that upgraded from 2.2.1 to 3.0 after they’d provisioned their iPhone.

After WWDC, I setup my iPhone for development use as described earlier. I was running iPhone OS 2.2.1 at the time. Later, I upgraded through iTunes to iPhone OS 3.0 when it came out. I continued the process of teaching my self how to program the iPhone. When it came time to upload a new app, I couldn’t.

After much hunting around, some reading of documents, checking of hex identifier codes, and the requisite gnashing of teeth, etc. I figured out by using the XCode Organizer window that my iPhone wasn’t provisioned anymore. Well as the last real change was the upgrade to 3.0 that was probably it.

I used XCode’s Organizer to “Restore iPhone” (via a popup on the Summary tab) using the iPhone OS 3.0. This wiped the phone’s data and apps and restored it’s provisioning. It didn’t affect the OS version installed. The popup only allowed the 3.0 version to be restored.

This left the phone in a minimal mode only able to make an emergency phone call and with a graphic on the screen that it wanted to be plugged into my USB. So I did that. I used iTunes to re-restore the system to my last backup. Which, fortuitously was five minutes before I started this mess.

In the end, after the few non-productive hours I spend figuring this out, restoring, and re-restoring, I’m back to having my iPhone with all my data, and I can download new apps to it from XCode as well.

The Root Cause

I surmise from past experience in working with keys, certificates, and public key encryption that there is a tie between the certificate and the OS version. This is a pain for developers and breaks Apple’s user experience principle of allowing upgrades without pain. Granted, only developers are affected and perhaps it’s my failing as a new iPhone developer but I had found no warning of this effect of the OS upgrade.

I understand why Apple is using key signing for applications and that’s good. But as a coworker (hi Randy) once said: The point of security is to create a failure point. I would hope Apple tries to smooth this process in the future. An undocumented failure point is more typical of a Microsoft feature than the usual Apple experience.