Friday, October 23, 2009

Meet Me, NYC, Nov. 5th

On November 5th, I'll be speaking at the Apple Store SoHo in New York City. I'll be speaking at the MetroMac meeting. The meeting is from 6:00 to 9:00, but I won't be speaking for the entire meeting. I believe I've been given roughly between ninety minutes and two hours, though, which is probably longer than anyone should have to listen to me.

I've been given fairly free reign in terms of what I speak about, as long as it's relevant to the audience (iPhone, Mac, etc), however be aware that MetroMac is not a developer group and the audience will run the gamut from consumer to total gearhead. As a result, the talk will not be particularly technical (at least not hardcore developer-type technical). I'll be leaving about twenty minutes to a half hour for questions, and will be happy to answer questions and chat even after the meeting is done.

Although I've been to the Flagship 5th Avenue store a few times, I've never been to the SoHo store, so I'm really looking forward to the talk, though it'll be the first time I'll have given a non-technical presentation in… well, years, so if I make a fool of myself, pretend I didn't, 'kay?

Because of how far away I live and how late the talk is, I'm also in the city for the night, so I could probably be talked into having a beer or three after the meeting with any City Geeks who are allowed to stay out after curfew.

Live in or near NYC? Stop by and say hi.

Marble Madness?

The developer of Stone Loops, a marble game that used to be available in the App Store, has a very discouraging tale to tell in his blog today. Obviously, this is only one side of the story, but it does seem very suspicious to me that MumboJumbo only made these hefty claims of improper and illegal activity to Apple and not in any other forum (like, say, legal proceedings) nor have they leveled the same complaint about the multitude of previously existing platform version of Stone Loops. If Code Minions had really stolen code (among the things alleged from MumboJumbo), it seems like they would be taking more serious action than just complaining to Apple, that is, unless they don't have sufficient evidence to meet the standard of proof anywhere else, but if that's the case, then Apple shouldn't have removed a competitor's application without being shown proof.

