Thursday, October 28, 2010

Lifting the Skirt

MartianCraft has received a surge of requests for quotes and proposals in the several weeks. A disturbing trend that I've been noticing in some of these proposals is that more and more of the people who contact us are wanting us to sign NDAs before they'll lift their skirts even a little. Often, we can't get the most basic information about a project, not even things like ballpark budget, timeline, or type of application until we've signed an NDA, often a pro-forma NDA that was downloaded from the web.

The last thing any reputable iOS dev shop is interested in doing is stealing your idea. First of all, it would destroy our business if we did that. NDA or not, it would be unethical. This is what we do for a living. If we were to steal an idea and publish it as our own, word would get out and people wouldn't trust us. Our business would die even without ever being sued.

More than that, though: Ideas, with only rare exceptions, have little value without the ability to execute on the idea and execute on it well. I guarantee you that no matter how great you think your idea is, we have several of our own that we'd rather be spending our time on. But we don't even have time to work on our own cool side projects right now, never mind steal yours.

It's absolutely understandable, of course, to reserve certain strategically important details until after a contract is signed, but you have to give us enough information for us to decide whether we're a good fit for your project.

Every NDA or contract we sign costs us money, and not an inconsiderable amount of money. Every single one goes to our lawyer before we'll sign it, and most of them have to be modified and negotiated. It's a costly process. Even the simplest NDAs cost MartianCraft hundreds of dollars by the time we've signed it. We're not going to spend that if we don't have some notion that it's a good project for us and that we have the resources to do it well. We'd quite honestly go bankrupt if we were to forward every NDA request we got to our attorney.

If we know a little about your timeline and budget and a brief synopsis of the app you want to build, we're far more likely to submit a proposal. If you're not willing to give us even the most basic information, then we're going to politely decline your NDA and pass on the project unless you're a Fortune 500 company… maybe.

Here's the important thing for you to realize if you're looking for any mobile developer, but especially an iOS developer: there are nowhere near enough competent, experienced mobile developers right now to meet the demand. By now, all the large companies have realized that mobile is the strategic battleground for the next several years. As a result, experienced mobile developers rarely have to look for work. MartianCraft has existed for less than a year. In that time, the only advertising we've done is to put a banner ad here on my blog, and yet we already have had to turn down at least as much work as we've accepted. I say that not to brag, but to show what the current state of the market is. It's not unusual for us to receive a half-dozen requests for proposals in a single day when you combine requests to MartianCraft and those that come to us individually. When we don't submit a bid on one of those proposals, it's not out of hubris, but rather out of practical necessity.

We are far from alone in this. All of us have friends in other longer-established mobile dev shops, and it's the same story all around. There's a lot of work — a lot of interesting work — and simply no way to accept every interesting project that comes along.

If you insist on an NDA before you give any information at all, you are potentially limiting your pool to the developers who are desperate for work, and given just how much mobile dev work there is out there right now, I'm really not sure that you want to limit your talent pool to just the ones who are desperate for work.

Update on OpenGL ES 2.0

My editor at the Pragmatic Programmers has informed me that I will be able to post the chapters of my OpenGL ES blog once the cancellation is complete. I have nothing but great things to say about my experience with the folks there. Good people all around. If you get a chance to write for them, you'd be foolish to pass up the opportunity.

So, once my cancellation letter arrives, I will begin prepping chapters for posting. I still don't have much in the way of free, so I wouldn't expect more than a chapter a week. I have to scrub the content both for copy edits and for potential NDA violations and then convert from DocBook to HTML.

iOS Secret Meeting

There have been reports lately of Apple holding a secret conference for iOS developers. Now, let me just state up front so there's no misunderstanding: Other than the normal news outlets, I haven't heard any information about such a conference - I'm certainly not invited if there is such a thing going on. This post is just conjecture on my part.

But I'm not sure why this is news. Apple constantly has strategically important developers (and other partners, like wireless carriers) out to Cupertino to work on future product announcements and to be informed about future products. It certainly shouldn't be news to anyone that the people who get up on stage with Steve at keynotes and presentations (plus everybody involved behind the scenes) knew ahead of time that they would be doing so.

If you follow a lot of iOS developers, you'll pick up subtle hints about when some of them are on campus or on their way there. It might just be a "Wheels down SFO" tweet, a comment about the food at Caffe Macs (the cafeteria at 1 Infinite Loop which is quite excellent), or a dinner with certain Apple employees, but the signs are there if you know what to look for.

Unsurprisingly, Apple is just as careful about keynotes as it is with everything else. As a result there are constant "summits" going on in the weeks before any public announcement. Since Apple now spreads their product announcements around the calendar year, that means it's an almost constant ebb and flow of strategic partners.

The process to be involved with a keynote presentation is long, stressful, and involves many trips to Cupertino. I can't say anything more specific about the process without betraying confidences (I've never been directly involved myself), but rest assured that despite Apple's famous secrecy, if you're at all involved with the developer community, then there are likely people outside Apple whom you've socialized with who knew a fair bit about certain products before they were released. Even people who aren't directly involved with a keynote presentation have to, at times, find out information about products early, and in some cases even get access to pre-release hardware (though usually with strong precautions talem to keep photos or other info from leaking).

