Application Development for the iPhone using Apple's official SDK.
Treadmill Desk Plans
I've been promising this for a while. I apologize for the delay, but it's been a hectic month and I wanted to write up instructions that were easy to follow. I also wanted to make sure my desk continued to be sturdy and usable before writing it up. Finally, I'm ready, and this post will detail how I built the treadmill desk I've been blogging and tweeting about for the last month.
I've been using this desk for a little over a month now. Since December 21st to be exact. Despite Christmas (and multiple Christmas parties), New Year's Eve, socializing and drinking after the New York City Tech Talks, and a family vacation, I've still managed to lose 23 pounds, and I've done it just by going to work. To say I'm happy about how this is working out would be an understatement. I still have quite a bit more weight to lose, but it all seems very doable now.
Before you decide to build a desk like mine, there are a few things to consider. First, the reason I built one rather than buying one is because my rig is much heavier than the typical one. I have a Mac Pro with two 27" ACD monitors and a large number of peripherals. If you work with a lighter setup, like a laptop plus monitor, or an iMac, then you might want to consider buying a pre-made treadmill desk. Building the desk won't save you a significant amount of money and it will take a fair bit of your time. Plus, it requires you to already have a number of tools. Plan to spend at least a full day building this. For me, it was closer to three, but that's because I had to experiment a lot to come up with a design that was sturdy enough to make me feel comfortable putting 200+ pounds of expensive kit on it.
A company called LifeSpan makes a treadmill desk that looks sturdy and may be a better option for many of you. It's not cheap, but when you factor in your time, it's probably not much more expensive than buying a treadmill and building a desk according to these plans. I would have bought one if I had been confident I could buy one that would work with my setup.
Also, before committing to a full treadmill desk, you can setup a makeshift desk for considerably less money in order to try it out and make sure it's going to work for you. I didn't have any problem adjusting to walking while working, but building a treadmill desk is a significant investment of time and money, so you might want to make sure it's going to work for you before investing.
Finally, make sure you go slow when you start and that you get good shoes that fit you well. Here's another tip: Definitely consider getting some underwear designed for exercising. Though this isn't really exercise, it is a lot of movement over the course of the day and something like Under Armour instead of regular cotton underwear can save you some definite pain and suffering.
When I first started, I was averaging about 1.3 miles per hour and was spending between three and four hours a day on the treadmill desk, then working from my laptop the rest of the day. I could have handled walking faster, but I kept my speed slow so I could adjust to typing and mousing while walking. The point of the treadmill desk isn't to work up a sweat (though you may if your office is warm), but to be in constant motion. Long and slow is better than fast and short.
I find I tend to increase my speed and/or time each Monday. After taking a day or two of rest, I come back able to walk longer and/or faster. After 5 weeks, I'm now averaging about 2.2 miles per hour for about six hours per day, which equates to about 1500 calories burned per work day. I don't think I'll increase my speed any more, as my ability to mouse precisely seems to degrade when I hit 2.3 or 2.4 miles per hours (I might be able to go a bit higher using the trackpad, though, which seems less impacted). I do plan to keep increasing my time on the treadmill until I'm spending every working hour on it.
So, if you're still with me and still intent on building your own heavy-duty treadmill desk, let's start.
Note that this desk is designed to be used with this treadmill, so if you're planning to use a different model, some adjustments might be needed. This treadmill is designed just for walking, is shorter than most treadmills, and has the speed and other controls on the handle in addition to the console, which is important because the console will be hard to reach while using the desk unless you disassemble it.
Last thing before we begin: I'm providing the information on what I did. It's your responsibility to make sure the desk you build is sturdy enough for your gear and to make sure you're taking necessary safety precautions while building it. While you don't need to be an expert carpenter to build this desk (I'm certainly not), you do need to know how to use a variety of different tools and to use them safely.
Tools List
- Table saw or circular saw
- Saber saw, or jigsaw
- Drill with ¼" bit and 1" bit
- Phillips head screw bit for drill or electric or manual Phillips head screwdriver
- Swage tool for ⅛" wire rope crimping sleeves, or alternatively a hammer and anvil or heavy-duty pliers (but a swage tool like this one will make your life easier)
- Heavy duty cutters capable of cutting ⅛" wire rope
- Palm router, router (the power tool, not the networking device), or router table with ½" or ¾" rounding bit (optional)
- Respirator (for sanding and for applying paint, lacquer, and/or polyurethane)
- Safety goggles or glasses (no, really)
- Rotary sander, mouse sander, or lots of elbow grease
- Sawhorse or cinder blocks to put wood on while cutting, sanding, and painting it
- Level
- Ruler or measuring tape
- T or L Square
Parts List
- 8 - equal lengths of 1¼" diameter galvanized steel threaded pipe (20"-24" see pre-build instructions to calculate length)
- 2 - equal lengths of 1¼" diameter galvanized steel threaded pipe (20")
- 8 - 1¼" diameter galvanized steel flanges
- 4 - 1¼" diameter galvanized steel T-couplings
- 4 - 5" long threaded pipe nipples (1" diameter galvanized steel)
- 8 - 1" diameter galvanized steel flanges
- 1 - 10' length (or longer) ⅛" wire rope
- 48 - ¼" (#20) wood screws (½" long)
- 6 - crimping sleeves for ⅛" wire rope (actually, get a few extra, they're cheap)
- 3 - ¼" eye-eye turnbuckles (not eye-hook or hook-hook)
- 2 - 1¼" thick wood boards, 24" x 48" (if you are getting them custom cut instead of using stock pieces, get one 24" x 48" and the other 18" x 38" instead)
- Wood stain or paint, shellack, polyurethane - depending on how you want to treat the wood. I went with black gloss paint followed by a coat of shellack, followed by a coat of polyurethane, (optional - even just plain wood will work and I won't be giving detailed instructions on how to paint or polyurethane)
Pre-Build Instructions
Determine the pipe lengths for the 8 equal length threaded pipes. Threaded pipe comes in standard pipe lengths (24" is one of the standards), but most hardware chains (in the US at least) along with most plumbing supply shops will cut pipes to length and thread them. It is important that you get your desk the right height, otherwise it will be uncomfortable. I'm 6'3, and I used 24" lengths, which is comfortable for me, but if it were any higher, it would not be. If I were building it again, I'd probably use 23½" lengths. Unfortunately, because of the treadmill's arms, if you go less than 20" on these supports, you may have problems. If you're short enough that this will be a problem, you may need to look at a different treadmill model. You can accommodate a slightly shorter desk by moving the desk back from the treadmill console a bit, but if you move it back too far, you'll run out of room to walk.Keep in mind, as you're calculating the lengths, that reducing the pipe length by one inch will reduce the desk height by two inches. If you're unsure about what lengths to use, your best bet is to stand on your treadmill, put your arms out as if you were typing, and measure the distance from the ground (and make sure that position is above the arms of the treadmill).
The completed desk height will be approximately equal to (2 * pipe length) + 6". The flanges, desk surface, and T-coupling contribute to the height and amount to approximately 6" in height.
Threaded pipes don't all screw together to exactly the same point, so the height will vary a small amount, and you may need to adjust the height of some legs by adjusting the flange tightness or using shims to get the desk exactly level.
Build Instructions
- Take one of the two wood boards to serve as the desk surface (if using custom cut pieces, this will be the larger piece).
- Using the 1" drill bit, drill two holes Using the diagram at the end of this blog post as a guide. These holes will be used for attaching guy wires.
- Again, using the diagram at the end of the post as a guide, cut out a 24" x 6" notch at the back (the same side of the desk that you cut the holes for the guy wire) using a jigsaw or sabersaw. This notch will be for the treadmill console panel and to make sure you have enough tread in front of the desk to walk comfortably.
- (Optional) Using a router with a ½" or ¾" self-guided rounding bit, bullnose the desk edges to get rid of the sharp edges and corners. This is optional, but it makes the desk look nicer and decreases your chances of a deep forehead gash should you ever stumble while walking. You can, of course, use more decorative edge treatments if you are so inclined, but a simple bullnose looks nice, is less deadly, and won't accumulate dust, crumbs and other detritus of your workday the way some of the more ornate edge treatments will.
- Sand the surface and edges of the desk very, very well, starting with a medium grit and working up to a finishing grit. When done, you should be able to run your palm over the entire surface area without feeling any grit or imperfections or getting slivers . A circular or mouse sander will make your life much easier.
- Paint or stain the surface to your tastes, making sure to let it dry completely. If you choose to shellack and/or polyurethane, you'll want to let it dry for 48 hours after the final coat before assembling your desk (even if the instructions say you need less time - trust me on this one).
- Take the other piece of wood.
- If you didn't get the pieces custom cut, cut the second piece down to 18" x 38". This will be the riser for your monitors.
- Repeat sub-steps 3, 4, and 5 that you did on the larger piece of wood on this piece of wood (in other words, do the same edge treatment, if any, then sand and paint or stain just like you did with the other piece)
- Assemble the legs. The following instructions need to be done twice, one for each pair of legs. From here on, you'll want to assemble the desk where you want it to go. Once assembled, it will be very, very heavy and difficult to move. Please note: pipe threads, especially if you had the pipes custom cut, will potentially be very sharp. Be careful. I learned this the hard way; learn from my mistake and save yourself some pain and blood loss.
- Take two of the eight equal length pipes and screw them into opposite sides of a T-coupling. When done, you should have one long, straight piece with a perpendicular opening for another pipe to be attached. Make sure you have tightened them as tightly as you can.
- Screw a flange onto each end of the connected pipes. Screw until they're tight, but don't go too tight - you can unscrew the flanges to make minor height adjustments for leveling.
- Repeat the previous two step to create a second identical piece
- Take one of the two 20" lengths of pipe and screw it into the remaining socket on the T-coupling of one of the pieces you just constructed. You should now have a very big, very heavy "T". Set this aside for a moment.
- Attach the other assembled piece to the other end of the 20" pipe to create an even bigger, even heavier "H". Make sure all pipes are tightly screwed in and aligned
- You've just completed the supports for one half of the desk
- Once the paint, stain, or other treatment on the wood is fully dry (48 hours… really!), take the larger piece of wood and put it top down on the floor so the bottom is facing up. You're going to screw in both leg pairs (the Hs you built out of pipe) into the wood using the flanges and wood scres. You want them just far enough apart for the treadmill to fit between them. Measure the treadmill width to determine the distance. I used the actual treadmill width plus one inch. Once positioned, secure the legs tightly to the bottom of the desk surface using 16 wood screws.
- Attach the guy wires
- Cut two lengths of wire rope. Take one length, loop it around one rear leg just below the T-coupling (the rear leg is the one on the same side of the wood as the notch and holes) and secure it with a crimping sleeve. Make sure you really crimp hard to make sure the wire rope can't slip out when you tighten the turnbuckles later.
- Repeat the last step with the other piece of wire rope on the other rear leg.
- Take one turnbuckle and unscrew it as far as you can without it coming apart.
- Loop one of the two wire ropes you connected to the legs through the turnbuckle and crimp with a crimping sleeve.
- Repeat with the other wire, attaching it to the other end of the turnbuckle and making it as snug as you can. Now, you should have a wire that stretches from one rear leg to the other, but is probably not too tight and may even sag a little.
- Tighten the turnbuckle until just barely snug. DO NOT OVERTIGHTEN. This guy wire provides inward lateral support. Until we have balanced it with outward pulling guy wires, tightening can actually harm the stability of the desk and rip out the wood screws securing the leg. Err on the side of under-tightening at this stage.
- Repeat the steps above, this time running a wire from the cross support near the rear leg to the hole in the corner of the desk, again, tightening the turnbuckle until just snug.
- Repeat the previous step for the other rear leg.
- You now have wires pulling both inward and outward, so you can alternate tightening turnbuckles until the wires are good and tight. Don't tighten any turnbuckle more than two full turns without turning the others. Stop when the wires are taught. The inward guy is much stronger than the outward ones because it pulls straight, so once you've got the guys taut, you probably want to match a single turn of the turnbuckle on the inward guy turnbuckle with a turn and a half of the outward.
- It's time to stand your desk up. You might want help from a second person while doing this, as the desk will be very heavy, and you don't want to put too much pressure on the legs while lifting. Once the desk is stood up, it's time to check to make sure the desk is sturdy enough for your kit. If all went well, there should be very little lateral play and none forward and back. There will be a small amount of side-to-side play, but it shouldn't wobble, it should move no more than maybe a half inch and should come immediately back to its original position. It should feel sturdy. If not, play with the turnbuckles, or consider adding more guys. An additional set of guys that run from the bottom of the rear legs should give additional stability, though I didn't need to on mine. Make sure to add inward pulling guys only to the rear legs. Adding them to the front legs will interfere with your ability to walk on the treadmill.
- Take the four pipe nipples and the eight 1" flanges. Attach a flange to each end of each of the pipe nipples. These will form the supports for the monitor stand.
- Position the four supports on the desk. There are two approaches you can take here. The obvious one is to center the supports and monitor riser. If you're not using a Mac Pro, this is probably the best bet. If, however, your setup contains a Mac Pro (or other large tower computers), you're probably going to want to offset the riser to one side or the other. The Mac Pro is 9" wide, so you need at least that much space from one end of the riser to the edge of the desk. I have my Mac Pro on the left, so the riser is off-center to the right leaving a little more than 9" on the right side of the desk. Place the riser on top of the supports and adjust until the configuration works for you, then use the remaining wood screws to screw the riser supports into the desk and the riser. You may need a short screwdriver or a screwdriver with a 90° bend to tighten all of the screws, as the 5" pipes don't leave a lot of room between the two boards.
Guess What? That's it. Position the treadmill if you haven't already, and you're ready to go.
Here's the desk diagram showing the placement of the console notch and the two holes for guy wires.

Here's a better view of the "H" legs and guy wires. Please excuse the mess. I can't currently get behind the treadmill desk to clean it, and haven't had the gumption to relocate it yet.
Here's a picture of the desk and riser. Notice how my riser is off-center to make room for the Mac Pro:
http://iphonedevelopment.blogspot.com
Posted on 28 January 2012 | 12:56 pm
Wow.
Just… wow. Those are crazy numbers any way you cut it.
http://iphonedevelopment.blogspot.com
Posted on 24 January 2012 | 2:02 pm
How I Learned to Stop Worrying and Love the iBooks Author EULA
I've been debating whether to post about the iBooks Author EULA or not. In general, I've been trying to avoid hotly debated and controversial subjects here for the simple fact that those discussions tend to eat up a lot of time and often aren't very productive. My opinion on iBooks Author and iBooks 2 is fairly close to some other authors I know. Because this is something that's near and dear to my heart, however, I figure it's worth a few words. And with me, a few words is usually more than a few.
There's been a lot of foofooraw since the iBooks 2 announcement last week. There's been all sorts of stories, tweets, and blog posts about how Apple is going to "steal your work" if you use iBooks Author. There's also been the all-too-familiar refrains of just how evil Apple is. It all seems vaguely familiar. Almost like… almost like we've been here before, what with all the people gnashing their teeth, rending their clothes, and complaining to the heavens about how evil Apple is because of the developer agreement app store guidelines iBooks 2 EULA.
There's also been a lot of complaints about the fact that Apple is using a proprietary format rather than using and extending ePub 3.
None of this bothers me terribly. Oh, it's not that there aren't things I would want different if I were King of the World, but the reality is that deciding whether to use iBooks Author is just another business decision for me. Emotional outcries and hyperbole are all well and good, but they don't change the parameters of the decision. Business decisions inherently involve risk, and the risk here is at a level that I'm perfectly comfortable with.
Before I explain why, though, I want to put up front that I'm not a lawyer. Well, that's not technically true, but I'm not a practicing lawyer and I'm not YOUR lawyer, so don't take anything I say as legal advice. I'm just explaining why I'm not concerned. If you have concerns, you should take those concerns to your lawyer before making up your mind.
The EULA
Make no mistake, the iBooks 2 EULA is poorly written and vague. The mere fact that people are up in arms is testament to that fact. And if the ambiguity that is there bothers you, don't use it. There are plenty of tools for creating eBooks, so if you think the risk of Apple "stealing" your work is too high, using another tool solves the problem.There are several reasons why I'm perfectly comfortable with the risk involved. In no particular order, those reasons are:
- It's simply not in Apple's long-term interest to take ownership of authors' books and Apple can almost always be relied upon to do what's in their own long-term best interest. Getting 30% of every iBook sale means they are motivated to keep authors happy. More than that, though, they need authors to want to write for this new platform in order to establish it as the dominant interactive next-generation eBook platform. Stealing books won't get them to that goal. Suing authors who publish non-interactive versions of their content for other platforms like the Kindle or ePub won't either.
- Although the wording is certainly vague enough that you could argue more than one interpretation, the capitalization of "Work" in the EULA (meaning it has a specific contractual meaning) combined with the verbiage, "Work you create with this software" implies that the intent is to restrict only the application-specific output. In other words, the most likely intent as I read it is to cover the proprietary file format used for the new features not supported by other existing eBook platforms.
- Even if that weren't the intent, from a purely evidentiary point of view, the other file formats that iBooks Author exports to are open, standard formats and it would be difficult for Apple to prove a particular non-interactive work was "generated" with iBooks Author even if they really did want to try and "steal our books". A PDF generated from iBooks Author would be nearly impossible to distinguish from one generated using Pages by simply copying and pasting the content from iBooks Author .
- The EULA contains the following phrase: Title and intellectual property rights in and to any content displayed by or accessed through the Apple Software belongs to the respective content owner. Basically, it explicitly states that the ownership of any content you create outside of the app and import into it is completely unaffected by any "book stealing" clause, even if such a thing existed. This seems to counter the notion that Apple is trying steal our intellectual property in the first place because unless the words and images were created directly in iBooks (as opposed to being imported from Pages, Word, Photoshop, etc.), Apple would have no claim to the content anyway. Their claim would be limited to the way the content is formatted. Again, from an evidentiary standpoint, it would be incredibly hard for Apple to prove you created the content in iBooks.
- The deal we're getting with iBooks Author isn't all that different from the deal we get when using Xcode as iOS developers, and the language of the agreements aren't all that different from each other either, and that's worked out pretty well so far.
- And last, but not least, the kicker: Let's say, for giggles, that "book stealing" was Apple's intent, and such an intent was found to be both legal and the actual intent of the contract, and Apple decided to exercise those rights to steal my books. You know what? Even with all that, it's still a hell of a lot better deal than I've ever gotten from a traditional publisher. Apple is offering 70% of the sale price to me. The most favorable contract I've ever gotten from a publisher starts at 12% of the net price the publisher gets from the distributor, wholesaler, or retailer (which is half or less of the retail price). That percentage does slowly escalate up to 20% if I sell a ton of books, but if I publish a new edition of an existing book, the escalators go back down to 12% and I have to start all over. To put this in more concrete terms, if I were to sell a book in the iBooks Store for $9.99, I would get $6.99 per book sold, which is about four times what I get when one of my current $39.99 books sells, and I'd get that money months sooner. Oh, and guess what? I don't own those books published through a traditional publisher, either. My publisher can even have someone else update the book and can continue to use my name to promote it, even if I don't like the revisions or think the update sucks.
ePub 3 vs. iBooks 2
Many people have suggested that Apple should have used the existing ePub 3 standard and worked with the standards body to extend it in whatever ways Apple needed it extended. Instead, they decided to create a proprietary file format using the older ePub 2 specification as a starting point. It is important to note, however, that Apple is not advertising this new format as being ePub; we only know it's based on ePub 2 because people have reverse engineered the generated .ibooks files.
Now, I'll be honest. In a perfect world, I'd prefer to see Apple using an open standard here. But, there isn't an existing open standard that does what Apple wanted to do, and working with a standards body to revise existing standards to meet their needs for a yet-to-be-released piece of software would have tipped their hand about the software they were developing. People would have known exactly what Apple was working on from the things they were requesting of the standards body, which would have given competitors an advantage and could have hurt Apple's negotiations with publishers. Apple's culture is steeped in secrecy, and many would argue that this secrecy has been a contributing factor to their repeated successes over the last decade. Anybody who follows the company and understands the way they work knows exactly why they made the choice that they did here. Was it the best choice for Apple? Only time will tell, but there are obvious reasons why they would think it might be.
It's also important to note that iBooks Author is completely and totally free. But really, nothing is free. TANSTAAFL. Developing both a platform to do what iBooks 2 can do and developing a tool to create content for that platform was not a trivial task and Apple almost certainly devoted a lot of resources to getting it done and to getting existing publishers on board. Apple doesn't write software to be nice, they write software to make money. In this case, they're not making money directly, but make no mistake, it was written to make Apple money. The fact that they are not letting people use this free product to compete with them, or to create works for competing platforms should surprise no one. We, as users, authors, and publishers might desire such a tool and might have all sorts of reasons why such a tool would be an awesome thing for us. But so what? I'd like a pink unicorn that farts money. That doesn't mean I should expect somebody else to find one and give it to me for free.
Embrace, Extend, Extinguish
Lastly, several people on Twitter have pointed out that Apple's move here seems frighteningly similar to what Microsoft did throughout the nineties with their infamous "embrace, extend, extinguish" campaign. There's definitely some uncomfortable similarities, but I'm not quite ready to put this in the same camp… yet.
First, iBooks is not the dominant eBook platform, so any suggestion of a monopoly would be silly. Amazon sells far more Kindle books than Apple sells iBooks, and there are other eBook platforms, including Barnes & Noble's Nook, Kobo, and Sony's eReader to name just a few of many. The very idea of embrace, extend, extinguish requires monopoly-like control of a market to be effective, which Apple doesn't remotely have here (yet). There's also been no evidence (yet) of an attempt to "extinguish" the open ePub standard, or to brand the proprietary extended version as the standard. iBooks still supports ePub, and until Apple moves to change that, we're missing the most important and deadly of the three Es, without which there's really no harm, no foul.
The Bottom Line
To quote the narrator in Peter Pan, "all of this has happened before, and it will all happen again." Many developers railed against the "unfair" restrictions of the iOS developer agreement, the inability to sell apps outside the App Store, and the review process. I'm sure there will be similar teeth-gnashing the next time Apple creates a new market or platform, or revises any of the agreements related to any of the existing ones.And certainly, there have been bumps in the road, some of which are still around. But overall, iOS has proved to be a great platform for developers to be on. The number of iOS devices in the world now numbers in the hundreds of millions, and many of the owners of those devices have shown a willingness to pay for content, including apps, movies, and books. It's not the gold rush the mass media thought it was four years ago, but it has been fertile grounds providing a great many people with a living, including me.
It's not a perfect place, but personally, there's no other place I'd rather be. The fact that I can now do both of the things I do professionally (write apps and write books) on those same fertile grounds, excites me. The fact that I can do things while writing my books that simply weren't possible before excites me even more.
Absolutely, things could change in the future, but I'll worry about the future in the future if I need to. For now, I'm happy here and thrilled about the possibilities that iBooks 2 and iBooks Author represent.
http://iphonedevelopment.blogspot.com
Posted on 23 January 2012 | 8:14 pm
Blog Files
As my inbox can well attest this morning, the web server that hosted most of my blog files is gone. I moved all the blog files over to Github, but forgot to post about the new repository.
Unfortunately, I just don't have time to go back and update all the old links, but every bit of code that I've posted that's now missing, can be found at GitHub.
Old code repository at GitHub.
Sorry for the inconvenience.
http://iphonedevelopment.blogspot.com
Posted on 9 January 2012 | 5:56 am
Speaking at MDevCon
I'm proud to publicly announce my first speaking opportunity of 2012. I'll be speaking at MDevCon in Amsterdam this year on March 10th. This will be my first trip to Amsterdam and I'm incredibly excited to have the opportunity. I'm so excited, actually, that I'll be staying in the city for several days after the conference to hang out in Appsterdam and visit. When I know exactly which days I'll be in the city, I'll let you know.
I have one other conference that I've already agreed to speak at this year, but that one hasn't been publicly announced yet, so I can't spill the beans quite yet, but I'm equally excited about that one.
http://iphonedevelopment.blogspot.com
Posted on 30 December 2011 | 7:41 am
Treadmill Desk Update
I'm coming up on the end of my second week using my treadmill desk, albeit two relatively quiet work weeks thanks to the holidays. I haven't put together the plans yet for those who might be interested in building a similar one, but the desk does seem to be holding up well. It's still very sturdy and has been working great for me.
After a really great first day where I put in over nine miles, my daily averages have backed off a bit to more in the 6-7 mile range and I'm averaging about 800 calories a day burned according to the treadmill. It seems that 1.6 MPH is my sweet spot for being able to type and mouse, though I sometimes go a little slower if I'm tired. I also usually start the morning at about 1.3 MPH, but after about 15 minutes, I'm usually up to 1.6.
I'm not finding it difficult to work for the most part. In fact, often I feel more alert and able to deal with complex problems. However, late in the day, I often feel just the opposite. I start to get fatigued, and when I do, then I often find that a difficult problem requires me to go over to my sitting desk or else needs to be pushed off until the next morning when I'm fresh. I suspect that this problem will go away as I continue to get used to it and am able to walk longer.
I currently spend about 4 hours walking, another 1-2 standing at my new desk, and the rest of my workday right now is at my old sitting desk. My goal is to get up to at least 8 hours of walking, but I'm really happy with this so far. It's not hard to do. There's no motivation for me to find. It's just part of my routine. When I go to my office, I start the treadmill. Easy-peazy.
I'm walking slow enough that I'm not experiencing much in the way of muscle soreness. A tiny bit in my calf last week, but none this week. There are some other problems that go along with the treadmill desk, however. First and foremost, my feet start to hurt something fierce by the end of the day. This week was better than last, and I suspect in a few weeks it will be a non-issue. A lot of it, admittedly, was poor shoe choice. More on that later.
Another problem with spending this amount of time moving is the potential for chafing and rashes. It goes away relatively quickly if you're smart enough to wear appropriate clothing, which I wasn't at first. If you experience chafing, here's two words to remember: coconut oil. Yep, the kind you buy for cooking. It's a solid at room temperature, but will turn into liquid from the heat of your hands. It's magic for irritated skin and it's also a lubricant. It's better than any lotion or salve I've ever tried.
I close my office door and open the window while I'm working, even though it's winter and I wear shorts and a t-shirt while working. Even at that, I'm a little warm, but I'm a warm person in general, always have been. I haven't broken out my winter jacket yet this year, so your experience might be different. Nobody I've talked to has mentioned being this warm, so it might just be me.
This one's important. Get some good walking shoes. Don't wear your existing sneakers or shoes, or worse, don't be stupid and go barefoot or wear sandals, crocs or whatever shoes happen to be closest to you. Good shoes, designed for walking, fitted by somebody who knows WTF they are doing. Four or more hours of walking is a lot of steps you're taking each day. Your feet will thank you.
So, the big question people probably want to know is: Have I lost weight?
It's really too early to tell. The scale says I've lost between two and four pounds, but honestly, my weight can fluctuate more than that just from water weight over the course of a single day. I might have lost nothing, or I might have lost more than that. I need more data points before I can form any conclusions. But, I suspect I have lost some. Even with a holiday party last weekend, I've been eating less than normal. I'm not sure if it's psychological or physiological, but I'm hungry less, and when I do eat, I'm tending to eat less and to eat healthier. I also haven't been tempted by my personal demon, the midnight snack. Well, more like the 2:30am-up-late-coding snack. Part of that may simply be that I'm too tired to work until 2:30am these days, though.
Overall, I'm declaring the experiment a success already. I'm able to work just as well walking as I am sitting except when I get fatigued, I'm burning calories while I work, and am just generally feeling better than I have in a long time.
http://iphonedevelopment.blogspot.com
Posted on 29 December 2011 | 11:48 am
Brilliantly Simple Idea: the Treadmill Desk
Software development is not the easiest vocation for getting or staying in shape. For that matter, being part-owner of a relatively young business isn't either.
I've been steadily putting on weight and getting in worse shape since before the dot com boom. Since we started MartianCraft, I've had very few days off, and my average work day has been probably twelve hours, possibly longer. Every time I try and get into a routine of exercising, something happens: a client emergency, a deadline, a build, a new prospective client, a minor family emergency. When there's not enough hours in the day (and there never are), the exercise was always the first thing to get cut.
Recently, I came across this brilliantly simple idea from a Mayo Clinic cardiologist. It's called the Treadmill Desk. Essentially, you replace your chair with a treadmill, and instead of trying to get a good strenuous calorie-burning bout of exercise in a few times a week, you just walk while you're working. You don't walk fast; in fact, you go quite slow. They typically recommend that you walk between one and two miles per hour, which is about half of most people's normal walking speed. This speed allows you to function fairly normally. After just a few minutes, you can type and mouse normally. If it gets hard to type, you back off on the speed a little. It's not a race. It's not even exercise in the traditional sense.
I'm typing this blog post while walking on a treadmill.
The goal with this walking is not to break a sweat, but rather to just be in constant motion. You will want your office a touch cooler than normal, though, as even slow walking does raise your body temperature. Despite the low-key nature of the movement, a typical person burns an additional 100 - 130 calories per hour they're at their desk. For a typical person working an eight hour day, that's between 800 and 1040 calories per day. If you work longer hours or weigh more than the average person, it's even more calories. Now, think about that. You have to burn approximately 3500 calories to lose a pound of weight, so assuming you don't increase your caloric intake, that's about a pound every three to four days of work, or two pounds a week. For someone working a forty hour week, that's about five pounds a month, or sixty pounds a year without additional exercise or dieting. There's a lot of health benefits that go along with losing extra weight, also. Lower blood pressure, lower cholesterol, lower incidence of several types of cancer.
If you work more than forty hours a week, the benefits can be even greater, assuming you don't eat more to make up for the extra calories you burn.
I've talked to a number of people who are using treadmill desks, and the feedback was universally positive. Everybody lost weight – several of them a considerable amount – and all were in better health than when they started. And almost everyone said the following word-for-word phrase to me: "I would never go back to a normal desk".
After about the third person gave me the same basic story, I was sold. Sign me up! I can do this.
But there was a problem.
There are lots of plans for treadmill desks around the Internet and you can actually buy treadmill desks now. But, here's the thing: My primary machine is a Mac Pro with two 27" ACD monitors along with a crap-ton of accessories. I couldn't find any desk for under $5,000 that looked sturdy enough to safely and securely hold the weight of all my gear, and all the plans I found for building one seemed to assume the use of a laptop or small computer with small monitor.
Because of that big sheet of glass, Apple's monitors are heavy. Because of that big aluminum case, the Mac Pro is also very heavy. My computer and monitors alone weigh well over a hundred pounds, and I wasn't about to trust that much weight worth that much money to something that looked flimsy or was designed to hold a laptop.
I experimented for a week using a makeshift treadmill desk with my MacBook Air, and I found the walking and working quite easy to do, but also found myself constantly pining to move back to my desk to use my more powerful machine and bigger monitors. I usually abandoned the treadmill after about two hours when I'd start getting into more hardcore coding, not because of the treadmill, but because of the computer.
But, that week was enough to convince me that this was a good way to reverse the slow but persistent upward trend in my weight that's marked the last several years of my life. Unfortunately, it also convinced me that I could only make it work if I could find a way to use my computer while walking.
So, I decided to build my own desk. Building a sturdy desk this tall (over four feet tall in my case, since I'm 6'3" and will be standing on a treadmill desk that's about 6" high) turned out to be an interesting, but not-entirely-trivial engineering exercise. It took a couple of re-designs and a lot of swearing, but my desk is now done and I've been happily using it for a couple of days now.
Here's my rig on my desk (excuse the messy office):
After I've been using it for longer and am convinced the design is good, I'll share how I made the desk for anyone who might wish to build one for themselves.
So far, so good, though. The desk seems to be solid, has no perceptible wobble, and the monitors and computer don't seem to be putting any noticeable strain on it. Yesterday, I walked nearly nine miles at an average of 1.6 mile per hour and had a productive work day. Today's about half over and I've burned a little over 600 calories while fixing two pretty gnarly bugs in client apps. These two days have been enough to convince me that this is going to work.
By having my good computer on the treadmill desk and my MacBook Air at my regular desk, there's a built-in incentive for me to walk, or at least stand, rather than sit at my desk. I'm simply more productive when I have more screen real estate and a more powerful computer.
In a week or so, I'll put together a parts list and basic instructions, but the design is pretty basic. 1¼" galvanized pipe makes up the main frame of the desk with ⅛" wire rope and turnbuckles as guy wires to provide additional lateral stability.
This is the treadmill I use:

It's designed only for walking, will hold up to 400 pounds, and it's shorter than most treadmills, so it takes up less room. It's not cheap, but it's fairly reasonable for a treadmill at $400, and it can fold up out of the way if you need to. I've been very happy with it so far. While it's not whisper quiet, it's nowhere near as loud as most treadmills I've used, and it has a full set of controls on the handle where you can reach them easily while using it as part of a treadmill desk, which is much nicer than having to awkwardly reach over the desk to the treadmill's console.
The desk plans (when I post them them) are intended to work with this treadmill, you will probably need to make minor adjustments to use it with other models, as well as account for any height difference.
http://iphonedevelopment.blogspot.com
Posted on 20 December 2011 | 10:52 am
Comments Gone
I regret to inform you that I've had to completely disable comments on the blog. I had to switch to moderation a while back since the spam detectors were failing to catch anything meaningful. Unfortunately, the rate of spam comments has been accelerating recently to the point where I simply don't have the time to search for the few actual and valid comments in the proverbial haystack of spam.
I wish I didn't have to do this. I like comments. I like hearing other peoples' takes on things and love it when somebody catches a mistake or proposes a better solution. But, comment moderation has been sucking away what little time I have for the block lately.
Maybe at some point I'll have the time to transition to software that can handle spam comments better, but I don't right now.
Sorry it had to be this way. It sucks that there are people in the world who do this shit and ruin things for everyone else.
http://iphonedevelopment.blogspot.com
Posted on 14 November 2011 | 7:30 am
Flash is Dead. No, Really this Time
It appears that Adobe is going to cease development of mobile Flash.
I'm not ordinarily one to gloat or dwell on I-told-you-sos, but I'm going to make an exception in this one instance. I took an awful lot of heat for those blog rants backin 2009 for saying things like
I hate to break it to you, but Flash, as it currently exists, is dead. Oh, it's not going to die quickly, it's going to die a slow painful death precisely because there has been such a large investment of time and money into using it by so many large corporations like Disney. Flash's roots run way too deep for it to disappear quickly.
Here's the thing, though: Flash is a product of a different generation of computing. It's a product of a world where 90% of the people used one platform, and the bulk of the remaining used another. There was Windows, and there was the Mac.
[…]
And now, the world is changing. People are increasingly browsing the web from mobile devices, and unlike the computer world of a decade ago, the mobile computing landscape is not anything like a monoculture or monopoly. There are several viable mobile platforms all competing in that space. We have the iPhone, Blackberry, Palm Pre, Windows Mobile, Android, Symbian and probably others that have slipped my mind. All of these are operating systems currently shipping on phones and all come with browsers. None of them, except a solitary model of Android phone, has Flash.
But before I get too smug, you know what? I missed a huge factor in the demise of Flash. I assumed the performance issues they were having back then were simply technical hurdles that would be overcome by Adobe's engineers before long. In the end, the lack of a monoculture was certainly a significant factor in the demise of mobile Flash, but the real nail in the coffin was that Adobe never even got mobile Flash working demonstrably well on a single model on a single platform, let alone working well on the "billions of mobile phones" they were shooting for with the Flash Consortium. I completely overestimated Adobe's ability to deliver, technically.
But all is not lost for Flash developers. Adobe has stated that they are going to "refocus" their efforts on allowing Flash to create HTML5 compliant web apps. What a brilliant idea!
If I may… one last quote from my much-reviled Flash rants:
But, that doesn't mean there's no hope. There are many ways that Adobe could save Flash/Flex for the mobile world. One way would be to create something like Google's GWT - an environment where some or all of the code gets translated into HTML and Javascript to be run on the client, leaving to a VM only those tasks that can't reasonably be handled that way.
I said that back in August 2009 and, frankly, I was kind of stating the obvious. Maybe Adobe should have made me CEO. I doubt I would've done much worse than the current management given the recent layoff announcements.
I know people think of me as an Adobe hater. I'm not. More accurately, I'm a disgruntled fan. In the nineties I held Adobe in higher regard than I held Apple (at least Apple before Jobs' return). I adored Photoshop, which I had started using around version 1.5 and which enabled me to make a living for a couple of years. Somehow, in the span of fifteen years, Adobe went from being a company that made amazing things to being a company that made mediocre things that they marketed as amazing. A company that had no focus. A company that churned out new versions of software in order to generate new income, not to meet honest customer demand. I watched a great company become a company that didn't care about being great as long as quarterly profit sheets looked good.
I, for one, am hoping for a Phoenix-like rise from the ashes on the order of Apple's comeback. Hoping… but not expecting.
http://iphonedevelopment.blogspot.com
Posted on 9 November 2011 | 6:20 am
Objective-C 2.0 Compiler Directives
Steffen Itterheim has posted a really nice list of all the Objective-C 2.0 compiler directives along with examples of how to use them.
Nice!
http://iphonedevelopment.blogspot.com
Posted on 20 October 2011 | 8:26 am
GLKit Examples
I've added three new projects to my iOS OpenGL ES repository on GitHub. They are fairly simple examples of how to use GLKit and GLKBaseEffect. You can find them in the GLKit Stuff directory.
They're kind of rough, but they should be helpful to you if you're just getting started with GLKit and trying to figure out how to use it.
Thanks to Julián Oliver for tweeting the solution to a problem I was having getting textures to work with GLKBaseEffect.
http://iphonedevelopment.blogspot.com
Posted on 19 October 2011 | 10:32 am
CGAffineTransform Additions
As you probably know, Apple provides a bunch of functionality for manipulating objects in 2D space using CGAffineTransform. Oddly, Apple doesn't provide you with a way to extract the scale, transform, and rotation information from a CGAffineTransform and they don't provide any shearing functionality at all.
Here are some additional inline functions that I use. This adds the ability to extract component values of the CGAffineTransform and also adds the ability to create and extract shear information.
As always, this code is free to use without restriction or limitation, but has no warranty whatsoever. If you fix a bug, feel free to let me know about the fix so I can incorporate the fix.
#ifndef __MCP_AFFINE_TRANSFORM_ADDITIONS__
#define __MCP_AFFINE_TRANSFORM_ADDITIONS__
#import <CoreGraphics/CoreGraphics.h>
#ifdef __cplusplus
extern "C" {
#endif
#define degreesToRadian(x) (M_PI * x / 180.0)
#define radiansToDegrees(x) (180.0 * x / M_PI)
static inline CGAffineTransform CGAffineTransformMakeShear(CGFloat shearX, CGFloat shearY)
{
return CGAffineTransformMake(1.f, shearY, shearX, 1.f, 0.f, 0.f);
}
static inline CGAffineTransform CGAffineTransformShear(CGAffineTransform transform, CGFloat shearX, CGFloat shearY)
{
CGAffineTransform sheared = CGAffineTransformMakeShear(shearX, shearY);
return CGAffineTransformConcat(transform, sheared);
}
static inline CGFloat CGAffineTransformGetDeltaX(CGAffineTransform transform) {return transform.tx;};
static inline CGFloat CGAffineTransformGetDeltaY(CGAffineTransform transform) {return transform.ty;};
static inline CGFloat CGAffineTransformGetScaleX(CGAffineTransform transform) {return sqrtf( (transform.a * transform.a) + (transform.c * transform.c) );};
static inline CGFloat CGAffineTransformGetScaleY(CGAffineTransform transform) {return sqrtf( (transform.b * transform.b) + (transform.d * transform.d) );};
static inline CGFloat CGAffineTransformGetShearX(CGAffineTransform transform) {return transform.b;};
static inline CGFloat CGAffineTransformGetShearY(CGAffineTransform transform) {return transform.c;};
static inline CGFloat CGPointAngleBetweenPoints(CGPoint first, CGPoint second)
{
CGFloat dy = second.y - first.y;
CGFloat dx = second.x - first.x;
return atan2f(dy, dx);
}
static inline CGFloat CGAffineTransformGetRotation(CGAffineTransform transform)
{
// No exact way to get rotation out without knowing order of all previous operations
// So, we'll cheat. We'll apply the transformation to two points and then determine the
// angle betwen those two points
CGPoint testPoint1 = CGPointMake(-100.f, 0.f);
CGPoint testPoint2 = CGPointMake(100.f, 0.f);
CGPoint transformed1 = CGPointApplyAffineTransform(testPoint1, transform);
CGPoint transformed2 = CGPointApplyAffineTransform(testPoint2, transform);
return CGPointAngleBetweenPoints(transformed1, transformed2);
}
#ifdef __cplusplus
}
#endif
#endif
http://iphonedevelopment.blogspot.com
Posted on 18 October 2011 | 9:57 am
Long Live the King
Jeff Atwood of Coding Horror has an interesting post today about being a developer for Apple's ecosystem. We'll leave aside for now the fact that Jeff isn't and has never been an Apple developer and is, in fact, a strong proponent of Microsoft's developer stack. Despite that flaw, I usually enjoy reading Coding Horror. I think Jeff's a smart guy with a lot to offer the world in terms of insight about software development.
But…
Jeff's premise today is that third party Apple developers "serve at the pleasure of the king", which is absolutely true. But, he finishes his post by saying he would never develop for Apple's app stores because of the chance of "being thrown under a bus" by Apple. Fair enough, we all have different tolerance levels for things, and his assumption here is essentially correct. Apple developers run a risk of having Apple compete directly with us if our product is successful enough. It happens, perhaps, to .01% of us, but it does happen.
I want to run with Jeff's metaphor a bit, but first, I need to address a couple of points in his article.
The first point I want to talk about is his claim that if Microsoft were to ever do something as audacious as release a product with the same features as one of their third party developers
…developers would be screaming bloody murder and rioting in the, er, blogs and web forums.
Wait… what? Excuse me? What the hell kind of fantasy world does one have to live in to think that Microsoft doesn't, wouldn't, and hasn't competed with their own third-party developers. Microsoft practically made a sport of it in the nineties, and has continued to do it since then, albeit less obnoxiously. I mean, have we forgotten that Microsoft was convicted by both the US and the EU of abusing their monopoly power to compete unfairly. Microsoft used to routinely use their market power to put smaller software companies out of business in order to gain control of a particular niche of the software industry.
And what were the third party Microsoft developers doing back then? Screaming bloody murder?
Nope.
They were defending Microsoft, and understandably so. The hand that feeds and all that. Those developers knew that being assimilated by Microsoft, or being unfairly competed against by Microsoft, were risks of doing business in that particular market and they deemed it worth the risk, much the way that iOS developers do today with Apple.
The second point that I think needs to be made is Atwood's implied assumption that because Marco Arment isn't up in arms over Safari's Reading List feature (which duplicates many of Instapaper's features), and isn't ranting to anybody who will listen, that it means he's "a loyal subject of the king". The implication being that Marco will put up with any treatment that Apple chooses to dish out, no matter how unfair, because he's a good whipping boy.
Which is a completely inaccurate characterization.
I don't know Marco personally, but he's one of the very few people I follow on the Internet who has consistently come across like a grown-up. Marco knew that getting sherlocked was a risk he faced by participating in Apple's ecosystem and decided that it was worth the risk. When that risk turned into reality, he accepted the consequences like a grown up. Anyone who could condemn a man for acting maturely should be called out for it, and that's exactly what Jeff is doing here. Marco's response to the Reading List feature was nothing less than admirable.
Virtual Geography
Now, back to Jeff's original metaphor of App ecosystems as countries. Let's talk a little bit about the Apple Kingdom and also about the neighboring countries where, as a merchant, you might choose to peddle your wares if the King's terms aren't acceptable to you.
The Apple Kingdom
As Atwood noted, the Apple Kingdom is a monarchy, ruled by a King. By Jeff's own admission, this king is a benign king, making decisions that he feels are best for his citizenry (consumers). He's not perfect, but generally his decisions have served the populace well, and they are happy and prosperous. The Apple Kingdom has beautiful paved roads and a great system of railways, and state-run stores within walking distance of every single citizen in the country. The king has invited even the smallest merchants to use this infrastructure to sell goods in exchange for a small percentage of their income and so long as those merchants follow some guidelines that the King has set (and, admittedly, may periodically change) in order to make sure his citizens have a good experience in his stores.
The Apple Kingdom is large, and its citizens are fairly affluent. They regularly shop at the King's stores and enjoy buying things there. Even tiny merchants are finding ways to make a comfortable living by being able to reach all the citizens of the country. Sure, not all merchants are succeeding. Even the best roads and stores aren't going to make a poorly run business profitable or get people to buy spoiled produce, but the opportunity is there for any one who wishes to sell goods to do so with minimal overhead and startup costs.
The King, however, is also something of a merchant himself, and sometimes he will sell at his own stores. He doesn't sell much, but when he does, sometimes he's selling the same types of products as some of the merchants in his kingdom. The King, of course, doesn't have to pay a percentage of his income to use the trains, roads, or stores, though. In even rarer cases, he'll find a product in the stores he likes so much that he wants to provide it to all of his citizens for free, which basically makes it impossible for the original merchant to sell that product any longer.
Now, the Apple Kingdom is not the only country in the world, and the King doesn't prevent anybody from emigrating or, in fact, even from exporting products to other countries. When deciding whether to pack up and go to another country, you need to make sure that your destination is going to be better than where you are now, so let's look at these other countries.
Androidistan
The largest neighboring country is an enormous country called Androidistan. Androidistan doesn't have a king, but instead has dozens of local and municipal governments of varying types and quality. Their national system of government is probably best described as anarchy. Androidistan's infrastructure varies greatly from province to province, with some roads and trains being free for anybody to use, and others requiring payment. Many provinces have their own stores where anybody can sell, but it's hard to find what you want and the quality of the goods is generally kind of poor, though there are exceptional products if you're willing to look for them. Unfortunately, there are also dangerous products sitting on the shelves as well. Poisoned produce and other deadly items disguised as legitimate goods.Although there's a lot of people in Androidistan, most of them don't really like to buy goods at the government stores. They like to go in and make a meal of the free samples, but most don't really like to actually buy anything and shoplifting is rampant in these stores. In fact, it's often considerably easier to steal a product than to buy it legitimately because many of the stores aren't very well run.
Most merchants have found they can't make enough money selling their goods in Androidistan's markets, so they've tried placing stickers on their goods advertising other products. Some merchants are making a really good living doing this, but many more aren't even covering their costs.
Windowsland
On the other side of the Apple Kingdom is the relatively large country of Windowsland. Windowsland was once prosperous and has a huge amount of industry, but the country has been stagnating somewhat during the recent move toward smaller merchants. The government has recently started updating their infrastructure and building stores modeled after the ones in the Apple Kingdom. Windowsland has started a heavy advertising campaign trying to get merchants to sell their goods there.
Despite a great infrastructure and clean, brightly-lit stores, Windowsland has been having limited success in moving to the modern age of small merchants. Their large industry is still going strong, though, and in the long run, likely their stores will start to do a good business. Someday.
Oh, did we mention that Windowsland is also run by a King? He charges the same percent of income to use his railways, roads, and stores, but has placed fewer restrictions on his merchants in an attempt to lure them to sell in his country. Windowsland is a pleasant enough place, but there's just not all that many people going into their stores yet.
The Democratic Republic of WebOS
This small country had huge potential, but recent mismanagement and ineptitude have basically shut the government down. There are a few citizens roaming the streets still in a bit of a daze, but most have left for better-run countries.
The Blackberry Oligarchy
The Blackberry Oligarchy, which actually has two kings, has gone in one generation from prosperous world power to third world country due to its inability to change its ways. Citizens have been leaving this country at an alarming rate and the remaining citizens have little faith that their pair of kings will be able to fix the problems given the frequent power outages and decaying infrastructure.
There are several other small outlying countries in MobileWorld, but these five pretty much cover the major markets that merchants would want to sell into.
Epilogue
Metaphors are easy to stretch to a point that they become meaningless, and I probably crossed the line a few paragraphs back, but the point is this: all ecosystems have their benefits and their downsides. In the old days of boxed software, instead of a single benign king, you had to deal with a dozen tyrants (software chains) to get your goods on the shelf, and they took more than half the sale price in exchange. If you didn't want to deal with them, you could instead choose to work through a distributor who took another large chunk of your gross income in exchange for dealing with the tyrants on your behalf.
In every market at every time the risk of competition from a bigger, richer competitor has existed.
Part of Atwood's argument is that even good Monarchies can go bad. Sure they can. So can good democracies. Let's take what Apple might be someday off the table. We can't fault people for not staging a revolution before there's an actual reason to revolt.
Whether you do it explicitly or not, going into business means you're accepting certain risks in order to obtain certain rewards. When bad things happen in business — when risks (anticipated or otherwise) turn into actual problems — acting like a twelve year-old and whining to the Internets doesn't make things better. You buck up, find a way to fix it, or move on to something else.
So, yeah. We Apple developers serve at the pleasure of our King, and we know it. In exchange, we get access to millions of citizens who want to buy our products. A tiny percentage of us will end up competing directly with our king at times, but overall, life is pretty good in the Apple Kingdom for us merchants.
And, while we'd be glad to have you among our ranks, Jeff, you're more than welcome to pack up your gear and move to a neighboring country if you think life would be better for you there.
http://iphonedevelopment.blogspot.com
Posted on 15 October 2011 | 8:26 am
Disappointing
So, like others, I was tempted to write a defense of the iPhone 4S after all the pundits and naysayers came out last week calling the iPhone 4S "disappointing". I'm glad I never found the time. As it turns out the iPhone 4s doesn't need anybody to stand up for it.
1,000,000 phones sold on the first day of pre-orders. That's 400,000 more than the iPhone 4.
And, that's not counting the number that will sell on October 14th when they arrive at the Apple Stores in 7 countries.
There's also a large batch of countries that don't get the phone until October 28, and a whopping 40 more countries (including China, where new Apple Stores have been shattering sales records lately) that won't get the iPhone 4s until some time in December.
Yeah. Disappointing. You guys in the media sure nailed that one.
http://iphonedevelopment.blogspot.com
Posted on 10 October 2011 | 8:28 am
Respect & Shame
It's been fascinating seeing how many people have responded to the death of Steve Jobs exactly the way I did. It's truly amazing how many people who never met the man feel not just that the world has lost somebody significant but that they themselves have lost a friend.
Hearing others express exactly what I'm feeling? It helps. And, for the most part, the media has been right there with us, responding to Steve's death by focusing on his impact and the good he has done.
I really hope seeing how many peoples' lives he has touched is helping Steve's family and friends get through this.
But not all of the media has chosen to focus on the good. I won't link to any of the actual articles, but Gawker and the New York Times top a short list of media outlets that have chosen to focus on Steve's flaws and to stand up and shout out to anybody who will listen that Steve was… well… human. Imperfect. Flawed.
There's a custom in modern society that's often called "respect for the dead". It has nothing whatsoever to do with the dead. The dead don't care what you say about them. It's about the living who cared about the dead, and they do. It's because they care that mourning is such a difficult process. Painful. Sad. It's not a time when you want reminders of the flaws of the person whose absence you are trying to come to terms with.
No human with with a shred of empathy or decency chooses to publicly criticize the recently departed, famous or otherwise, regardless of how they felt about them. Doing so is an act of cruelty. It's hurtful. Little. It's kicking people hard when they are already as low as they can be.
For those, like me, who care, but didn't know Steve Jobs personally, people like this are an annoyance. They're just another crass, classless obnoxious Internet loudmouth that we have to make an effort to ignore.
But for Steve's family, friends, and coworkers… the people who really knew him, it's a hell of a lot more than that. It breaks my heart to think that they might read those articles.
Shame on you, New York Times. You're better than that. Shame on you, Gawker. You should be better than that.
http://iphonedevelopment.blogspot.com
Posted on 6 October 2011 | 10:19 pm
Sad Mac

I haven't had much time for blogging lately. I have about a half-dozen unfinished blog posts in my queue, but have been too busy to finish any of them.
One of the things keeping me busy right now is work for Apple through MartianCraft. This work, in many ways, is a dream come true for me, as I wanted to work for Apple for years and never managed it.
I started programming on an Apple ][+ in 1980 and Apple has been a part of my life ever since then. I don't need to look much further than the desk I'm sitting at to realize just how much my life has been impacted by this company called Apple started in a garage by two guys named Steve. I make a living using Apple's products and developing for Apple's products, but more importantly, my life is better because of their products.
I took a few hours away from my desk this evening and returned to the news of Steve Jobs' death. I came back to news that quite literally felt like a kick in the stomach. And I mean literally. My stomach hurts.
It seems odd to feel this way about a man I never met. I've only once been closer to Steve Jobs than the front section of Moscone West or North, and that was when I accidentally knocked into him on the show floor at MacWorld one year. But I feel like an old friend has died. I'm fighting back tears, and maybe I should be ashamed of that.
But I'm not.
Steve died far too young. I think a few tears are in order.
http://iphonedevelopment.blogspot.com
Posted on 5 October 2011 | 6:16 pm
Online Session Code for Big Objects (Plus a Warning)
In Chapter 9 of More iPhone Development, we wrote a set of classes that mimicked the behavior of GameKit's peer-to-peer connectivity, but for regular network connections (GameKit's only works with BlueTooth and local network connections). Basically, we wrote a class that lets you send and receive anything that can be packaged into an instance of NSData. Since it's relatively trivial to implement NSCoding for most classes, this means passing objects between two iOS apps (or an iOS and a Mac app) becomes pretty easy. You don't have to poll for the data, or worry about chunking out the data. You just make a method call and pass an NSData instance to send data, and then implement a delegate method for receiving data back from the other end. Life is good, right?
Hmm...
Maybe not. There's a pretty big limitation in the book's implementation. That implementation, designed for passing tiny packets of data (TicTacToe game moves), kept everything in memory. If you try to send a good size image to the other connection, likely you'd run out of memory fairly quickly.
A while back, I faced exactly that situation. For a kiosk app that MartianCraft was writing for a client, I needed to send large images shot with a DSLR camera from a Mac Cocoa program to an iPad program and also needed to send pictures taken with the iPad's camera back to the Mac Cocoa app. These images, compressed, ranged from about one to about five megs. I grabbed the OnlineSession class from More, figuring I had the network code basically done, and watched my application go down in a blaze of… well… not glory, that's for sure. Not only did the iPad run out of memory, it ran out of memory FAST… much faster than I expected. Even sending the smaller iPad camera images often caused low-memory crashes.
There were two basic problems with the OnlineSession class when you try to use it for sending larger volumes of data. First, as I said, was that it relied only on physical memory. Given that the physical limitations of the original iPad, this was problematic. But there was another, much bigger problem.
The second issue was that during the process of chunking up the data to send, the code kept making unnecessary copies of the data. Put simply, I made a n00b mistake. The mistake didn't impact the TicTacToe application because the game moves would easily fit into the send buffer, but it's a mistake I've made before and definitely should've known better.
So, what, specifically, was this mistake, you ask?
Using NSData's regular convenience constructor dataWithBytes:length: when creating the new NSData instance to store the portion of the image that won't fit into the send buffer. If you read the description of dataWithBytes:length:, it very clearly says that it makes a copy of the data you provide. So, every time a packet was sent, the code would create a new NSData instance to hold the remainder that wouldn't fit in the buffer, and it would copy all the remaining unsent data for every packet. Ouch.
So, as a simple example, if we were sending a 5 meg image, and the send buffer was set to 128k, the code would make a 4.825 meg copy after the first packet was sent, then a 4.75 meg copy after the second packet was sent, a 4.265 meg copy after the third packet, and so on. After every packet, another slightly smaller copy of the data was made. A descending progression that would eat up memory fast.
After a lot of swearing at myself, I made some modifications to the class to do two things.
First, I switched to using NSData's dataWithBytes:NoCopy:length:, which uses the provided data in place without making a copy. This kept the memory footprint a lot smaller. In some instances, because the DSLR images were so large and our app needed to send so many, I still hit memory problems. So, the second thing I did was to add filesystem caching of the outbound queue so that all the encoded objects waiting to be sent didn't have to fit in memory for the application to function properly.
The new version of the class functions exactly as the one from the book, so you should be able to just drop-in replace the OnlineSession from Chapter 9 with this one without making any changes to your application code.
You can download the new version right here.
http://iphonedevelopment.blogspot.com
Posted on 12 August 2011 | 6:58 am
Working for MartianCraft
In case you missed my tweets earlier this week, MartianCraft is looking to add a few developers. We're looking for a couple of experienced developers, and are also thinking about bringing in one or two entry-level devs without significant experience to be trained up.
Initially, the work would be project-based contracting and would start in late August. Conversion to full-time employment is a possibility, but not right away.
If you're interested in being considered, send an e-mail with relevant work experience and/or résumé/CV to work@martiancraft.com.
http://iphonedevelopment.blogspot.com
Posted on 26 July 2011 | 2:25 pm
Auto-Incrementing Build Numbers for Release Builds in Xcode
I use the wonderful Test Flight to distribute builds. One thing that Test Flight is a little picky about is build numbers. When you upload a build, it uses the build number to see if you're uploading a replacement or a new build. It will let you create a new build even if you don't remember to increment the build number, but it's an extra manual step, and then you end up with two builds with the same build number.
Because I'm forgetful, I wanted to automated this process. Basically, I wanted to increment the version short string any time we do an Archive and increment the bundle build ID any time we do a Release configuration build, but leave the version numbers alone on Debug builds.
Unfortunately, several of our projects are ones that we inherited or took over, so not every project uses the same version numbering scheme. How we increment 1.0b5 is different from how we increment 1.0.12, or a simple build number like 1058.
The way I deal with this is a Run Script Build Phase in my application's executable target that runs the following Ruby script (make sure you set the "shell" field to /usr/bin/ruby, and make sure the script is the last build phase in the application). Feel free to use this script if you wish and modify it to meet your needs. If you improve it, I'd be glad to incorporate improvements back into it. One item of note: the way that I differentiate between Archive builds and other Release configuration builds might be a bit fragile since I'm relying on an undocumented naming pattern in an environment variable.
Note: I'm aware of agvtool. I avoided it for two reasons. First, I wanted more control over the numbering schemes, and second, I tried using agvtool in a build script a few years back, but at that time, there were issues when you bumped the version numbers of a project that was currently open. Those issues may have been resolved, but I didn't want to fight that battle again.
def get_file_as_string(filename)
data = ''
f = File.open(filename, "r")
f.each_line do |line|
data += line
end
return data
end
def handle_alpha_beta(old_value, letter, infoplist, start_of_value, end_of_value)
parts = old_value.split(letter)
version_num = parts[0]
alpha_num = parts[1].to_i
alpha_num = alpha_num + 1
new_version = version_num.to_s + letter + alpha_num.to_s
print "Assigning new version: " + new_version + "\n"
new_key = "<string>#{new_version}</string>"
part_1 = infoplist[0, start_of_value - '<string>'.length];
part_2 = new_key
part_3 = infoplist[end_of_value + "</string>".length, infoplist.length - (end_of_value - start_of_value + (new_key.length - 1))]
new_info_plist = part_1 + part_2 + part_3
new_info_plist
end
def find_and_increment_version_number_with_key(key, infoplist)
start_of_key = infoplist.index(key)
start_of_value = infoplist.index("<string>", start_of_key) + "<string>".length
end_of_value = infoplist.index("</string>", start_of_value)
old_value = infoplist[start_of_value, end_of_value - start_of_value]
print "Old version for " + key + ": " + old_value + "\n"
print old_value.class.to_s + "\n"
old_value_int = old_value.to_i
print old_value_int.class.to_s + "\n"
if (old_value.index("a") != nil) # alpha
infoplist = handle_alpha_beta(old_value, "a", infoplist, start_of_value, end_of_value)
elsif (old_value.index("b") != nil) # beta
infoplist = handle_alpha_beta(old_value, "b", infoplist, start_of_value, end_of_value)
elsif (old_value.index(".") != nil) # release dot version
parts = old_value.split(".")
last_part = parts.last.to_i
last_part = last_part + 1
parts.delete(parts.last)
new_version = ""
first = true
parts.each do |one_part|
if (first)
first = false
else
new_version = new_version + "."
end
new_version = new_version + one_part
end
new_version = new_version.to_s + "." + last_part.to_s
print "New version: " + new_version.to_s + "\n"
new_key = "<string>#{new_version}</string>"
infoplist = "#{infoplist[0, start_of_value - '<string>'.length]}#{new_key}#{infoplist[end_of_value + '</string>'.length, infoplist.length - (end_of_value+1)]}"
elsif (old_value.to_i != nil) # straight integer build number
new_version = old_value.to_i + 1
print "New version: " + new_version.to_s + "\n"
new_key = "<string>#{new_version}</string>"
part_1 = infoplist[0, start_of_value - '<string>'.length]
part_2 = new_key
part_3 = infoplist[end_of_value + "</string>".length, infoplist.length - (end_of_value+1)]
infoplist = part_1 + part_2 + part_3
end
infoplist
end
config = ENV['CONFIGURATION'].upcase
config_build_dir = ENV['CONFIGURATION_BUILD_DIR']
archive_action = false
if (config_build_dir.include?("ArchiveIntermediates"))
archive_action = true
end
print "Archive: " + archive_action.to_s + "\n"
print config
if (config == "RELEASE")
print " incrementing build numbers\n"
project_dir = ENV['PROJECT_DIR']
infoplist_file = ENV['INFOPLIST_FILE']
plist_filename = "#{project_dir}/#{infoplist_file}"
infoplist = get_file_as_string(plist_filename)
infoplist = find_and_increment_version_number_with_key("CFBundleVersion", infoplist)
if (archive_action)
infoplist = find_and_increment_version_number_with_key("CFBundleShortVersionString", infoplist)
end
File.open(plist_filename, 'w') {|f| f.write(infoplist) }
else
print " not incrementing build numbers"
endhttp://iphonedevelopment.blogspot.com
Posted on 14 July 2011 | 7:28 am
Happenings and Prospects
I apologize for the relative dearth of posts here since WWDC. That week in San Francisco always tends to backlog me pretty badly (I returned from WWDC at inbox 1138 - and that's after spending the return flight answering e-mails), so I've been pretty much heads down on work-related stuff ever since. I've also, at the same time, been consciously trying to back away from the 12-15 hour days, 7 days a week schedule that I'd fallen into trying to help get MartianCraft off the ground. Those two have conspired to give me very little time for writing lately, but I think things are under control now.
I've got my semi-mythical OpenGL ES from the Ground Up 10th installment on skeletal animation nearly finished and hope to have it posted within the next couple of weeks, and it's bit of a doozy. My goal with this post is to make one of the more intimidating topics in graphics programming approachable. Fingers crossed, it's been a challenge making this topic approachable, but I think I'm getting there.
A few other bits of news.
First, work has officially started on Beginning iPhone 5 Development. Yes, I know it probably should be called Beginning iOS 5 Development, but as of right now, we're sticking with the naming sequence Apress established with the first book. Dave, Jack, and I have already started updating the book for Xcode 4, ARC, Storyboards, and all the other cool new stuff and are hoping to have the book ready to go to press when the GM version of iOS 5 ships this fall.
Second, I purchased a new domain today. There's nothing there yet, but OpenGLESBook.com is now mine, and I have big plans for it. Once Beginning iPhone 5 Development is in the can, I'm going to revisit my partially written OpenGL ES 2.0 book. I plan to revise it to use GLKit and to add material about the very cool new OpenGL ES tools we're getting with iOS 5.
As of right now, my plan is to self-publish. I'm still researching the exact process, tools, and services that I'll use, but my plan is to sell the book without DRM and at a reasonable price. I'd like to have an early access program, however since a lot of the material I'll be covering will be under NDA until iOS 5 goes GM, I can't promise that at this time.
http://iphonedevelopment.blogspot.com
Posted on 7 July 2011 | 10:08 am
Update on UpdateConf
Just wanted to let you know that I'm speaking at another conference. I'll be speaking at the inaugural UpdateConf in Brighton, UK on September 5th.
As part of the conference, I'm also giving a two-day intensive workshop on OpenGL ES. The workshop assumes no prior experience with graphics program, but will be fairly fast-paced and will cover a lot of ground because there's a lot of new ground to cover. I'll be going over the new GLKit and the incredible new OpenGL debugger as well as the updated OpenGL ES Instruments templates.
Not interested in OpenGL ES? There are four other two-day workshops going on with some really awesome instructors. Marcus Zarra is doing a two-day workshop on Core Data, Drew McCormack is doing a workshop on Core Animation, Sarah Parmenter is doing one on iOS UI design, and Remy Sharp is doing one on HTML5 for mobile. The worst thing about giving this workshop is that doing so will prevent me from going to one of the other great workshops.
The conference proper has a number of speakers, including the workshop instructors and it's really shaping up to to be quite a conference, and also quite a steal at £99 for early bird tickets to the conference (the workshops are extra). You can sign up for the conference on EventBrite.
Hope to see you there!
http://iphonedevelopment.blogspot.com
Posted on 7 July 2011 | 5:52 am
On Being Excellent to Each Other
Marcus Zarra has a somewhat depressing post today on the excellent Cocoa is My Girlfriend blog. It's about the release of The Daily. Because of all the secrecy around The Daily prior to its official launch, I think not a lot of people knew Marcus was not just involved with it, but was actually leading much of the development effort.
I knew.
I wasn't on the main development team for The Daily, but I did most of implementation work on a single component (the 360° panorama). I wasn't in NYC every day the way Marcus was, but I went down there enough to know the conditions under which the application was written. I saw the endless late nights (actually, it was usually early mornings) and the stress and difficulties under which the app was written.
A personal stake always makes it harder to watch negative publicity. The Daily's launch was especially hard because I was in a position where I couldn't really come to Marcus' team's defense, since my involvement with the project wasn't yet public knowledge. If it had been, I would have been written off as biased.
So, I had to just sit back and watch it the way you'd watch a trainwreck. It was painful watching the snark. It was painful watching Loren Brichter, a well-respected member of our community put together a carousel demo in a complete vacuum and post a video of it as if it proved something about performance in an incredibly large and complex application. It was even more painful seeing John Gruber link to that video, spreading a false impression to a far wider audience.
They both enough about software development that they should have known better. There's almost no part of The Daily that can't be re-implemented in a few hours as a standalone application using static data and with great performance.
Doing the same thing as part of a large development application developed by a large team, working with a larger management team and a huge content and production teams under an unreasonable deadline and constant pressure? That takes more than being a competent developer. A lot more. It takes patience and diplomacy and a very high tolerance for frustration. I don't think I would've survived in Marcus' shoes all those months. I would've walked out or been escorted out long before the launch ever happened. It was honestly that tough.
I'm not sure that our community is getting quite as bad as it appears to Marcus at the moment, but there is no doubt that we are capable of producing our share of snark. And let's be honest… I am capable of producing more than my individual share. I don't think we think about being mean when we fire off a smug comment. I think it's usually just a side effect of expressing a myopic, partially informed opinion. I'm sure Loren honestly believes he could have done better with the carousel had he been working on The Daily. But he's wrong. He just doesn't know enough about the situation to realize it.
But it's not my intention to point fingers here. I'm been just as guilty at times. Last year, during the WWDC keynote, I was extraordinarily snarky about the Farmville demo, completely forgetting that I know people who worked on it. I wasn't intending to shit on their work, but I did, and I'm sincerely sorry about it. There have been other examples. I hope there won't be more in the future, but only time will tell.
I think Marcus' post should be read and taken to heart by all of us. I think it should serve as a reminder that real people — very often our friends and colleagues — are behind the software and hardware that we express opinions on. We should keep in mind that a lot of work went into it. We should also keep in mind that in most cases, we have no idea the circumstances under which the application was written.
Being critical is not only fine, but a necessary part of driving each other to be better developers. But we should try and avoid being a dick about it. It can be done respectfully, and should be.
I promise to try if you will.
http://iphonedevelopment.blogspot.com
Posted on 4 June 2011 | 4:18 am
Thoughts on Unity3D
As I stated in my previous post on 3D engines, I'm going to do four blog posts giving my thoughts on each of the four engines that I looked into using for a project recently. Those four engines are Unity3D, Sio2, Ogre3D, and Cocos3D. I'm starting with Unity3D, which we selected for one of our recent projects.
Now, let me state up front, that all four of these are competent engines and I could see situations where I would recommend three of the four engines for client projects and could easily imagine situations where all four of them would be good choices.These four do not make an exhaustive list; there are other engines out there, including some really good ones, but these were the four that we looked at for this specific project. As much as I like the UDK, for example, I don't like it enough to spend quality time in Windows, so that one is off the table for me until the fine folks at Epic decide to port their dev and content tools to the Mac.
Unity Overview
Unity3D actually predates the iPhone, and of the four engines, it's the one that feels the most mature and has the most robust developer tools. It also has one of the most active developer communities. Unity3D is a closed-source commercial product that you must pay for, which might be a turn-off for some, but it is worth every penny of the license fee.Unity Pros
Unity is actually fairly easy to learn, yet has a feature set that is compares favorably to most other engines. Unity's asset pipeline is really robust and their tools give you the ability to very quickly make changes and test those changes.One of the best things about Unity3D is the fact that it supports both Windows and Mac OS equally as development platforms. Regardless of which platform you develop on, you can generate games that runs on every platform Unity supports (assuming you're licensed for it). You can even have part of your team developing on Macs and the other part on Windows with no problems.
At the time I'm writing this, it is possible to generate games from Unity that run on Mac OS X and Windows (both native apps as well as games playable through a web plug-in), iOS, Android, Wii, Xbox 360, and PS3. The Unity folks are also actively working on adding Linux support. Console licenses are negotiated on an individual basis and are likely quite expensive, but it's nice to have the option to take a successful game to so many platforms without having to do a full port each time.
Having had to port OpenGL ES apps from iOS to Android more than once (which is no fun), I can honestly state that the Android support should be a huge selling point you're giving any thought to supporting both iOS and Android.
Unity Cons
The downsides to Unity3D are relatively few, actually.It is the most expensive of the engines I looked at, and the costs are completely front-loaded. You pay a flat per-developer license per platform up front, but then you can create as many games as you want for the platforms you're licensed for. For the basic iOS license, it's $400 per seat (one developer using up to two machines), for the Pro license, you're looking at $3,000 (because the $1,500 iOS Pro requires the $1,500 Unity Pro), which might sound like a lot of money, but it's really a pittance compared to the amount of development time it can save you. The "Basic" version of Unity, which allows you to generate Mac, Windows, and Web games (though excludes some of the more advanced features) is available completely free of charge.The other potential downside in some situations is that the underlying C++ source code is not available. You work primarily in either JavaScript or C# (MonoScript) and at a higher level of abstraction. Unity supports a few other languages besides Javascript and C#, but only those two languages work for mobile development.
After about two weeks of spending my evenings with Unity, I actually came to the conclusion that not having access to the source isn't really much of a drawback, and for many developers, working this way will be better than working in C++. The engine takes care of almost all the low-level stuff you'd need to do, but even if it doesn't, Unity has a shader language that lets you write code that runs on the GPU and anything that needs to run on the CPU can be done by scripting inside Unity.
Although the programming in Unity3D is done with scripting languages, the scripts you write are actually compiled, so there's not a huge performance overhead to using them. In the exceedingly rare situation where C# or Javascript isn't sufficient, it is possible to send messages into and out of Unity from your application's C or Objective-C code.
Learning Curve
I found Unity surprisingly easy to learn. There are some really good resources out there, including lots of tutorials and instructional videos. I actually had a game functioning after about two hours of playing. It was ugly and the game mechanics were simple, but it was playable. Unity also has a fairly active developer community forum where you can go and get help when you get stuck.If you don't already know something about graphics programming, you still don't need to be too scared or intimidated. Most of the gnarly stuff is squirreled away where you won't see it until you need it, and you can do a surprising amount by just configuring things in the development GUI. You can create, for example, a fairly full-featured physics simulations without ever writing a line of code. Want to stack up a bunch of crates and roll a ball into them and watch them all fall? You can do it without ever opening a text editor. Heck, you can even do that without opening a 3D program.
Complexity
I was scared of one thing going into learning Unity: I was concerned that because it was so easy (at least I had heard it was), that it was going to be a dumbed down game maker that sacrificed more advanced features for the sake of lowering the obstacles to entry. My fears were completely misplaced, though. That's not the case at all. The Unity folks have done a really great job of making their tools easy to use while still giving you the ability to do most anything you'd ever need to do. It's even possible (though the process is a bit convoluted) to integrate UIKit and Unity3D within the same application.Asset Pipeline
The thing that actually impressed me most about Unity is what they call their "asset pipeline", which is the process by which you get 3d models, textures, and other assets into your game. If you've ever developed a game or game mod for the UDK, a Valve Source game, or other commercial engine, usually there's kind of a convoluted process you have to go through to get your game assets including characters, textures, props, and environments, into the game. You usually have to use separate applications to specify shaders and physics options, sometimes write a compile script or other text document to define certain trains, and then compile the object and package it all up into some kind of bundle or package. While developing a single mod, you typically iterate through this process many, many times. It can be a bit tedious and hard to learn and usually requires the use of multiple tools and lots of trial and error.Unity bypasses almost all of this tedium. When you save your assets from your 3D program or Photoshop, you simply save them in your Unity project's Assets folder. When you launch Unity, or navigate back to it if it's already open, Unity detects the new file, or any changes you've made to an existing file. It imports it and adds it to the list of available assets.Anything you need to do that can't be done in your 3D program, such as specify a shader or identify the physics engine properties for the object, you do right in Unity, and most of that can be done without writing code (though everything you can configure without code can also be changed from code).
Which 3D program do you need to use? Pretty much any one you're comfortable with. Unity3D has direct import support for the native file formats from several programs including Blender , but any package that can export to Autodesk FBX or Collada can be used with full support for all features like bones, textures, animations, etc.It also supports native Photoshop files (.psd) for textures, flattening layers in a non-destructive manner when you build your app.Assets can even be given different characteristics for different platforms. You could have, for example, a 2048x2048 texture asset for the desktop version of your game but tell Unity to use a 1024x1024 version for game consoles and a 512x512 version on iOS and Android.
The Bottom Line
As I stated earlier, there are situations where I could see any of the four engines I looked at being a good choice, as could many of the other engines I didn't look at. But, honestly, if I had to make an engine decision without detailed information, Unity3D would be my first recommendation. The tools are solid, the company and community support is awesome, it supports many platforms, and getting assets into your game couldn't be easier. It's relatively easy to start using for both experienced developers and those who aren't.A good, experienced graphics programmer working in mobile right now can easily ask $200 per hour or more because the demand far outstrips the supply. Figure it out. Unity's full iOS license is basically the equivalent of 15 hours of a graphics programmer's time. Yet, Unity will easily cut five times that many hours off of any decent size software game project's schedule, probably a lot more.
I'm giving Unity3D two big thumbs up. I'm using it on a project now and hope to use it on many more in the future because it's fun to use and removes much of the tedium associated with 3D programming without removing power.
1 Many of the more advanced features require the more expensive "Pro" license, however, and really cutting edge features from the latest games generally take a little while to show up in the tools
http://iphonedevelopment.blogspot.com
Posted on 3 June 2011 | 12:26 pm
A Few Seats Left
There are a few seats left for the afternoon trip to Cupertino on June 6th. If you're interested, go here.
As I write this, there are less than 15 seats, though, so if you want one, I suggest you hurry.
http://iphonedevelopment.blogspot.com
Posted on 25 May 2011 | 3:28 pm
Bus Update
Just to let you all know, we're down to eleven remaining available seats on the third and last bus, and they're about equally split between morning and afternoon. If you missed getting a seat on the first two buses, and haven't filled out the interest form for the third, there probably won't be a seat.So, go here now to tell us you're interested in one of the remaining seats. Speak now or forever hold your peace.
http://iphonedevelopment.blogspot.com
Posted on 21 May 2011 | 9:52 am