I'll refrain from judgment until I hear the other side of the story, but if things are as laid out in Maciej's blog, then Stone Loops should be restored to the App Store immediately. On top of that, Luxor should be pulled from the store just as immediately, as punishment for making unfounded allegations about a competitor. I'd even go so far as to consider pulling MumboJumbo's developer privileges if this is true, and it were my call to make. I have no tolerance for underhanded tactics, especially when resorted to by companies failing to compete on their merits (I'm looking at you, Nokia).

Again, we don't know the whole story now, because neither Luxor nor Apple has addressed Maciej's allegations yet, so let's not pull out the torches and pitch forks just yet. You might want to sharpen the pitch forks, though, just in case. Apple is unlikely to make a public statement about this; it's just not their style, but MumboJumbo, at very least, should respond.

Personally, I think Apple should impose a new policy. When someone makes an allegation of impropriety about a competitor, they should pull both apps until it's resolved. After resolution, the prevailing party's app goes back on the store, the other does not. This may seem harsh, but it would make people think twice about leveling accusations unless they have substantial proof to back up their claims. Of course, this only works if Apple also puts in a mechanism to expedite resolution of conflicts and they may just not want to get into that business. But, as sole gatekeeper of the sole way to sell iPhone applications, they should have expected conflicts of this nature to arise and should be willing to deal with them in a fair and expeditious manner.

SQLitePersistentObjects Lives. It LIVES!

I know that some people were understandably upset and annoyed when I decided to stop new development on SQLitePersistentObjects. Although it's a project that I really enjoyed working on, I just couldn't justify spending more time on it in light of Apple's release of the far more mature Core Data in the iPhone SDK 3.0.

Although I like certain things about the approach I took in SQLitePersistentObjects better than Core Data (like not having a data model file separate from the data model classes), it would have taken literally hundreds of hours (at least, maybe thousands) to get it to the point where the performance and feature set were comparable to what Core Data already has. Even if we got the performance and features to a comparable point, there's just not enough compelling advantages over Core Data to justify spending more time on it. At least, that's the case for me.

But, I must say, that I'm happy to hear that development on SQLitePersistentObjects continues! You can read more here. I wish Andrew the best of luck with this project. It's nice to see the code I abandoned was adopted by new loving parent. So, if you're using SQLitePersistentObjects and have been dreading the move to Core Data, check the new version out.

Thursday, October 22, 2009

Tech Talk World Tour

I didn't blog about this year's iPhone Tech Talk World Tour when it was announced. Many of the locations filled up so fast, it seemed like it would be just a tease to tell people about it when it was too late to actually do anything about it.

If you did sign up, I've gotten word from a handful of people that acceptance e-mails have started to trickle out of Cupertino. I signed up for the NYC Tech Talk, but haven't received word either way yet. Fingers crossed.

Nice One, Microsoft

Microsoft opened their first Apple Store today. Wait, no. What I mean to say is that Microsoft opened their first Microsoft Store. That's the ticket. And it's very unique. I can't even imagine where they got the idea for the layout, decor, uniforms or grand opening welcome line. I also can't fathom where they got their inspiration for opening a boutique-style retail store in the first place.

Hey, Redmond? Need a new tagline? How about?

If it's blatant, it's Microsoft.

or, maybe

We do shameless better.

I think either of those would work well, and both would be accurate and honest. Although, in Microsoft's defense, Apple grand openings never have guys in suits at the end of the welcome line golf clapping. That's original.

Patent Lawsuits: the Last Resort of the Mediocre

Nokia today announced they are suing Apple . Right in the press release, Nokia states that they are suing over patents that cover implementations of standards (GSM, WCDMA, WLAN, UMTS).

WTF? That kind of misses the point of having an open standard in the first place. There's only so much difference between different implementations of the same protocol or standard. Jeebus! The problem with these cases, though, is that the judges are experts in law, but not in technology, so they rarely have the knowledge and/or cojones to issue summary judgment even in cases with no merits. Like this one. So, Nokia will, at very least, cause Apple to spend millions of dollars to defend themselve.

Apple's release of the iPhone pretty much meant I'd never buy another Nokia phone again for myself, but now I will actively avoid their products. I won't recommend them to others and I won't buy them for family members. If this is how they hope to succeed in the future, I hope Nokia dies a quick and painful corporate death.

Tuesday, October 20, 2009

Wil Shipley on Internationalization and Localization

Words of wisdom and free code from the Godfather of Cocoa, Wil Shipley. Go read now. Nuff said.

Good Day for Android, Bad Day for Pre

The Palm Pre lost a high profile developer today (Jamie Zawinski, a notable contributor to many open source projects include Mozilla and XEmacs). He took some pretty harsh parting shots on his way out the door.

Having an App Store that's more open than Apple's is one way to compete, but it's not enough. If consumers don't have a good experience with your phone, developers are not going to want to develop for it.

The Nook

For whatever reason, Amazon's Kindle has never really appealed to me. Though I read a fair amount, and am not opposed to the idea of an e-reader, I've just never had any techno-lust for it. It's not because of the DRM, though I'd rather they didn't have it. It's just that it's not that exciting. It's basically a one-trick pony. No matter how thin they make it, or how many books it can hold, it will only every serve the very limited purposes of reading books and doing some light web browsing. Boring. I can do both of those things on my phone, albeit on less than an ideal screen size, or on my laptop.

Today, Barnes & Noble announced their competitor, the Nook. The Nook is based on Android. Now, people who read this blog know that my opinion of Android is that it's not as good as the iPhone in most respects, both from the point of view of a consumer and from the point of view of a developer. Obviously, that's subjective, but it's my honest opinion of where things stand right now.

However, I see the Nook as possibly a game changer for Android, much more so than the much-touted Verizon Droid, which might be a good phone, but it doesn't strike me as a game changer as much as being a not-totally-horrible-like-the-Voyager ersatz iPhone for people unwilling to switch to AT&T. I'm not quite ready to say it IS a game changer, but it definitely could be. It's a book reader that can be more. It's a tablet device that can be programmed. It's bigger than a phone, but still portable. This device, in my opinion, is every so much more techno-lustworthy than the Kindle. It also raises the bar for Android. Here's a whole new audience of devices that will be able to buy Android apps.

Of course, we'll have to see how it actually performs and how people like it. But assuming it delivers on its promises, then I'd say that Android just pulled out a tiny bit from the pack and its odds are looking better. There's a long ways to go in the race, but this could be a turning point. This could be the thing Android needs to achieve critical mass for their App Store, which is the one thing that they absolutely must have if they're ever going to challenge the iPhone's dominance.

I can't wait to see where this goes from here, and I can't wait for Apple to introduce some kind of new iPhone OS device, whether it's a tablet, or something completely new. I don't have any idea what Apple is going to do, but I'm sure they are not going to stand still.

Monday, October 19, 2009

Oh, My. Fiscal Results.

Today, Apple announced their Fiscal 2009 Q4 and boy, what a quarter it was. Funny, it's been a while since I heard someone predict the death of Apple. It's hard to believe just how common a practice that was among pundits only a decade ago.

Apple sold more iPhones and more Macs last quarter than in any previous quarter in history, and they have the largest percentage of the market share they've had since 1994. That's true whether you take the lower Gartner number of 8.8% market share, or the higher IDC number of 9.4%.

Friday, October 16, 2009

Accessorizer 1.5

I've posted about Accessorizer before. It's just been updated to version 1.5, incorporating a new feature that sprang out of a feature request that was made by yours truly. Actually, it was more of an off-hand comment then a feature request, but Kevin Callahan, the brains behind Accessorizer liked the request and jumped on it with gusto.

The new feature? Accessorizer now has the ability to auto-detect classes that are commonly used as outlets and, if you want it to, will add the IBOutlet keyword automatically to the generated property statements. I've been beta testing this new functionality, and works pretty darn well.

If you do any significant amount of Objective-C programming and haven't tried Accessorizer, I'd really suggest giving it a try. In the application I wrote today for More iPhone 3 Development, I'd estimate that Accessorizer saved me at least five minutes of typing (not to mention greatly reduced the chances of mistakes and typos). I typed in only my instance variables, then a few short keystrokes and about twenty seconds later, I had my property declarations complete with IBOutlet keyword where needed, @synthesize declarations, and both NSCoding methods. You don't have to write too many classes for it to pay for itself if you do this for a living. If you're a hobbyist then, in a way, your time is even more valuable.

And if you're not sure how to use it, or why you would use it, check out the Accessorizer videos in the lower right of the home page.

Device Detection Redux

A while back, I posted some code by Max Horáth to detect the device your program was running on. That script dates from the pre-3Gs days, so won't identify that model. I'm not sure if Max has updated his script, but I found this class on Stack Overflow by Jason Goldberg. In addition to adding the more recent hardware, it uses a really efficient approach implemented in relatively few lines of code. I like that a lot.

The one thing I don't like is the way the class is implemented. There's no reason to use instance methods like this and incur the overhead of object creation to. The object has no state, just behavior, so either of these methods could have been written either as C functions or as class methods, thus avoiding the need to create an object and manage its memory. At very least, this class should have been implemented as a singleton.

Anyone who's been reading my blog probably knows where I'm going here. In my ever-so-humble opinion, the best approach for this functionality have been to write it as a category on UIDevice, like so:

UIDevice-Platform.h
#import <Foundation/Foundation.h>

@interface UIDevice (platform)

- (NSString *) platform;
- (NSString *) platformString;

@end

UIDevice-Platform.m
#import "UIDevice-Platform.h"
#include <sys/types.h>
#include <sys/sysctl.h>

@implementation UIDevice (platform)

- (NSString *) platform{
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:machine];
free(machine);
return platform;
}

- (NSString *) platformString{
NSString *platform = [self platform];
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
return platform;
}

- (BOOL)supportsBluetoothNetworking {
NSString *platform = [self platform];
return !([platform isEqualToString:@"iPhone1,1"] || platform isEqualToString:@"iPod1,1"]);
}

@end

360|iDev Conference San Jose 2010

The dates for the 2010 360|iDev Conference in San Jose have been set for April 11-14 at the eBay Conference Center in San Jose, the same location as last year.


I really enjoyed last year's conference. Tom and John do a great job organizing things (and seem to like me despite my opinion on Flash), and it's one of the best groups of attendees you could imagine. I was bummed to have to skip out on the 360|iDev Denver last month due to being behind on my writing obligations.

Registration for the early-bird pricing is already open. Call for speakers will go out next week.

Thursday, October 15, 2009

In App Purchase Can Now Be Used for Free App

Yep, just got notified by Apple. Free apps. In-app purchase. Say good-bye to "Lite" apps.

The Little Things

