Filed under: iPhone, SDK, iPod touch
Tuesday’s iPhone OS 3.0 announcement has left the interwebs even more iPhone-obsessed than usual. If you find digging through all this information overwhelming (or, if like me you were out of town when OS 3.0 was announced), check out this round-up of news, opinions and videos. The only thing missing is a beta copy of OS 3.0 and that’s already floating around various torrent sites.
If that’s not enough, be sure to check out our continuing iPhone OS 3.0 coverage.
Watch the OS 3.0 presentation — Were you left off the invite list too? Check out the video in HD or SD at the link above or in iTunes [iTunes link] as a video podcast.
Engadget’s iPhone OS 3.0 Hub — Engadget has a whole page dedicated to their furious and hands-on iPhone OS 3.0 coverage, including this video walkthrough.
What Apple Didn’t Announce — Apple’s iPhone OS 3.0 presentation didn’t answer every question or address every iPhone issue. Our old friend David Chartier tackles what was left out.
SDK 3.0 brings more NDA fun — Much to the chagrin of many iPhone devlopers, the NDA is back for SDK 3.0. At Arstechnica, our pal Erica takes on what this means for developers. Let’s just hope the NDA is lifted as soon as 3.0 is officially released.
OS 3.0 Screenshot Pr0n — Pfft, what NDA? iLounge has put together a great gallery of iPhone OS 3.0 screenshots, showing off what’s new and improved. Love it.
iPhone OS 3.0 vs. Android — Lifehacker has a pretty neat comparison of features that are currently avaialable in the iPhone 2.21, stuff that’s coming in OS 3.0 and what’s available and coming for Android. As someone who has spent a LOT of time using both the iPhone OS and the T-Mobile G1, I’d just add that hardware and UI is actually just as important as “features” when comparing the two platforms. Right now, the iPhone absolutely cleans Android’s clock — despite having fewer “features” — because the hardware is better (that G1 keyboard is terrible), the UI is more thought-out and the third-party software is better by leaps and bounds. (hat tip, Gruber)
Future iPod/iPhone models referenced in latest betas — The latest iPhone OS 3.0 SDK includes references to future iPhone and iPod models (3,1) and two other unknown devices.
TUAWiPhone 3.0 Friday roundup originally appeared on The Unofficial Apple Weblog (TUAW) on Fri, 20 Mar 2009 16:00:00 EST. Please see our terms for use of feeds.
Read | Permalink | Email this | Comments
(Via The Unofficial Apple Weblog (TUAW).) Original Link: iPhone 3.0 Friday roundup
Here’s the post.‘ It basically goes like this:’ Apple has said it is increasing its embedded device list this year.’ Ten-inch touch screens seem to be flying around Asia en route to Apple for late Summer.’
If there is a tablet with higher resolution/independence, developers are going to need a few months to tweak their apps for launch.” What if that $20 minimum Premium App Store happens to be for higher resolution apps?
Also, ARM’s new line of Cotex A8 architecture processors are tablet-worthy.’
Plus, I need something to look forward to…So here’s why we might see a tablet intro tomorrow.
Speaking of which, we’ll have the 9to5mac LivePanel open for the iPhone 3.0 Event.’ Stop by to see all information sources in one page.
‘
“
iPhone OS 3.0 is coming, preview on March 17th: “
Filed under: Cellphones
iPhone OS 3.0 is coming, preview on March 17th originally appeared on Engadget on Thu, 12 Mar 2009 12:06:00 EST. Please see our terms for use of feeds.
Permalink‘|’Email this‘|’Comments“
(Via Engadget.)
TUAW Bookshelf: iPhone in Action: “
Filed under: Analysis / Opinion, iPhone, iPod touch, TUAW Bookshelf