If this is a surprise to you, chalk that up to the fact that the third party developers who are involved understand and respect Apple's desire for secrecy and want to continue being involved with the process. Apple is not known for being forgiving to those who leak information of that nature.

So, is there something even larger than normal going on next week, perhaps a replacement for the Tech Talk World Tours of past years? I don't know. It's absolutely possible. But, what seems more likely to me is that Business Insider simply got a whiff of information about an ongoing process and interpreted it incorrectly. Apple is never idle, and we're less than a month away from 4.2 being publicly released. It's altogether possible (I'd say likely) that there will be hardware or other software announcements that will coincide with release of 4.2.

Frankly, I'd find it far more surprising if there wasn't a flurry of third-party developers going in and out of Cupertino right now and for the next few weeks. Whether it's a formal summit of any size, I don't know, but I have my doubts. The more people involved with something like that, the harder it is to keep it secret and the more likely a leak is. Right now everything I can find online leads back to the original Business Insider story. Despite requests for anonymous information, no new information seems to have come out.

My bets are on business-as-usual pre-announcement activity, not some secret conference. If it is a secret conference, the participants are likely only the most strategically important partners: people who have been involved with pre-release products previously.

OpenGL ES 2.0 Book

I've been getting a lot of questions lately about the status of my OpenGL ES 2.0 book for PragProg. What I've been telling people is: "it's about half done but I have no idea when I'll be able to finish it". To say I've been busy lately would be an understatement of epic proportions. As a part-owner of a business in its first year, being too busy is a great problem to have, but it does take its tolls in both subtle and not-so-subtle ways.

When you combine how busy I am with the fact that I've been completely unable to get even ballpark information about when Xcode 4 will go GM (the book is heavily based on Xcode 4), it means I simply cannot nail down a production schedule for the book. Even if I had time to finish the book right now, it can't be published until the Xcode 4 NDA drops. It also makes no sense to revise the book to a version of Xcode which is soon to become obsolete.

As a result, today, I made the difficult decision, along with my editor at Prags, to indefinitely shelve the OpenGL ES 2.0 book project. I would have liked to keep the project open and work on it whenever I have time, but that wouldn't have been fair to my publisher. They have to plan their production pipeline very carefully and a book with no set timeline throws a real monkey wrench into that process, which I really don't want to do. The door has been left open for me pick the book up in the future if and when I have time, but for now, it's coming off the production schedule to free up resources for other authors' books.

I have requested permission to post the existing seven chapters of the manuscript to my blog (tweaked so I'm not violating the Xcode 4 NDA, of course). From a contractual and legal point of view, I cannot just post what I've written without the the permission of my publisher. Prags has been nothing but fair, patient, and a pleasure to deal with and I want to make sure I'm just as fair to them and also comply fully with my contract.

However, if I can find a path to posting the chapters that's legal, ethical, and doesn't harm my relationship with Prags, I will do so.

Tuesday, October 19, 2010

Tile Cutter Updated

Today, I released a new version of Tile Cutter. This is just a bug-fix release; the changes have been pushed to GitHub.

OpenGL ES iOS

I've created a new public project on GitHub for classes, scripts, and projects related to OpenGL ES programming on the iPhone. I'll be slowly consolidating all of my OpenGL ES code snippets, utilities, and sample projects except for the particle generator (which has its own repository) into this location.

Right now, all it has is:
  • Blender export script for Objective-C for Blender 2.49a
  • Blender export script for Objective-C for Blender 2.5+
  • My old OpenGL ES Xcode project template for OpenGL ES 1.1
  • A fairly simple OpenGL ES 1.1 Xcode project
  • A fairly simple OpenGL ES 2.0 xcode project
  • A few OpenGL ES-related categories and classes
  • My old Wavefront OBJ file loader
I'm happy to accept back changes as well as additions.

Thursday, October 14, 2010

Outlets, Cocoa vs. Cocoa Touch

I almost always follow Apple's lead on Cocoa and Cocoa Touch conventions. I figure that by the time outside developers like me see something for the first time, Apple engineers have been living with that thing for many months, so they've likely got a much better idea than I do about the best way to use that new thing.

But, after spending time with their stuff, sometimes — not often, but sometimes — I disagree with what appears to be Apple's recommended "best practice" for doing something. I think I've come to the decision that the IBOutlet behavior in iOS is one of these areas.

If you look at Apple's documentation snippets and sample code, you find that they almost always retain IBOutlet properties, like:


#import <UIKit/UIKit.h>


@interface FooView : UIView
{

}

@synthesize (nonatomic, retain) IBOutlet UIButton button;
@synthesize (nonatomic, retain) IBOutlet UITextField textField;
@synthesize (nonatomic, retain) IBOutlet UIImageView imageView;
@end



There's a good reason for this. In iOS, the documentation explicitly states that you need to retain all outlets because the bundle loader for iOS autoreleases all objects created as a result of loading a nib.
Objects in the nib file are created with a retain count of 1 and then autoreleased. As it rebuilds the object hierarchy, however, UIKit reestablishes connections between the objects using the setValue:forKey: method, which uses the available setter method or retains the object by default if no setter method is available. If you define outlets for nib-file objects, you should always define a setter method (or declared property) for accessing that outlet. Setter methods for outlets should retain their values, and setter methods for outlets containing top-level objects must retain their values to prevent them from being deallocated. If you do not store the top-level objects in outlets, you must retain either the array returned by the loadNibNamed:owner:options: method or the objects inside the array to prevent those objects from being released prematurely.

This is different from Cocoa on the Mac, where it wasn't necessary to retain outlets and people rarely did. In fact, we didn't usually bother with accessor or mutator methods for outlets (it was just unnecessary extra typing in most cases), we just put the IBOutlet keyword in front of the instance variable and the nib loader was happy to attach our outlets like that, retaining the objects that needed retaining.

The behavior under Cocoa/Mac is not actually to retain everything in the nib, but rather, to retain any object that doesn't have a parent object to retain it. So, in other words, if an object in a nib will be retained by something else, like a superview, the nib loader doesn't bother to retain it again. But, if it doesn't, the bundle loader retains it so that it doesn't get deallocated.

This is a logical approach and, in fact, was necessary back in the pre-Objective-C 2.0 days because outlets back then were just iVars and there was no easy way for the controller class to retain objects that needed to be retained.

I have to wonder why they would change the fundamental behavior of a foundation object like NSBundle between Mac OS and iOS? NSBundle is not part of Cocoa or Cocoa Touch, it's part of Foundation, and the whole point of Foundation is to have common objects between the different operating systems.

I wrote a small project to test if the Bundle Loader really did behave differently, as documented, by using an instance of UIView in the nib with no superview. Sure enough, when I didn't retain the outlet, I either got an EXC_BAD_ACCESS or a different object altogether when I printed the outlet to NSLog(). The difference is real. The bundle loader on the Mac will retain outlets for you if they need to be retained, which allows you to continue using instance variables, or properties with the assign keyword. This means you don't have to release your outlets in dealloc and you don't have to mess around with anything like viewDidUnload on iOS.

The bundle loader on the iOS, on the other hand, does not retain anything for you, so if an object does not have a parent object to retain it, you have to retain it in your controller class or you will end up with an invalid outlet.

I really don't see the value in changing this behavior. I'm guessing the decision was made for the sake of memory efficiency in the early days of the iPhone. The idea being that you might load a nib with object instances that you aren't actually using, and with the old behavior, those would take up memory as long as the nib was loaded. That doesn't necessarily sound like a good idea on an embedded device with no virtual memory and 128 megs of RAM, which is what the original iPhone and iPhone 3G had.

Despite that, I think the cure here is worse than the disease. If you don't remember to release your outlets in viewDidUnload (which, if I remember right, we couldn't even do in the 2.0 version of the SDK), your outlets will continue to use up memory after the nib is unloaded, obviating any advantage of the lazy loading. Essentially, it's more fragile, because it depends on the programmer doing the right thing and there are few if any situations where a programmer would need to not do the right thing.

By virtue of the bundle loader not retaining outlets, it also requires more rote, boilerplate code to be written in every controller class in every iOS application, yet it runs just as much of a risk of unnecessary memory use, arguably a greater risk. In other words, the cure is no better than the disease.

iPhones are getting more robust and less memory constrained with every new device that comes out. I would argue that it's already time (or, at very least, soon will be time), to bring the behavior of the two bundle loaders together. If they are brought together, they should be brought together using the old Cocoa behavior not the new iOS behavior. When you think of the number of people coding for the iOS now, those extra required dealloc and viewDidUnload lines in every single controller class in every single iOS application are really adding up to a lot of engineering hours lost on boilerplate.

A few weeks ago, I started experimenting with using assign instead of retain for IBOutlets except in cases where the outlet's object didn't have a superview or another object retaining it. If an outlet's not a view or control, then I also use retain. In essence, I'm mimicking the old behavior of the nib in designing my controller classes.

This has led to a lot less typing and less code to maintain because 95% or more of the outlets I create are connected to objects retained by their superview during the entire existence of the controller class.

Now, I'm not necessarily saying you should do what I'm doing. It can be tricky, at times, remembering which objects need to be retained and they can be hard to debug if you get it wrong. Apple has made a recommendation with good reason and I don't think you should disregard that recommendation lightly. That being said, if you're comfortable enough with Objective-C memory management and the bundle loader to be able to distinguish when a nib object will be automatically retained by something else, you could save yourself a fair bit of typing over time.

I normally try to embrace changes Apple makes, but in this case, I just can't convince myself that this was a good change. The old nib behavior of retaining only things that need retaining has been in use for over 20 years, dating back to when desktop computers were less powerful than our iPhones are, and there doesn't appear to be any practical advantage to the change. On the other hand, we'd all benefit from going back to the old Mac OS bundle behavior because we'd have less make-work to do when setting up a controller class. There's also little danger in changing this behavior because code that follows Apple's current recommendations would continue to work correctly.