I love when Apple's engineers quietly slip little things into the developer tools to make my life better. I commandeered my daughter's iPod Touch to do some peer to peer testing. Her iPod doesn't have my development provisioning profile on it, so when I went to run the app on it, I got this:



I have no idea when they added this, but I know it didn't always give me the option to install and run. It's a little thing, but it saved me from having to go find the right provisioning profile and install it on her iPod.

I'm often quick to note when something doesn't work right or as well as we'd like. I thought it was only fair to take a second to say kudos to Apple for quietly making my life just a little bit easier.

Don't Fear the Interface Builder Redux

Last week, when I advised readers not to fear Interface Builder, I left out one very important piece of information. I am far from the only one who says that using Interface Builder isn't really optional. Apple's documentation says exactly the same thing, in no uncertain terms. The relevant portion is as follows:
Note: Although you can create an Objective-C application without using nib files, doing so is very rare and not recommended. Depending on your application, avoiding the use of nib files can involve overriding large amounts of framework behavior to achieve the same results you would get using a nib file.
I don't think Apple could be much clearer on this point. Apple and NeXT developers have been using Interface Builder for twenty-one years, longer than many programmers have been programming. I think, at this point, they've got a pretty good handle on how it works and when it should be used. It boggles my mind that there's even a debate on this issue. There's really no excuse for creating your user interface in code in the vast majority of situations. Using Interface Builder is faster and much easier to maintain.

Don't fight the design, work with it.

Thanks to Saurabh Garg for pointing this out.

Tuesday, October 13, 2009

Gamasutra on Android Game Development

Gamasutra, a great website devoted to "the art and business of making games", has an article today on developing games for Android. Of course, about half of the article is spent discussing the success of the App Store and making comparisons to it.

Although I like the article, there are a few things in it that I take exception to. On the first page, for example, the article says that Android uses the "more developer friendly Java". What the hell does that mean? I've done both Java and Objective-C for a living, and neither one has ever waved to me or gotten me a cup of coffee. They're programming languages. Sure, there are more people who already know Java than Objective-C, but if that's what he meant, there were far more accurate ways of saying it.

It's also just plain wrong in terms of game programming. Objective-C is a superset of C and you can write entire games in C or C++ with the exception of a small amount of code to set up and configure your OpenGL ES view. Please don't even try to tell me that, from the perspective of a game programmer, Java is more "user friendly" than writing OpenGL code in C or C++.

Overall, the tone of the article is very optimistic, almost like a recruitment article hoping get people interested in Android development. They point to statistics to show that Android is gaining momentum and the iPhone is losing it. Well, you know what Disraeli said about statistics1.

If you follow the link in the last paragraph, the iPhone chart clearly does not show a decline in anything except in an artificial comparison to Android in terms of "percentage of projects started" (a dubious metric, at best). The iPhone is showing a slowdown in growth when looking at new projects being started, but there is still growth, and considering just how big and successful the store has been, that's kind of amazing. On the other hand, look at the Y-axis label on both charts. They are using completely different scales. If they were charted together on the same graph, the Android "flurry" of project starts would barely get over the first line, and it would do that in only one of the months charted. Also, while the iPhone may be experiencing a slowdown in new project starts, that's more than being offset by an increase in interest from the large gaming interests like EA and the fact that many more big, long-term projects are being started.

I don't want to come across as too down on Android. I think right now, of all the smart phones in the race, it's in the best position to be a real competitor to the iPhone, and a strong competitor is definitely something the iPhone needs. If I had to bet on which platform might overtake the iPhone someday, it would be Android, but I would not be betting a lot of money. There's still an open field for second place and a long distance between the pack and the current leader. Nobody currently jockeying for second place has begun to move substantially away from the pack toward the leader. At some point, somebody undoubtedly will break away and gain ground on the iPhone, but nobody - including Android - has started the kick yet. They might have a little better odds on placing, but they're still a long shot for winning.

Androids greatest advantage in that field also be its Achille's heel in terms of game development, which is the fact that Android is hardware agnostic. It will run on a variety of devices from different manufacturers with different CPUs and different GPUs. It will run on phones with touch screens and phones with keyboards. That's going to introduce a lot of complexity and make it hard to write apps that work perfectly on all Android devices that ever have been made or ever will be made, or even to identify how well it will run on any potential customer's phone. The only way for a developer to know if their game will perform well on any particular phone is to buy them all and test. That just isn't a possibility for the stereotypical garage game developer. This hardware agnosticism also means that optimizing game code for performance might result in improvements on one platform and then unexpectedly cause degradation on another. Those are issues that big game companies have the resources and experience to deal with, but are not so easy for smaller independent game developers.

Despite the issues, despite the difficulty competing in an increasingly large App Store that's beginning to get populated with big-budget games, I feel strongly that the iPhone is still the best game in town for the small, independent game developer, and it will continue to be well into the foreseeable future. Yes, you will still have to market your game. Yes, there is a chance of failure. The App Store is not magic, it's just a great opportunity.

Now, this equation will change over time, and this what I'm saying not be true a few years from now, but it's going to take time for Android to build momentum and gain ground. Right now, the games in the top ten on the Android Store are averaging well less than $100 a day income, and that's just not enough potential money for most people - big companies and independent developers alike - to see it as a viable opportunity proposition yet.



1: "There are three kinds of lies: lies, damned lies, and statistics." It was originally said by British Prime Minister Benjamin Disraeli. Sometimes it's wrongly attributed to Mark Twain. Though he certainly popularized it in America, the quote does not originate from him.

Monday, October 12, 2009

Why Objective-C Survives