I’ve never found book reviews to be terribly helpful — technical book reviews even less so, as how one learns differs from person to person. Some iPhone devs out there learned simply by poring over Apple’s copious documentation. Others have been poking at the iPhone’s innards since pre-SDK days, learning as they went from forums and good old hacking. But once the NDA lifted, the floodgates of iPhone dev books opened.
Each book and each publisher has a different angle both in content and presentation. Each book may appeal to different people and different learning styles with different backgrounds (not to mention the numerous sites, blogs and video resources out there beyond what Apple provides). Over the course of 2009 we’ll be taking a look at some books in a new series called TUAW Bookshelf. We won’t just be covering developer resources, either. There’s a wide world of Apple-related reading out there, so stay tuned as we pull from our personal libraries and share our thoughts on what’s available.
To kick things off I read iPhone in Action by Christopher Allen and Shannon Appelcline, published by Manning. I wound up reading this first because one of the authors threw a few copies at me while at Macworld (sorry, I don’t know who you are and I can’t seem to find your business card!). We’ve got a few to give away, but look for that in another post this month.
iPhone in Action is designed to be a soup-to-nuts intro to almost everything you can develop for the iPhone. This includes web apps, which was the book’s main focus until the SDK was announced while they were writing. I don’t think shifting focus to the SDK is a bad thing, and as near as I can tell it didn’t hurt the content. In fact, I thought this book would make an excellent primer to Apple’s mobile platform efforts. Having taught technology for six years, I can say this is the book I’d use for a 100-level course in developing for the iPhone. I’m not saying it will make you into an expert overnight, and I’m not saying you can’t come to the table with zero dev experience, but as a starting point, it is wonderful. To find out why, keep reading…
Continue reading TUAW Bookshelf: iPhone in Action
TUAWTUAW Bookshelf: iPhone in Action originally appeared on The Unofficial Apple Weblog (TUAW) on Wed, 04 Mar 2009 18:00:00 EST. Please see our terms for use of feeds.
Read‘|’Permalink‘|’Email this‘|’Comments“
Debug Cocoa with DTrace Guide & Embedding DTrace into Xcode Video: “Debugging Cocoa with DTrace GuideFinally today I can finally reveal my Debugging Cocoa with DTrace guide to you. I had originally meant that this be a quick article on this site, but I kept adding and adding to it and finally by the time I knew what I had gotten myself into it was 40+ pages long. This guide isn’t as comprehensive as I would like even at the length that it is. It covers many”
(Via Cocoa Samurai.)
Understanding Flipped Coordinate Systems: “
Flipped coordinate systems always seem to confuse people, myself included. After working things out with pen and paper or handpuppets, I always feel like they’re not quite correct so I thought I’d resolve things here. If anything, I can refer back to it whenever I forget this stuff (which happens every couple years). First a refresher in case you need it: Cocoa Drawing Guide: Flipped Coordinate Systems.
The main thing to keep in mind is that while a flipped coordinate system is basically translating the origin to the top left and flipping things vertically, semantically it doesn’t mean that everything is upside-down. Images, text and other elements are supposed to render right-side-up. The flipped coordinates should affect where those elements are placed, not how they are rendered. Being flipped is a higher level notion and is separate from the
CTM. While setting something as flipped will flip the CTM, modifying the CTM without setting the graphics context as flipped results in everything being entirely upside-down, which is different. Many of the Cocoa classes and functions take flipped coordinate systems into account and will draw right-side-up for you but it gets tricky with images.
There are two sets of methods in NSImage to render it in a graphics context: the -composite... methods and the -draw... methods. I’ve put together an interactive example app to help illustrate the differences. It might help you to download it now so you can follow along. The figures included in this article are from that app
The -composite... methods actually seem to work in the sense that the image is always right-side-up. The problem is that it draws ‘upward’ from the draw point regardless of the coordinate system. The result is you have to calculate the compositing point at the upper left corner of the image instead of lower left. This is the result of these methods not taking the CTM into account in terms of scaling and rotation. That also means that if you scale your view up, the images won’t scale with it. While you can use this to your advantage in some cases (like rendering resize handles or labels which you want to stay the same size regardless of zoom), it’s usually not the right way to do it.
View scaled at 2x. Notice how the composited version does not scale.
The -draw... methods on the other hand follow the CTM properly. That also means that if the view is flipped, so is the image, so you need to adjust accordingly. So while these methods obey the CTM, they do not take into account the flipped flag of the context which would be the cue to draw things right-side-up.
The draw... routines follow the CTM, but not the flipped flag.
Now, to complicate things even further, NSImage’s themselves can be flipped. The reason for this isn’t to make the images upside-down. It’s there to provide a flipped coordinate system for whenever you draw into it (i.e. lockFocus on it, draw, then unlockFocus). It’s useful for when you want to tell a flipped view to draw into an NSImage, for instance. It’s basically like a flipped view; you don’t expect a flipped view to draw upside down, no matter which view you set as its superview. A subtlety to be aware of is that flipping an image loaded from a bitmap does not make too much conceptual sense (you are changing the coordinate system after the content has already been ‘drawn’) but it does have the practical effect of flipping the image vertically, which seems to be an implementation detail. Yes, flipping the image will work to ‘correct’ orientation problems in most cases but, depending on where your image gets its data (for instance if it has an NSCustomImageRep like the example app – see below) and whatever implementation-specific details lurk in NSImage, you may end up with undesired or inconsistent results.
As mentioned above, I’ve put together a little interactive example app (Leopard-only) to show how the different methods behave. In addition, I’ve written methods in an NSImage category (-drawAdjusted...) which will render the image correctly regardless of the flipped status of the coordinate system it draws into. As suggested in Apple’s docs, it does a transform reversing the flip, draws the image, then reverts the coordinate system back.
The image itself is drawn by code, not loaded from a bitmap. The reason for this is that I also wanted to illustrate using flipped images. It draws an arrow and some text to indicate the proper orientation. When flipped, the drawing code is exactly the same in that no coordinates are recalculated. The text content is changed to compensate for the new orientation. Notice how the text renders right side up no matter the flip state of the image; an indication that the NSString drawing methods are ‘flip-aware.’ Also, it shows how to check the graphics context to get its flipped status so you can make your own drawing routines flip-aware as well.
Unfortunately, not everyone draws flipped images correctly. One place in particular is NSView’s/NSWindow’s -dragImage:at:offset:event:pasteboard:source:slideBack: method which will draw flipped images upside-down. Since you can’t control how the image is drawn, you can instead draw your flipped image into another non-flipped image and pass that in. I’ve added a method to the NSImage category to do this and you can check out the result in the example app (you can drag the image out of the views though only the last one has the corrected version).
And what if you actually want to draw everything upside-down, you irrepressible nut? Well, apply your own transforms using NSAffineTransform or CGAffineTransform. Just remember to concat the transform and not set it (a good general rule when using affine transforms). As long as you don’t tell any classes that you’re flipped, it should work out.
Hopefully this didn’t make things even more confusing (and also, hopefully, my interpretation of all this is correct). If you are still lost then just follow these rules:
-drawAdjusted... methods in my category (or similar technique) to do all your image drawing.-unflippedImage method in my category to get an unflipped version of the image and use that instead.That should handle most cases you run into. And trust me on rule #4.
“
(Via Noodlings.)
Dropping NSLog in release builds: “
NSLog() is a great tool that helps debugging efforts. Unfortunately it is expensive, especially on the iPhone, and depending on how it’s used or what you’re logging, it could leak sensitive or proprietary information. If you look around the web, you’ll find a few different ways to drop NSLog in your release builds. Here is what I’ve put together based on those.
First add the following to the <AppName>_Prefix.pch file in your Xcode project:
#ifdef DEBUG
# define DLog(...) NSLog(__VA_ARGS__)
#else
# define DLog(...) /* */
#endif
#define ALog(...) NSLog(__VA_ARGS__)
Right-click on your target and click Get Info. Select the Build tab. Make sure Configuration is set to Debug. Add -DDEBUG to the Other C Flags of your target.
And that’s about it. When you want to log only in debug builds use DLog(). In release builds DLog() will be compiled as an empty comment. Otherwise use ALog() for logging in both debug and release builds. (A as in always.)
I like this approach for a few reasons:
If you’d like to replace NSLog with DLog in your source files, here’s a quick sed command that you can run in Terminal:
$ sed -i '.bak' 's/NSLog/DLog/' *.m
FYI, this will make a backup of each of the .m files whether it changed them or not.
“
(Via Cocoa Is My Girlfriend.)
Record Your Core Animation Animation: “
Every once in a while I find a way to combine multiple technologies that, while they don’t produce anything terribly useful, are very interesting when combined. In this post I will be taking a look at combining Core Animation and QuickTime. As you may or may not be aware, you can draw in a graphics context while your Core Animation animation is running and add each image created to a QTMovie object from QTKit. This enables you to create a QuickTime movie of your Core Animation animation. Here’s how.
The basic process flow goes like this. Clicking the ‘Capture’ button on the user interface calls an IBAction called -saveAnimation. It prompts the user to select an output file for the movie. When the user has selected the file, the animations are created and added to the layer. Next we create a timer that is going to call a function that will grab the current frame and place it into the QTMovie object using -addImage at a specified interval. We set our AppDelegate to also be the delegate for the animation group so that when the animation completes we get notified and can then write our QTMovie object data to disk.
First you are going to need an animation that is worth recording. Of course any old animation will do, but we’ll keep it interesting by adding multiple animations to a single layer. I have created four different keyframe animations that we will add to an animation group. The keypaths are ‘backgroundColor’, ‘borderWidth’, ‘position’, and ‘bounds’. Check the sample code to see how these animations are constructed.
We set the duration for all of the animations to five seconds. We also need to make sure that we set the duration for the group itself, otherwise it will override the five second duration we set for the animations themselves and run in the default 0.25 seconds. The code below shows how the animations are added to the layer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
- (void)loadAnimations; { CAAnimationGroup *group = [CAAnimationGroup animation]; ' [group setAnimations:[NSArray arrayWithObjects:[self backgroundColorAnimation], [self borderWidthAnimation], [self positionAnimation], [self boundsAnimation], nil]]; ' [group setValue:@'mainGroup' forKey:@'name']; [group setDuration:5.0]; [group setAutoreverses:YES]; [group setDelegate:self]; ' [layer addAnimation:group forKey:@'group']; } |
Notice that we have used KVC here to set a name for the animation group. We will use this as a tag later to make sure the animation that triggers our -animationDidStop:finished animation delegate is the correct one. More on that later.
Prior to loading the animations, we prompt the user to select a file to write the movie file to. After loading the animations, we start our timer.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
- (IBAction)saveAnimation:(id)sender; { NSSavePanel *savePanel; ' savePanel = [NSSavePanel savePanel]; [savePanel setExtensionHidden:YES]; [savePanel setCanSelectHiddenExtension:NO]; [savePanel setTreatsFilePackagesAsDirectories:NO]; ' if( [savePanel runModal] == NSOKButton ) { movie = [[QTMovie alloc] initToWritableFile:[savePanel filename] error:nil]; } ' [self loadAnimations]; ' timer = [NSTimer scheduledTimerWithTimeInterval:1.0/(NSTimeInterval)10.0 target:self selector:@selector(updateTime:) userInfo:NULL repeats:YES]; ' } |
Our -updateTime selector will get called every 1/10th of a second and will grab the current frame to save it to the QTMoive object. Here is the -updateTime code.
1 2 3 4 5 6 7 8 9 10 11 |
- (void)updateTime:(NSTimer*)theTimer; { NSBitmapImageRep *image = [self getCurrentFrame]; ' QTTime time = QTMakeTime(1, 10); NSDictionary *attrs = [NSDictionary dictionaryWithObject:@'png ' forKey:QTAddImageCodecType]; NSImage *img = [[NSImage alloc] initWithData:[image TIFFRepresentation]]; [movie addImage:img forDuration:time withAttributes:attrs]; ' [image release]; } |
The code to obtain the current frame is somewhat lengthy, but the concepts are pretty simple. We need to create a graphics context that we can draw into and then draw into it using the presentationLayer of the contenView’s root layer. If you’re not familiar, the presentationLayer provides the current state of the animated fields while ‘in-flight’.
Core Animation doesn’t provide any callbacks for when a frame is ready to be displayed which is why we are using a timer. This means that we may be capturing more frames than we need to, so getting the right frame rate takes a bit of trial and error, which I have to confess I wasn’t able to get nailed down completely. I’m still working on it and will update here when I get that part figured out. Meanwhile, here is the code for -getCurrentFrame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
- (NSBitmapImageRep*)getCurrentFrame; { CGContextRef context = NULL; CGColorSpaceRef colorSpace; int bitmapByteCount; int bitmapBytesPerRow; ' int pixelsHigh = (int)[[[window contentView] layer] bounds].size.height; int pixelsWide = (int)[[[window contentView] layer] bounds].size.width; ' bitmapBytesPerRow = (pixelsWide * 4); bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); ' colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); ' context = CGBitmapContextCreate (NULL, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast); if (context== NULL) { NSLog(@'Failed to create context.'); return nil; } ' CGColorSpaceRelease( colorSpace ); ' [[[[window contentView] layer] presentationLayer] renderInContext:context]; ' CGImageRef img = CGBitmapContextCreateImage(context); NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:img]; CFRelease(img); ' return bitmap; ' } |
Notice that we are calling -renderInContext on the presentationLayer of the window’s contentView’s root layer. If we were only to render our animated layer, we wouldn’t be able to see the animation as it will only render the containing rectangle of the animating layer.
Finally we need to write the movie data out to disk. The QTMovie object provides a single call to do so, but we need a way to know when the animation has finished so we can make this call. When we created our animation group, we set its delegate to our AppDelegate which will cause the delegate method -animationDidStop:finished to get called. Remember that setting the delegate for each of the individual animations gets ignored when you are using an animation group. We implement the -animationDidStop:finished delegate as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 |
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag; { NSLog(@'Animation stopped: %@', theAnimation); ' id name = [theAnimation valueForKey:@'name']; if( name ) if( [name isEqualToString:@'mainGroup'] ) { [movie updateMovieFile]; [timer invalidate]; } } |
The first thing we do is check the animation tag we set when creating the animation group. This really isn’t necessary in this code example since there is only one animation that is going to use it, but this code shows you how to differentiate if you were to use multiple animations or groups and wanted to know when each of them finished animating.
The call to -updateMovieFile writes the data to disk and we now have a QuickTime movie that will play our animation. Open the resulting file in QuickTime or just invoke QuickLook to see the result.
Maybe you can think of a use for this kind of thing. I haven’t yet-other than for writing a blog post of course. Shoot me your thoughts and comments in the comments section. Until next time.
CA Animation Capture Demo Project
“
(Via Cocoa Is My Girlfriend.)