Matt Gallagher, who maintains the excellent Cocoa with Love blog, has an interesting post today on the differences between the Simula and Smalltalk object models including a short discussion of the history of the two models. Objective-C uses the Smalltalk object model, most other compiled OO languages today (C++, Java, C#) follow the Simula model.

Friday, October 9, 2009

A Neat KVC Trick

Uli Kusterer has a neat little hint today on his blog with a safer way of specifying keys in KVC and KVO.

Mobile Photoshop

Adobe just released a mobile version of Photoshop for the iPhone. Let me just surprise a few people here by saying that Adobe did a pretty awesome job with this. It's a really nice little application, and it's free. Sweet. Although it doesn't appear to be available in all of the international versions of the App Store yet.

I can't help but think that this would have been a good showcase application to show off what Flash-generated iPhone applications can do. Alas, it appears to be a bog-standard Objective-C application, complete with nibs and byte-swapped PNG images.

Adobe's Ace in the Hole?

There's one thing I'm having trouble figuring out about this whole Flash CS5 thing. Adobe invested a lot of time and money to get Flash on the iPhone, seemingly against Apple's wishes. To sink that much time and money into trying to get software onto a closed, proprietary platform without the consent or help of the gatekeeper seems odd. From an outsider's perspective, Apple seems to hold all the cards. They have any number of technical means to prevent Flash-generated apps from going on to the App Store if they decide to. It seems to me that there's only two possible explanations for Adobe's actions.
  1. Their management is desperate and completely incompetent. Possible, but doesn't seem that likely. While Adobe has made a lot of decisions in the last few years that I consider poor, I haven't seen any evidence of this level of gross ineptitude

  2. They have leverage to use against Apple, or some reason to think Apple will allow them to do this. Perhaps, some kind of "ace in the hole" that Apple really wants? Perhaps a 64-bit version of their main CS5 apps, like Photoshop and Illustrator?
I don't know. Obviously, Adobe's not going to tell me anything, but one has to wonder if there isn't more to this than meets the eye.

Thursday, October 8, 2009

Louis Gerbarg on Flash for iPhone

The day that Adobe announced Flash CS5 with iPhone support, I took apart several of the Flash-generated iPhone applications and tweeted my findings. Louis Gerbarg has done a more detailed dissection of the Flash-generated iPhone ipa files (the actual file that gets downloaded from the App Store) than I did. He found the use of multiple (about a dozen) private API calls being used after doing what he calls a "cursory examination". His opinion of the size of the applications jived with mine as well (unnecessarily bloated), and he throws in some more concrete evidence showing that these apps do, in fact, perform poorly on iPhones prior to the 3Gs.

Louis' findings would cast some doubt on Adobe's claim that they didn't do any reverse engineering. Of course, in my mind, there already was a fair amount of doubt on that point.

Two Finger Rotate

Here is an Xcode project that shows how to do the two-finger rotate gesture. It's pretty straightforward, it just uses a CGAffineTransform to rotate the text on the screen to the same angle as the angle between the user's two fingers.

This project does not deal with the fact that touches come into the responder methods unordered, so you may notice some minor glitches if you try and do more than a 180° rotation. That's a subject for a future blog posting.

Wednesday, October 7, 2009

More Flash Thoughts

There's been a lot of interesting discussion around the whole Flash CS 5 generating iPhone Apps thing. None of it has changed my opinion that it's in Apple's best interests and ultimately the best interests of iPhone users for them to take steps to stop Adobe from moving forward with this, or at least for Apple to set some boundaries with Adobe and phase the program in over time to avoid overwhelming the App Store infrastructure. The problem is multi-faceted, which can be confusing. To me, it seems to break out into a couple of related, but distinct issues:


  1. Technical: Are the applications generated by Flash 5 as good, or at least "close enough" to being as good as those created using Xcode? It's not a simple question, because even the best tools can be used to generated sloppy, bloated executables, but it's still important to get a sense of whether the typical Flash-generated application is going to be comparable to the typical applications created using Xcode. It's an unanswered question. I'm sure Adobe is going to argue that their applications are just as good. I, and many other developers who have been working with the platform since it came out are going to be somewhat skeptical of that claim. How likely is it that they've been able to add an extra layer of complexity, including a garbage collector, and not incur any additional overhead? Probably nots possible, but the question then becomes: just how much overhead does it add? Is it enough to really matter?

    This is just an educated guess, but with first and second generation iPhones, I'm going to bet it will matter, and the simplistic nature of the Flash apps already on the App Store does little to dispel that notion. If the apps were really "just as good", they would have put a sample up that really showcased what they could do rather than just showcasing the fact that they could do something. If they were just-as-good, Adobe would have wowed us with a 3D game or something else that really pushed the limits of the iPhone's hardware. Even on my 3Gs, I thought the Flash iPhone apps all felt a little sluggish compared to what I'm accustomed to.

    Unfortunately, we have no objective data on this point right now. We have no way to take an app generated by Flash CS 5 and the same or similar app ported to Objective-C and compare them in meaningful ways. If someone would be willing to compile a version of a iPhone apps with debug symbols on, I might be able to get some hard data using the performance tools. As things stand, though, we have no objective data, and without that, it's all conjecture. We could argue forever, and neither side will concede anything.

    In my mind, there's enough reason to believe the apps won't be "as good" technically speaking, that it's fair to put the burden of proof on Adobe. They should prove that these Flash-generated apps are capable of being just as good or at least identify how close they are and support that claim with verifiable data. We already know the file size of the Flash-generated apps are considerably larger than comparable Objective-C apps created with Xcode. Subjective evidence seems to point to the apps also being slower. I'd like to see some hard evidence so we can judge them more fairly, but until some exists, I think it's a fair assumption that these Flash-generated apps are not as good and the differential is enough to matter. If somebody wants to prove me wrong, I'd be thrilled to see some hard evidence so we can discuss this intelligently. If I am wrong, believe me, I will be suitably impressed by the engineering that went into it.


  2. Logistical: There is a very large installed based of Flash developers and a large amount of existing content. The popularity of the App Store has already caused significant growing pains. The team responsible for doing App Reviews is overworked as it is and are doing a thankless job. Allowing existing Flash developers and existing Flash content to flood into the App Store almost overnight is bound to cause significant issues for the App Store infrastructure and the people responsible for maintaining it. That, in turn, will cause problems for customers and developers alike.


  3. Equitable: Related to the previous point, this flood of new content literally overnight is going to have a significant and detrimental impact on existing developers. You know, the ones who invested the time and effort to learn the platform and native tools? Those developers who will be penalized for that effort by having longer wait times and a lot more apps to compete with for attention. It's unlikely that the size of the App Store pie is going to increase measurably as a result of the influx, so an influx of new apps is inevitably going to dilute the chances for any single application to make a profit. It hardly seems very fair that the people who actually put effort into learning the platform and who have dedicated themselves to the platform won't be able to reap the benefits of that hard work without putting in addition effort to figure out how to get noticed above a sea of quickly-ported Flash games. Contrariwise, it hardly seems equitable to reward those who couldn't be bothered to learn the native tools.


  4. Political: Adobe and Apple long ago stopped being BFFs and have been in a somewhat contentious coopetition situation for quite some time. Apple made it very clear to Adobe on a number of occasions that Flash was unwelcome on the iPhone, and yet Adobe has continued to push ahead with an amazing disregard for that, fueled by what seems like a tremendous sense of entitlement: a feeling that they have a right to benefit from Apple's success with the iPhone even though they did not contribute to it in any way. The part that really doesn't sit right with me is that Adobe isn't being up front with their developers about how risky the situation is for them as a result of the politics of their relationship with Apple. Adobe didn't create Flash CS5's iPhone functionality with Apple's consent or knowledge. In fact, they did it despite being specifically told Flash wasn't welcome. That's pretty fucking rude. It's like inviting a million people over to somebody else's already-jam-packed party. Throw your own fucking party, man. Seriously. And the whole sneaky way Adobe went about putting their apps into the App Store just reeks of dishonesty. It's ends-justify-the-means thinking and it really does not endear me to Adobe at all.


  5. Legal: Despite Adobe's claims, I'm incredibly skeptical that they could have created the tools needed to generate iPhone apps without using Apple's toolchain at all given the amount of time it took them, unless they had access to the SDK and violated the legal agreement that they had to agree to to get access to it. Apparently, Adobe management is reassuring their employees internally that they respected the SDK agreement to "the best of their understanding" and are claiming that they didn't reverse engineer anything. I suppose it's possible, but it's improbable to the point of ridiculousness and I don't buy it.

    That Adobe could have figured out how to link to and use objects and functions from Apple's frameworks and figured out what to link to without some amount of reverse engineering just stretches credulity given how much of the iPhone's internals are not documented officially. Adobe's trying to make it sound like it was just a matter of compiling down to ARM assembly code and they didn't need to reverse engineer anything to do that. But it's not as simple as that. These generated applications have hooks into many of the existing Apple frameworks, including UIKit, OpenGL ES, Quartz, Core Animation, and Audio Queue Services. They are leveraging Apple functionality to do a fair chunk of the work, which means Adobe did more than just compile ActionScript to execute on the iPhone's ARM processor. A lot more.

    Even if they didn't reverse engineer anything, I would put forth that Flash 5's iPhone application generating ability IS a derivative work under section 2.5 of the iPhone SDK agreement. This would seem to be precisely the type of thing that Apple was trying to prohibit when they put that clause in the contract, so even if Adobe was completely above-board and did no reverse engineering, I think there's still grounds to allege they are in violation of the SDK agreement.

    At very least, I would say that there's sufficient grounds for Apple to bring legal proceedings if they choose to. They could very likely get an injunction to prevent Adobe from releasing the iPhone portion of Flash CS 5 if they wanted. I have no idea if Apple will go this route. I honestly doubt it's their first choice for dealing with the situation, but it's an option that's available to them and, therefore, is an added risk for Adobe and any Flash Devs who choose to use it.


It will be interesting to see how things unfold. The technical questions will eventually be known. At some point, we will be able to compare Objective-C and Flash-generated apps and get some concrete data about their size, efficiency, and performance. For the rest of it, the ball is really in Apple's court. Until Apple makes their next play, we don't really have an inkling of how this will all play out. Everything from Apple embracing Flash IPhone apps to an all-out war with Adobe is within the realm of possibility.

Code Consequences

I think we're all aware that our actions have consequences for ourselves and, often, for others. I'm going to talk about such a situation that is relevant to iPhone developers.

I've had to turn down some development work while writing More iPhone 3 Development. This isn't a big deal, as I expected that to happen when I agreed to do the book, and I like to see it, because it tells me that our platform is still doing well. However, a surprising number of the projects that I've turned down have been to fix iPhone applications written by other contract developers, something I don't consider to be such a good sign.

Even if I were available to take the work, there's something inherently uncomfortable about these situations. Some developer whose identity is unknown to me wrote this code. That developer has no chance to respond to my criticisms and I, in turn, have absolutely no idea of the situation under which the code was written. I feel like there's no right way to point out flaws in code like this. Yet, to fix the problem or even give an accurate estimate, those problems have to be identified.

In one such recent instance, the potential (and very trusting) client actually sent me their code along with the description of the problem. I knew that I couldn't take on a hefty project until the book is finished, but the description of the problem sounded like something that I might be able to be fix quickly and easily, so I looked at the code that evening.

The problem was exactly what I thought it was going to be based on the description, and I thought I'd be able to fix it with a few dozen lines of code over not more than a couple of hours, which would be a win for the prospective client and the client's users who were experiencing significant performance problems with relatively low volumes of data. In a well-designed application, fixing this specific problem wouldn't have impacted anything outside of a single class or, at worst, a handful of classes. It was a bottleneck in pure "Model" code in the MVC sense. In theory, as long as I didn't change the way the object's data was accessed and updated by other classes, I could change the implementation details, such as how the data was persisted, without impacting anything.

You know what they say about theories, right? They work great, in theory. But in practice…

So, yeah, that theory didn't pan out. I started looking at the rest of the project looking for potential cross-depenencies and I found that my assumption was totally and completely wrong. The underlying data store wasn't only vended through the data class, it was accessed directly by literally dozens of classes. In fact, all the actual persistence code - both loading and saving - (with the exception of encodeWithCoder: and decodeWithCoder:) was contained in controller classes. And there were dozens of these controller classes, many of which were nearly identical except for a handful of lines, which seemed to indicate a general lack of design or forethought. The core problem was thus made significantly harder to fix by a desperate and unrequited need for refactoring. There were, literally, several dozen classes that could have been written as a single-class or, at worst, a couple of subclasses with a common parent. The entire project looked like one thrown together by a tragically inexperienced developer, or one who didn't have any use for "this new fangled OO shit". Seriously, there should be a link to this project on the Wikipedia's spaghetti code entry, in the section on "Spaghetti with meatballs". Reading the project made me feel like I was in some weird programming equivalent of Poe's Law; I don't think I could intentionally create code this convoluted.

Now, I wish I could say that I'd never seen nor written bad code, but that wouldn't be true. I've seen lots of bad code over the years and have written more than I'd care to admit. Despite that, though, this code was worse than most of what I've seen, and that's saying something, given that my job for several years was fixing problems in other people's code.

After a couple of hours, I came to the inescapable conclusion that this job was beyond my ability to take on right now. I'm almost positive that it would be more work to try and fix the multitude of problems in this code than it would be to just rewrite the application from scratch. Even if not, the end result would certainly be better. Out of fairness to the prospective client, I had to explain why I had to turn down the project, something that seems likely to cause problems for the previous developer. I couldn't, in good conscious, not tell him, however. I did put it in far more diplomatic terms than I am doing here in my blog, at least, where I sometimes personify the fact that 'tact' is a four letter word.

The high demand for iPhone developers has made it a profitable livelihood and, I think, has caused many people to offer their services as iPhone developers without truly adequate experience. Hell, I've been working with the SDK as long as anybody outside of Apple, and I sometimes feel like I don't have "truly adequate experience" with it - that's the peril of a new technology I guess. Regardless, when you're developing for a client or employer rather than yourself, you really need to be aware that there will be downstream developers affected by the decision you make or fail to realize are there in the first place. When you cut a corner to save time or fail to use good design because you don't know any better or don't care, that decision may very well have significant consequences for your client and for other developers who inherit your code.

Good application architecture and writing good code takes a little longer in the short run, but in the long run, it requires much less of a time investment to maintain. Yes, I know most of us bill by the hour and writing bad code is far more profitable than writing good code, but don't do that. Seriously. That's worse than just being ignorant of how to write good code. Despite the economy, there's no shortage of iPhone development work right now, and even if that weren't the case, you owe it to your clients to give them the best code you are capable of writing.

Addendum: Based on some of the comments, I fear that this post has come across as rather more judgmental than intended. Contract software development, especially for clients who are not familiar with the process, is extraordinarily hard. No contract developer has ever, ever created a perfectly designed, bug-free application. In the real world, you have to deal with deadlines, unreasonable demands, and tons of other factors that work against you delivering a perfect application. I am not unsympathetic to this at all, as I have experienced it myself on countless occasions.

I intended this only as a cautionary tale to give you something to think about when deciding whether to cut a corner or to skip doing that rewrite you know you need to do, not as an indictment of anybody. Believe me, looking at some of my early contract work, I've got some pretty harsh words for myself.

One of the most important traits in a developer is the willingness to accept that no matter how good you are, you do make mistakes. You will never stop making mistakes and you will never stop being able to learn from those mistakes. Sometimes, you can even learn from others' mistakes and save yourself some pain.

Tuesday, October 6, 2009

What an Apple Offer Looks Like

No, I don't have an offer from Apple, but someone else does, and it's pretty damn cool to see what it looks like.

via CocoaGeek on Twitter

This Made Me Laugh

Sometimes 140 characters is just enough to make a point. If you don't get the reference, AOT is the term Adobe is using to describe what they're doing to avoid JIT compilation, which the iPhone SDK doesn't permit.

Sue Me, I Think Developers Should Care

James Higgs has a different take on MonoTouch and Flash for iPhone. You should read it. It's good to see other points of view.

That being said, I can't say that I agree with most of it. Indeed, I feel like James is missing the point and misrepresenting the point of view of well-respected members of the Objective-C community by cherrypicking individual tweets. The fact is, I agree with both tweets referenced in his blog post, even though they come off as a little crass and even elitist without context and given that the authors had only 140 characters to make a point.

To highlight my main difference with James' opinion, let me respond to his concluding paragraph that he seems to think no reasonable person could have a problem with, and tell you my problem with it:
It boils down to this: if MonoTouch and Adobe’s Applications for iPhone platform are no good, they will die. Developers who use them will sell fewer apps in the App Store. Objective-C developers will carry on developing apps in their preferred style and creating apps that sell well. But if the rival techniques are sound, everyone gets to write great iPhone apps, and the result is happy users, and an even wider adoption of the iPhone platform.
Here's the key point missed. It doesn't boil down to that. If MonoTouch and Flash for iPhone are no good, they won't die for a reason James himself pointed out earlier in the same posting: the users don't know or care how the application was created. If MonoTouch and Flash applications are slow and crash or use gobs of memory or break under future versions of the iPhone OS, the end users aren't going to take away a negative impression of Adobe or Novell, they're going to think "Apple Sucks". They're going to blame the iPhone. It will affect the users' opinion of the individual developer, sure, but first and foremost it's going to affect the users' opinions of the iPhone as a platform.

I'm pretty sure Apple will have a problem with that. If one app sucks, it's no big deal. If there are hundreds or thousands of apps that all break or perform poorly, that's going to impact the overall perception of the iPhone.

I, personally, have a problem with a developer who feels entitled to be able to develop for a platform without investing the time to learn the language or frameworks that platform was built around. Languages affect design. Objective-C has greatly affected the design of the iPhone application frameworks and, indirectly, the experience of iPhone users. If you can't be bothered to learn that, to understand the iPhone experience completely, that tells me that you just want a piece of the pie. You see something that's been phenomenally successful, and you want to be able to take advantage of Apple's success to make some fast money, but you're not willing to understand at even a superficial level the engineering that underlies that success.

This is vitally important on an embedded device. On a desktop computer, we can tolerate Flash because we have crazy fast processors, gobs of physical RAM, and full virtual memory. On the iPhone, the processors speeds are about ten years behind the desktop, we have a fraction of the RAM, and volatile memory won't get paged out to swap, so memory use and processor use are vitally important. Yet I should be "okay" with someone who wants to develop for the platform and is either ignorant or cavalier about these things? I don't think so.

A few paragraphs earlier, James says
Like me, many developers will welcome the chance to learn a new language and a new platform But many will just want to write an app and get it into the hands of their users as quickly as they can. (emphasis mine)
Exactly. That's exactly what I have a problem with. Getting an app into a users hands as quickly as possible is not a virtue. Getting an app to the user when it's done, and good, and well-tested, and performing well is. I don't want this mentality. I want developers like Snappy Touch, who obsess over the user experience. I want developers like Imangi, Flipside 5, Tim Haines, and the countless others who cared enough to dive in and learn the platform, learn the language and tools, and deliver great user experiences on the iPhone despite having to learn to do it. I want developers who care. Developers who care, care enough to use the right tools and invest time learning about their platform and about the users of that platform.

Part of the iPhone's success is exactly because there is an obstacle to entry for developers. It's not insurmountable, in fact it's pretty darn low, but it has tended to keep out the worst of the opportunists and hammer developers, and that's been a good thing. It's not a perfect environment, but it is pretty awesome, and it's a darn sight better than it would be if flooded with people who can't be bothered to learn a bit about the platform that they want to milk for all it's worth.

Here's another thought. Even with just Xcode and Objective-C available for building iPhone apps, the app review team at Apple is completely swamped and overrun and has a very difficult job. Do you think flooding the app store with iPhone ports of every crap Flash game in existence is going to help that situation? Hell no. It's going to make the situation so much worse. Now, try and tell me with a straight face that that isn't going to happen the second Flash 5 is released to the public. Of course it is. Every Flash developer is going to raid his or her portfolio for stuff they can quickly throw up on the App Store to try and make a quick buck.

Yeah, gosh, how could anybody not want that? That will make things so much better for iPhone users.

I don't know what Apple's going to do, but if it were me, I would let Adobe know, in no uncertain terms, that Flash apps are not welcome on the App Store and that Flash developers are more than welcome to come learn Objective-C and Cocoa Touch. If I were Apple, I'd be pretty darn annoyed at Adobe's insistence and willingness to resort to borderline unethical behavior to steal a piece of the iPhone and App Store pie, and I would take steps to protect the quality of the user experience on the iPhone, even drastic steps if necessary.

But, I'm not Apple, so only time will tell.

Monday, October 5, 2009

Adobe Adds iPhone Native App Creation to Flash

Today at Adobe Max 2009, Adobe announced the ability to create native iPhone applications using Flash 5. Now, this really has very little to do with my earlier rants about Flash, because it has nothing to do with Web Development. This is about creating native iPhone apps using ActionScript and Flash tools, which get compiled down to ARM assembly. You can find some more technical information about how they do it here and an FAQ here.

It's an interesting development, and I'm not sure what to think about it. At first glance, it certainly seems like a good move on Adobe's part, as it will make a great marketing point for their dev platform. From a realistic standpoint, though, it doesn't change my opinion that you should avoid hammer development principles and should choose the best tools for each platform. Flash has always been a compromise that takes considerable overhead to let you create applications that can run on multiple platforms while feeling native on none and getting native performance on none.

I also think that using this technology carries significant risks until Apple's position on it is made clear. I've seen no indication that Adobe worked with Apple on it and have seen at least one claim that it was done without Apple's involvement, knowledge, or consent. If that's true, it will be interesting to see how this plays out, but I wouldn't advise even touching the technology until Apple's opinion is known.

There are currently several applications on the App Store created with the private beta version of the Flash iPhone SDK. Out of curiosity, I downloaded several of them to check them out.

First impression: the end-user is unlikely to have any idea how the application was created. There's nothing about these Flash-created applications that screams "Flash". They look like pretty much exactly like any other immersive iPhone applications. That's good.

The next thing I noticed is that none of the applications are particularly advanced or feature things that would tax the hardware or need to leverage the GPU - no 3D rendering, no crazy amounts of animation, no particle generators. They seem to have the equivalent functionality to Flash games from seven or eight years ago though, to be fair, these are early beta experiments, and I probably shouldn't read too much into that. But, these first examples do feel a little sluggish for what they are.

The applications are also bloated for what they are. That Roach Game is nearly ten megs in size for a game that lets you squash roach silhouettes. Red Hood (App Store Link), is twelve megs in size for a point and click game that shows two static images and you have to find the differences. It's little more than an interactive Highlight magazine on the iPhone, with better artwork. The size is an important thing, since apps over ten megs can't be downloaded over wireless connections from the phone and most people buy over wireless. I would bet good money that these applications, rewritten as a native App, would be at least half the size. Which, of course, makes me wonder why there's so much extra code if there isn't an interpreter or JIT compiler in there. But Adobe claims there isn't and that this is compliant with Apple's 'no interpreters or compiler' term of the SDK. I'm not sure I buy that. I'm not sure Apple will either. I suspect there will be a lot of scrutiny applied to the binaries they produce, at very least.

As I dug in further, I noticed that everything gets compiled into the executable. In a typical iPhone application bundle, all the images and sounds files are stored as individual files, separate from the executable, which contains pretty much only the code. If you unzip a Flash-generated .ipa file, you don't see the typical application bundle structure. Other than the splash screen and icon, you don't see any resource files at all, but the executable file is enormous because all the resources are inside of it. This makes me wonder if these Flash-generated apps are memory efficient, which is very important when writing for first and second generation phones. It's not impossible that they could be, but this doesn't seem like the best storage option for an embedded application.

Digging in even more, I noticed that the images in these apps are PNGs, as recommended for iPhone development, but are not byte-order aligned with the iPhone's video memory (GBRA instead of RGBA). So, Flash iPhone apps would appear to get all the disadvantages of the PNG file format, like no lossy compression, without the advantages you get in Xcode-generated iPhone apps (byte alignment to speed up blitting).

The binary executable inside these Flash apps does link to a number of the standard iPhone frameworks, including UIKit (which Flash developers can't access directly according to the FAQ), Audio Queue Services, Core Graphics, and OpenGL ES. Supposedly these Flash apps can leverage hardware acceleration, which the linking seems to support, though the application performance seems to undermine.

Certainly, many Adobe Flash/Flex/Air devs who are scared by Objective-C are celebrating today. I think that celebration should be tempered with a note of caution.

I'm curious to see Apple's reaction to Adobe's back-door insertion of Flash apps into the store before publicly announcing the technology. That was a smart marketing move on Adobe's part - if Apple doesn't yank the apps, it validates Flash as an iPhone dev tool, but if Apple does pull them, they give Adobe assloads of free publicity in the process. Brilliant… in a skeevy sort of way.

Of course, since Adobe doesn't appear to be doing this in partnership with Apple, then it seems unfathomable that Adobe could have accomplished this feat without having violated the iPhone SDK agreement, specifically section 2.5 which prohibits reverse engineering or redistribution of any of the SDK components as well as the creation of any derivative works. Heck, I think you could argue that Flash 5 with iPhone support IS a derivative work under 2.5, and if it's not, there was no way they could have created it without reverse engineering parts of the SDK.

My guess is that Apple won't take kindly to Adobe reverse engineering certain undocumented parts of the SDK. I'm curious if Apple will confront them, and if they do, if it will be directly, or if they'll just do what they did with Palm and make it so Flash-generated iPhone apps stop working. Given how different the application bundles are between an Xcode-generated application and a Flash-generated iPhone application, it would be trivial for Apple to do that, if they wanted to. Heck, it's even possible that these apps will break on future versions of the SDK just because their bundles are different even without Apple doing anything intentional.

If I were a Flash developer, I wouldn't cheer just yet. This looks like a risky proposition to me at present. Adobe and Apple are still acting in an antagonistic fashion toward each other. Adobe could very well have crossed the line here. There are both legal and technical options open to Apple to prevent Adobe from doing this if they choose to. Will they? I honestly don't know. Apple still makes money from apps that are created with Flash tools, so they might just ignore it and take their 30% cut quietly.

But my gut says they are probably not going to do that. If I had to bet, I'd bet that this isn't going to sit well with Apple, and isn't going to play out well for Adobe. I think I would avoid using Flash for creating iPhone apps until and unless Apple gives the process some kind of blessing. Until that happens, it's just darn risky. Your apps could just stop working. They could get yanked. They could act oddly with future releases of the iPhone OS. I'm not saying any of that will happen, just that it's a risk that Adobe's not being up front with Flash developers about.

We do live in interesting times.

Sunday, October 4, 2009

Great Stack Overflow "Question"

I'm not a huge user of Stack Overflow, but that's mostly a byproduct of having very little free time at the moment; I think it's a great resource and am surprised by just how often the exact question I have is answered there, saving me the time of figuring it out or researching the Apple's documentation (don't disregard the documentation just because you find an answer there, though!). When my life settles down a bit, I hope to contribute some responses to unanswered questions.

Recently, somebody referred me to a question on Stack Overflow that's actually a mini-treatise on the use of UIImagePickerController. I'm not sure why the author, Peter Hosey, chose to post this information as a question, but there's a lot of great information there, and it's well worth a read if you use UIImagePickerController in your applications.

Whoops!: I screwed up. As was pointed out in the comments, the original author was Itay Neeman. Itay turned the question into a community Wiki, and Peter Hosey was one of a handful of people who made contributions. My apologies for the screwup.

Thursday, October 1, 2009

Translations

Today, I received the Japanese and Korean translations of Beginning iPhone 3 Development, along with the Japanese translation of Learn Objective-C 2.0, which I was the tech reviewer on. I really like these, though I can't read a word of either language.



Don't Fear the Interface Builder

The question of whether to use Interface Builder is not one most experienced Cocoa developers that I've talked to struggle with. Basically, they use Interface Builder unless they have a good reason not to. And reasons not to are relatively rare.

In the days before the iPhone, Apple's Cocoa Dev Mailing List would once in a while get a question from somebody new to Objective-C and Cocoa who wanted to create their GUIs programmatically. Here's a response to one of those questions from knowledgeable Cocoa/NeXTSTEP programmer and frequent Cocoa-Dev contributor John C. Randolph way back in 2001 that pretty much nails it:
This question comes up fairly often, and the answer is yes, it can all be done in code (which, after all is what -loadNibFile: is doing), but there's no more reason to abandon IB than there is to forego compilers and write all your code with a hex editor.
Yep. I couldn't think of a better way to say it, which is why I've quoted John's eight-year old response.

With the popularity of the iPhone, we've seen an upsurge in the number of people wanting to create their interfaces programmatically again. There are a number of factors contributing to this. First and foremost is that we've got a lot of people from different backgrounds, including people who have worked with languages and tools with GUI builders that use different, more problematic approaches or who have simply never worked with building GUI applications in a compiled language at all. Another reasons is that Interface Builder wasn't initially available for the iPhone, so a lot of applications and even a fair amount of early Apple sample code was written without it, so newcomers get a false sense that Interface Builder is just optional: purely personal preference.

Prompted by a comment in a recent blog posting, I've decided to try and explain in more detail why you shouldn't avoid Interface Builder. Most of this information is recycled from my iPhone Boot Camp Workshop material.

If your gut is telling you to avoid Interface Buidler, for whatever reason, your gut is wrong. This isn't one of those cases where there's more than one right way and it's purely a matter of personal preference. Interface Builder is clearly the preferred way and with very good reason: it makes your applications faster to create and easier to maintain. But there's even more to it than that.


The name of Interface Builder is actually a little misleading. It’s much more powerful than the name implies and it’s important to understand why.

Interface Builder does not generate code. It doesn’t create a forms file of any sort. What it does, is actually instantiate and configure the same objects that you use in your application to show your user interface. If you add a button to your application in Interface Builder, you’re actually creating an instance of UIButton or NSButton. When you configure it, you’re actually setting state on that button instance. Then, when the nib file gets saved, that button gets serialized into the nib file using NSCoding, exactly the way we persisted objects the archiving section of the persistence chapter in Beginning iPhone 3 Development. Basically, the nib loader is doing exactly what the code you would write to create and configure the interface object would do, down to the actual method calls used.

Why is this better than code generation or a form file? Well, in addition to letting you leverage extraordinarily well tested code to build your user interface, it also means that you are not limited to having just user interface elements in your nibs. You can put instances of any objects that conform to NSCoding, which is the protocol that allows objects to be serialized and de-serialized. Any object at all. In the iPhone Xcode project templates, this is how your application delegate and your root view controller get created.

There is a design philosophy at work here. It's simple and important. This design philosophy goes like this:

Any line of code you don't have to write, is a line of code you don't have to maintain and is a line of code that you can't introduce a bug into.
Simple, but elegant. And valuable.

If you’re writing tons of code to implement your user interface, that’s lots of code you have to write, maintain, and debug. The nib loading code is solid. It’s been around darn near 20 years and is used in literally thousands of production applications, including most of Apple’s applications. Apple very much "eats their own dogfood" when it comes to their development tools. If you look inside the bundles of an Apple application, the chances are very high that you will find some nib files in there.

I know some of you will still want to resist Interface Builder. Don’t. Seriously. You’re wasting your time. You are being inefficient if you are creating your user interface directly in code when there’s not a compelling reason to. There are times when the programmatic route is the right choice. There are times when it makes sense to programmatically create your user interface. In reality, though, those times are very few and very far between.

Yes, there is a learning curve, especially with debugging. But stick with it. It won't be long before you recognize the signs of a disconnected outlet or other IB-related problems and in the long run, the gains will more than justify the time investment.

 
Design by Wordpress Theme | Bloggerized by Free Blogger Templates | coupon codes