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.
Showing posts with label iPHone. Show all posts
Showing posts with label iPHone. Show all posts
Monday, October 10, 2011
Saturday, May 14, 2011
3D Game and Graphics Engines
One thing that I get asked about a lot is whether you should use a game or graphics engine instead of learning OpenGL ES. Often, these emails are prefaced by a statement about how hard graphics programming. I've had to answer this question enough times now that it seems like a good topic for a blog post.
Honestly, I find it kind of hard to answer, because I don't see the "using an engine" and "learning graphics programming" as being distinct or mutually exclusive approaches. While a good game or graphics engine will handle a lot of the more gnarly programming tasks for you and shorten your development time, you still need to understand the underlying concepts to build anything of any complexity.
All of these engines are built on top of OpenGL (and/or DirectX if they support Windows), and are subject to the same limitations and strengths. Not understanding, at least at some level, how these lower-level graphics libraries work and the basic maths of 3D programming will eventually hold you back.
But… that doesn't necessarily mean you need to learn OpenGL before you can start using these tools effectively. You don't. It's just that some of the difficult, sticky math and concepts that might be scaring you away from OpenGL are still there (though better hidden), and you may well still have to deal with them at some point if you're doing the coding on the game (as opposed to just creating assets or doing level design).
Here's kind of a simple nutshell rule:
So, when shouldn't you use an existing engine if your goal is to make a game and not to try and be the next John Carmack? Almost never. Rolling your own game engine should be a labor of love. It's got to be an itch you can't scratch; the kind of desire that I probably couldn't talk you out of anyway. Otherwise, it's just a waste of your time.
What about when there just isn't an engine that works for what you want to do?
Honestly, that's not all that likely in this day and age, but even if it is, you're far better off starting with an existing engine and then modifying it to meet your needs.
From a business and financial perspective, it's almost never better to start from scratch. Even many of the AAA commercial game engines are derivatives of other engines. To give an example: Valve's Source Engine, is derived from their older Goldsource Engine, which itself was forked from the Quake Engine back around 1996.
Though there are quite a few game engines around, a very large percentage of high-end commercial games, both console and PC, are based on either the Unreal engine or the Quake engine or one of their derivatives. If you throw in a handful of other engines, like the CryEngine, you've probably covered all but a few outliers.
If it's not cost effective for large, multi-person development teams with multi-million dollar budgets to develop their own game engines, it's probably not the best choice for individual indie developers or small shops.
So, don't reinvent the wheel. Use an engine and stand on the shoulders of John Carmack and others like him. Don't spend your time trying to solve problems that are long-solved. Just be aware that using an engine can't completely eliminate the need to learn a little math or to understand the underlying concepts.
I won't be discussing the UDK, even though it's a phenomenal engine, because it requires using Windows for many tasks, and I don't want to spend time in Windows. If you've got both a Mac and a Windows machine, however, and don't mind splitting time between OS X and Windows, you might want to check it out. A lot of time and brainpower has gone into getting the UDK to have incredible performance on iOS and the license terms have been changed to be much more friendly to small indie shops ($99 plus 25% of royalties after the first $50,000).
Honestly, I find it kind of hard to answer, because I don't see the "using an engine" and "learning graphics programming" as being distinct or mutually exclusive approaches. While a good game or graphics engine will handle a lot of the more gnarly programming tasks for you and shorten your development time, you still need to understand the underlying concepts to build anything of any complexity.
All of these engines are built on top of OpenGL (and/or DirectX if they support Windows), and are subject to the same limitations and strengths. Not understanding, at least at some level, how these lower-level graphics libraries work and the basic maths of 3D programming will eventually hold you back.
But… that doesn't necessarily mean you need to learn OpenGL before you can start using these tools effectively. You don't. It's just that some of the difficult, sticky math and concepts that might be scaring you away from OpenGL are still there (though better hidden), and you may well still have to deal with them at some point if you're doing the coding on the game (as opposed to just creating assets or doing level design).
Here's kind of a simple nutshell rule:
If you love graphics programming or are fascinated by it, then study OpenGL ES and the underlying maths and forget about using the engines at first (though studying their source is a great way to learn). There's always going to be work for good graphics programmers and you can't put a price tag on doing what you love.
If, on the other hand, your goal is to make a game or other graphics-heavy application, and graphics programming is just a means to that end, then use an engine, because it will shorten the amount of work you have to do tremendously, which inherently increases your chances of making money because time is money and there's never enough of it.
So, when shouldn't you use an existing engine if your goal is to make a game and not to try and be the next John Carmack? Almost never. Rolling your own game engine should be a labor of love. It's got to be an itch you can't scratch; the kind of desire that I probably couldn't talk you out of anyway. Otherwise, it's just a waste of your time.
What about when there just isn't an engine that works for what you want to do?
Honestly, that's not all that likely in this day and age, but even if it is, you're far better off starting with an existing engine and then modifying it to meet your needs.
From a business and financial perspective, it's almost never better to start from scratch. Even many of the AAA commercial game engines are derivatives of other engines. To give an example: Valve's Source Engine, is derived from their older Goldsource Engine, which itself was forked from the Quake Engine back around 1996.
Though there are quite a few game engines around, a very large percentage of high-end commercial games, both console and PC, are based on either the Unreal engine or the Quake engine or one of their derivatives. If you throw in a handful of other engines, like the CryEngine, you've probably covered all but a few outliers.
If it's not cost effective for large, multi-person development teams with multi-million dollar budgets to develop their own game engines, it's probably not the best choice for individual indie developers or small shops.
So, don't reinvent the wheel. Use an engine and stand on the shoulders of John Carmack and others like him. Don't spend your time trying to solve problems that are long-solved. Just be aware that using an engine can't completely eliminate the need to learn a little math or to understand the underlying concepts.
Engines
It just so happens that for a number of proposals I've done lately, I've been looking at game engines in some depth. I'm not going to do "reviews" per se, but over the next few weeks, I will try and post my thoughts about several of the engines available for iOS, including Unity3D, Sio2, Ogre3D, and Cocos3D.I won't be discussing the UDK, even though it's a phenomenal engine, because it requires using Windows for many tasks, and I don't want to spend time in Windows. If you've got both a Mac and a Windows machine, however, and don't mind splitting time between OS X and Windows, you might want to check it out. A lot of time and brainpower has gone into getting the UDK to have incredible performance on iOS and the license terms have been changed to be much more friendly to small indie shops ($99 plus 25% of royalties after the first $50,000).
Tuesday, September 28, 2010
Experts == Idiots?
It's sad, really, the state of technology journalism. But you knew that, already. I should know to enough ignore link-baiting crappy journalism, especially those that do little more than republish some company's press release. Most days, I do.
Not today, though.
Computerworld posted an article with this headline today: Devs bet big on Android over Apple's iOS.
Wow, really? That seems surprising. What could possibly justify such a claim? Some proof that developers are leaving iOS in droves? Some new data about the Android Marketplace is actually making decent money for a substantial portion of Android developers? No, though it is encouraging to see that the Marketplace opened up to 13 new countries today. Still another 60 or so to go, but it's a step in the right direction. But that fact's not even mentioned in this article.
So what justifies such a grandiose claim? A survey of Appcelerator Titanium developers commissioned by Appcelerator. Now, if you don't know, Appcelerator Titanium is a cross-platform framework that allows you to develop an app once and generate applications for multiple paltforms: iOS, Android, Linux, Mac OS, and Windows.
Leaving aside my personal opinions about cross-platform tools, the article has already strayed from the headline. Devs? Well, sure, they're devs, but they're not representative of devs in general as the headline would imply. They're developers who have specifically chosen one option, and it's an option that doesn't tie them to a platform at all. We're talking about a group of people that have already shown their willingness to hedge their bets and who aren't about to take the risk of hitching their wagon to a single platform.
It's an inherently skewed sample. If you ran that same survey past 15,000 dedicated iOS developers, or dedicated Android or Blackberry or .Net developers, you'd get drastically different results.
In other words, this survey has no value whatsoever except to Accelerator. To them, it's perhaps useful for helping them decide where to devote their resources in the future to keep their clients happy.
But for the world at large? Worthless.
Oh, and what constitutes "betting big" in the context of the article? Well, it's not actually addressed, but their idea of "betting big" doesn't seem to match mine. There's nothing about investments, or exclusive agreements, or anything else that involves any sort of risk whatsoever. Developers were just asked things like "how interested are you in a platform X". The "betting" didn't involve monetary investments, or time investments. These developers did nothing more than state an opinion. An anonymous opinion. Oh… those crazy rebels.
Well, I'm "betting big" that the author of this post is a hack and his soi-disant "expert" is fucking clueless.
Let's face it, nobody knows for sure where the mobile market is headed, and being a Titanium Dev doesn't make your opinion any more informed or valuable than anyone else's. Personally, I suspect Android will continue to grow in market share unless Windows Phone 7 is better than great or else Microsoft manages to one-up Google's relationship with Verizon. But, any way you cut it, this is not a replay of the PC battles. There are too many companies still in the game and who have the potential to grow market share, profit share, or whatever other metric by which you want to judge.
Despite what you may read, there is no clear market leader. Nokia is still in the lead based on total handsets, Blackberry is still in the lead based on smartphone handsets sold, Apple is kicking ass in the profits department, and Android is doing gangbusters in new sales unit, if you lump all the 100+ models of Android phones together and count free phones as sales. Plus, the market is still growing. Apple, for example, didn't increase their market share at all year over year, but they increased their units sold considerably.
Understandably, many people are counting Microsoft out of the mobile game, but I'm not. Though I'm no fan of their technology stack or their approach to business, I think the sheer size of Microsoft's advertising budget, their Enterprise-savvy sales force, and the enormous pool of existing .Net developer talent they can draw on gives them an opportunity for huge inroads. They may not capitalize on it, but it's certainly there and counting Microsoft out of the wireless market would be as foolish as counting Apple out of the game 12 years ago was. And over at HP, lots of money and time is being invested into the Pre platform, which has not been a huge commercial success, but got pretty good grades with many developers who worked with it.
The game's afoot. It's going to be fun to watch, but if you are truly a betting person, this is what you might call a high-risk scenario.
Not today, though.
Computerworld posted an article with this headline today: Devs bet big on Android over Apple's iOS.
Wow, really? That seems surprising. What could possibly justify such a claim? Some proof that developers are leaving iOS in droves? Some new data about the Android Marketplace is actually making decent money for a substantial portion of Android developers? No, though it is encouraging to see that the Marketplace opened up to 13 new countries today. Still another 60 or so to go, but it's a step in the right direction. But that fact's not even mentioned in this article.
So what justifies such a grandiose claim? A survey of Appcelerator Titanium developers commissioned by Appcelerator. Now, if you don't know, Appcelerator Titanium is a cross-platform framework that allows you to develop an app once and generate applications for multiple paltforms: iOS, Android, Linux, Mac OS, and Windows.
Leaving aside my personal opinions about cross-platform tools, the article has already strayed from the headline. Devs? Well, sure, they're devs, but they're not representative of devs in general as the headline would imply. They're developers who have specifically chosen one option, and it's an option that doesn't tie them to a platform at all. We're talking about a group of people that have already shown their willingness to hedge their bets and who aren't about to take the risk of hitching their wagon to a single platform.
It's an inherently skewed sample. If you ran that same survey past 15,000 dedicated iOS developers, or dedicated Android or Blackberry or .Net developers, you'd get drastically different results.
In other words, this survey has no value whatsoever except to Accelerator. To them, it's perhaps useful for helping them decide where to devote their resources in the future to keep their clients happy.
But for the world at large? Worthless.
Oh, and what constitutes "betting big" in the context of the article? Well, it's not actually addressed, but their idea of "betting big" doesn't seem to match mine. There's nothing about investments, or exclusive agreements, or anything else that involves any sort of risk whatsoever. Developers were just asked things like "how interested are you in a platform X". The "betting" didn't involve monetary investments, or time investments. These developers did nothing more than state an opinion. An anonymous opinion. Oh… those crazy rebels.
Well, I'm "betting big" that the author of this post is a hack and his soi-disant "expert" is fucking clueless.
Let's face it, nobody knows for sure where the mobile market is headed, and being a Titanium Dev doesn't make your opinion any more informed or valuable than anyone else's. Personally, I suspect Android will continue to grow in market share unless Windows Phone 7 is better than great or else Microsoft manages to one-up Google's relationship with Verizon. But, any way you cut it, this is not a replay of the PC battles. There are too many companies still in the game and who have the potential to grow market share, profit share, or whatever other metric by which you want to judge.
Despite what you may read, there is no clear market leader. Nokia is still in the lead based on total handsets, Blackberry is still in the lead based on smartphone handsets sold, Apple is kicking ass in the profits department, and Android is doing gangbusters in new sales unit, if you lump all the 100+ models of Android phones together and count free phones as sales. Plus, the market is still growing. Apple, for example, didn't increase their market share at all year over year, but they increased their units sold considerably.
Understandably, many people are counting Microsoft out of the mobile game, but I'm not. Though I'm no fan of their technology stack or their approach to business, I think the sheer size of Microsoft's advertising budget, their Enterprise-savvy sales force, and the enormous pool of existing .Net developer talent they can draw on gives them an opportunity for huge inroads. They may not capitalize on it, but it's certainly there and counting Microsoft out of the wireless market would be as foolish as counting Apple out of the game 12 years ago was. And over at HP, lots of money and time is being invested into the Pre platform, which has not been a huge commercial success, but got pretty good grades with many developers who worked with it.
The game's afoot. It's going to be fun to watch, but if you are truly a betting person, this is what you might call a high-risk scenario.
Friday, May 21, 2010
The Illusion of Open
Today, on Twitter, I've been having some back and forth with John Wilker, one of the founders of the 360|iDev Conferences about Android and the concept of "openness". The discussion really helped to clarify some of my thoughts on the matter (thanks, John!).
Now, I've been somewhat harsh on Android at times, but the things I'm harsh about are details and personal programming platform preferences. It's actually a pretty good platform with a huge amount of potential. It now appears to have reached the critical mass needed to really propel it forward, and I do have high hopes that it will keep moving forward, getting better, and pressuring Apple to do even more amazing things than they would have otherwise done.
Yesterday, Google IO ended, and it was clear from the tone of the conference that Google is planning to put up some fierce competition to Apple on several fronts, and that's good. A lot of Google's pitch was focused on this idea of "openness" - that Google's stuff is inherently more "open" (except, of course, the stuff they make money from, but that's a whole separate topic) and therefore better for the user. Tim Bray, Google's Android Evangelist, went off on a rather enthusiastic but somewhat silly Twitter rant a few days ago about openness and the "curated experience" of the iPhone. It's clear that Google sees "openness" as a competitive advantage over Apple and has made it their battle cry in the mobile space.
But, not too long ago, Google announced that it was ending direct sales of their phone, the Nexus One.
Here's the reality of the Android situation now: if you buy an Android phone, it will most likely be locked down by your carrier, possibly also with some features disabled. Or, to use Tim Bray's term, the reality is that most Android phones that get bought are a "curated experience".
In some places, some carriers will sell unlocked phones, but for a great many people, if you want an open Android phone, you will be required to buy one from a carrier and jailbreak it, which is likely a violation of your subscriber agreement. If you don't jailbreak it, you may not get future Android updates. If you buy an Android phone and don't jailbreak it, you might spend the entire life of your phone using the Android version that shipped on it. Your vendor could even charge you a ridiculous monthly fee for the upgrade, something that at least Verizon has considered doing. Even if your carrier does provide updates for free and regularly, there will be a delay as the vendor and provider add all their customizations and restrictions on top of the official Android release.
For the vast majority of people who will buy Android phones, "open" is an illusion because now that Google has abandoned their direct sales model, Android firmly puts the final decision making power for the overall experience of the phone back into the hands of the traditional carrier/vendor relationship that ruled the space before the iPhone came out. Apple, unlike other phone vendors, is capable of going toe-to-toe with the carriers and is willing to do so to fight for a better user experience. That's why we don't have AT&T branding all over our iPhones. That's why we don't have the mandatory 15-second spiel before voicemail that Verizon users have to suffer through. Apple is at least an equal partner with the carriers who sell their phones. Most of the other phone vendors, to put it bluntly, are the carriers' bitches.
Does Android have some nice features that the iPhone doesn't? Absolutely. Is Android improving? No doubt about it and on a regular basis to boot. But, by putting the real power back in the hand of the carriers and their vendor partners, the user experience is never going to be as important in the decision making process as it is for the iPhone. Even if the Android team manages to make the overall experience better than the iPhone (which I consider unlikely, but possible), the carriers will almost certainly screw it up with their ham-handed customizations and restrictions.
If you're going to have a curated experience, isn't it better to at least have one where the curator is making their decisions primarily around the quality of your experience?
Unless Google resumes direct sales or puts licensing limitations on the carriers to prevent them from locking down Android phones, "open" will be just another empty marketing slogan. And I suspect that's what it will be. Google doesn't really care about the user experience, they just want to keep making money on their proprietary, non-open advertising in the mobile space the way they have on the web, and the more Android phones that are out there, the more phones that will be getting Google Ads. Hell, Google even discussed the possibility of unblockable ads at Google IO!
Right. Nothing screams "open" like unblockable advertisements served using proprietary algorithms based on personal data that's been collected about what you do online.
Now, I've been somewhat harsh on Android at times, but the things I'm harsh about are details and personal programming platform preferences. It's actually a pretty good platform with a huge amount of potential. It now appears to have reached the critical mass needed to really propel it forward, and I do have high hopes that it will keep moving forward, getting better, and pressuring Apple to do even more amazing things than they would have otherwise done.
Yesterday, Google IO ended, and it was clear from the tone of the conference that Google is planning to put up some fierce competition to Apple on several fronts, and that's good. A lot of Google's pitch was focused on this idea of "openness" - that Google's stuff is inherently more "open" (except, of course, the stuff they make money from, but that's a whole separate topic) and therefore better for the user. Tim Bray, Google's Android Evangelist, went off on a rather enthusiastic but somewhat silly Twitter rant a few days ago about openness and the "curated experience" of the iPhone. It's clear that Google sees "openness" as a competitive advantage over Apple and has made it their battle cry in the mobile space.
But, not too long ago, Google announced that it was ending direct sales of their phone, the Nexus One.
Here's the reality of the Android situation now: if you buy an Android phone, it will most likely be locked down by your carrier, possibly also with some features disabled. Or, to use Tim Bray's term, the reality is that most Android phones that get bought are a "curated experience".
In some places, some carriers will sell unlocked phones, but for a great many people, if you want an open Android phone, you will be required to buy one from a carrier and jailbreak it, which is likely a violation of your subscriber agreement. If you don't jailbreak it, you may not get future Android updates. If you buy an Android phone and don't jailbreak it, you might spend the entire life of your phone using the Android version that shipped on it. Your vendor could even charge you a ridiculous monthly fee for the upgrade, something that at least Verizon has considered doing. Even if your carrier does provide updates for free and regularly, there will be a delay as the vendor and provider add all their customizations and restrictions on top of the official Android release.
For the vast majority of people who will buy Android phones, "open" is an illusion because now that Google has abandoned their direct sales model, Android firmly puts the final decision making power for the overall experience of the phone back into the hands of the traditional carrier/vendor relationship that ruled the space before the iPhone came out. Apple, unlike other phone vendors, is capable of going toe-to-toe with the carriers and is willing to do so to fight for a better user experience. That's why we don't have AT&T branding all over our iPhones. That's why we don't have the mandatory 15-second spiel before voicemail that Verizon users have to suffer through. Apple is at least an equal partner with the carriers who sell their phones. Most of the other phone vendors, to put it bluntly, are the carriers' bitches.
Does Android have some nice features that the iPhone doesn't? Absolutely. Is Android improving? No doubt about it and on a regular basis to boot. But, by putting the real power back in the hand of the carriers and their vendor partners, the user experience is never going to be as important in the decision making process as it is for the iPhone. Even if the Android team manages to make the overall experience better than the iPhone (which I consider unlikely, but possible), the carriers will almost certainly screw it up with their ham-handed customizations and restrictions.
If you're going to have a curated experience, isn't it better to at least have one where the curator is making their decisions primarily around the quality of your experience?
Unless Google resumes direct sales or puts licensing limitations on the carriers to prevent them from locking down Android phones, "open" will be just another empty marketing slogan. And I suspect that's what it will be. Google doesn't really care about the user experience, they just want to keep making money on their proprietary, non-open advertising in the mobile space the way they have on the web, and the more Android phones that are out there, the more phones that will be getting Google Ads. Hell, Google even discussed the possibility of unblockable ads at Google IO!
Right. Nothing screams "open" like unblockable advertisements served using proprietary algorithms based on personal data that's been collected about what you do online.
Friday, December 18, 2009
Holy Cow - 78 Million iPhone OS Devices‽
According to one analyst, at least, we are on the cusp of 78 million iPhone OS devices in existence.
It wasn't that long ago that I was startled by the fact that there were 55 million devices. Another 23 million devices in just a few months strikes me as a lot of sales, even for the iPhone.
Anyway, just thought I'd share. This may be my last post for a few days. I've come down with the flu, or at least some very nasty flu-like illness. I've been sleeping away the last couple of days (apologies to anyone who has e-mailed, tweeted, or phoned, I'm not even going to try and catch up until Monday). Combine that with the holidays and everything they entail, and I may not have much time for posting over the next week.
If I don't have a chance to say it, happy Christmas / Kwanzaa / Chanukah/ New Year / Bill of Rights Day / Forefather's Day / Maritime Day / Winter Solstice / Boxing Day and any other holiday I might have missed there..
It wasn't that long ago that I was startled by the fact that there were 55 million devices. Another 23 million devices in just a few months strikes me as a lot of sales, even for the iPhone.
Anyway, just thought I'd share. This may be my last post for a few days. I've come down with the flu, or at least some very nasty flu-like illness. I've been sleeping away the last couple of days (apologies to anyone who has e-mailed, tweeted, or phoned, I'm not even going to try and catch up until Monday). Combine that with the holidays and everything they entail, and I may not have much time for posting over the next week.
If I don't have a chance to say it, happy Christmas / Kwanzaa / Chanukah/ New Year / Bill of Rights Day / Forefather's Day / Maritime Day / Winter Solstice / Boxing Day and any other holiday I might have missed there..
Thursday, October 22, 2009
Patent Lawsuits: the Last Resort of the Mediocre
Nokia today announced they are suing Apple . Right in the press release, Nokia states that they are suing over patents that cover implementations of standards (GSM, WCDMA, WLAN, UMTS).
WTF? That kind of misses the point of having an open standard in the first place. There's only so much difference between different implementations of the same protocol or standard. Jeebus! The problem with these cases, though, is that the judges are experts in law, but not in technology, so they rarely have the knowledge and/or cojones to issue summary judgment even in cases with no merits. Like this one. So, Nokia will, at very least, cause Apple to spend millions of dollars to defend themselve.
Apple's release of the iPhone pretty much meant I'd never buy another Nokia phone again for myself, but now I will actively avoid their products. I won't recommend them to others and I won't buy them for family members. If this is how they hope to succeed in the future, I hope Nokia dies a quick and painful corporate death.
WTF? That kind of misses the point of having an open standard in the first place. There's only so much difference between different implementations of the same protocol or standard. Jeebus! The problem with these cases, though, is that the judges are experts in law, but not in technology, so they rarely have the knowledge and/or cojones to issue summary judgment even in cases with no merits. Like this one. So, Nokia will, at very least, cause Apple to spend millions of dollars to defend themselve.
Apple's release of the iPhone pretty much meant I'd never buy another Nokia phone again for myself, but now I will actively avoid their products. I won't recommend them to others and I won't buy them for family members. If this is how they hope to succeed in the future, I hope Nokia dies a quick and painful corporate death.
Wednesday, September 16, 2009
Multi Core Mobile Chip
It looks like the rumors of a multi-core mobile chip are actually well-founded. Boy, would something like this make for a jaw-dropping future iPhone model that would give us a real need for blocks and GCD.
from Bill Dudney
from Bill Dudney
Monday, July 6, 2009
Wireless Carriers the Great Train Robbers of this Millenia
I generally avoid chiming in with the whole "AT&T Sucks" chorus. Over the last fifteen years, I've had five different wireless carriers, and though AT&T isn't the best, they are far from the worst (which was MCI/WorldCom if you were wondering). They all suck, but some suck more than others and it's not like we have much in the way of options. We're a captive audience (especially iPhone users), so just like how you pay more for food at a baseball stadium or in a theme park, I actually expect to get gouged some for having an iPhone. I don't like it, but there's no sense pissing in the wind. If I hate them too much, I always have the option of choosing another phone. I don't hate them nearly that much.
But, I got my first bill since upgrading to the 3Gs, though, and found a few surprises and a few things I didn't understand in my bill, so I called AT&T for clarification.
Now, it appears that there were no mistakes in my bill, and the customer support representative was very nice and really was trying to help me out, but I kept finding the explanations about what things were kind of vague and just not clear to me. I didn't want to be a jerk to the lady on the phone, but I just wanted a clear explanation of the "Other Charges/Deductions" line items and kept asking her to lay them out in plain english rather than reading the intentionally vague explanation from her script.
There were, for example, these things called "Regulatory Cost Recovery Fee" and "Federal Universal Service Charge", which prompted the question from me "why aren't these under the section for surcharges and taxes.
The response was that these aren't mandated fees. These aren't required by any state or federal body at all. These represent money that stays in AT&T's coffers.
So, what are they?
In a nutshell? They are amounts that AT&T, in their sole discretion, is allowed to tack on to the bill to defray the cost of certain things. The "Regulatory Cost Recovery Fee", for example, is a fee they tack on to defray the expense of complying with state and federal regulations. The "Federal Universal Service Charge" is one they tack on to help with the cost of maintaining cell towers and other infrastructure.
Now, there's no documentation about exactly what costs are being defrayed and, as far as I can tell, not much accountability to the consumer on these. Sure, there are regulations about what they can include in these items, but there doesn't seem to be a requirement that they itemize or explain the charge, or how they arrived at the amount, to the consumer. Basically, these line items can be used to arbitrarily and randomly increase their income. If you multiply those charges (over $5 for me this month) by the millions of customers, it comes out to a fairly substantial amount of money.
This irks me in the same way that "fuel surcharge" by an airline or package delivery service or an "airport recovery fee" from a rental car does. Complying with federal regulations, fuel, and leasing space in an airport are all fucking operating expenses. They should be factored into the price of the product or service, not tacked on after you've agreed to the purchase based on the artificially low price that doesn't include random operating costs. When you hide the true cost in "recovery fees" and "surcharges", you make it impossible for the consumer to know what their actual real bill will be and impossible to intelligently compare competing products or services.
Wouldn't it be nice if you could do this with your paycheck? "Hey, Boss? Yeah, the head gasket on my car blew this month, you have to pay me extra this month as an 'Employee Transportation Recovery Cost'."
So, let me just break from tradition and chime in with one big "Fuck You, AT&T" to make myself feel better. The second the iPhone is available from another carrier in the U.S., I am kicking their ass to the curb. The next carrier may not be any better, but maybe if there's a mass exodus from AT&T when the iPhone is no longer exclusive they will consider changing their ways. Not likely, but the power to take our money elsewhere is the only power a consumer really has.
And now that I've said that, let me take a step back and say that AT&T is not the real culprit here. If you give a corporation the option of tacking on an additional fee that doesn't have to be advertised in the cost of their product or service or explained to the customer, they will use it, and almost certainly at times abuse it. Corporations are soulless entities that exist for a single reason: to make a profit. Individuals are motivated by other intangible things, such as "pride in craftsmanship" and "common decency", but those things are meaningless to a large corporation.
The real problem is the incompetent and mostly unnecessary FCC, which has become little more than Big Business's bitch. It's certainly not responsive to the taxpayers, but it is responsive to the big media and communication corporations. Sure, they occasionally waste taxpayer money "guarding the airways" against anything that might offend small-minded people in middle America, but their real mandate seems to be to help big media corporations make more money at the expense of the people who pay taxes to fund them. If the FCC's regulations were really designed to help the consumer, wireless providers would be forced to have a pricing model without inherent surprises and without intentionally planned nooks and crannies specifically designed to let the carriers steal extra profit. If you made a contract with a wireless carrier for $50 a month, you'd pay $50 a month plus, maybe, sales tax.
But, rather than say "Fuck you, FCC" in my own crass way, I'll let the far more eloquent Eric Idle say it in a moderately dated, but still very funny way:
But, I got my first bill since upgrading to the 3Gs, though, and found a few surprises and a few things I didn't understand in my bill, so I called AT&T for clarification.
Now, it appears that there were no mistakes in my bill, and the customer support representative was very nice and really was trying to help me out, but I kept finding the explanations about what things were kind of vague and just not clear to me. I didn't want to be a jerk to the lady on the phone, but I just wanted a clear explanation of the "Other Charges/Deductions" line items and kept asking her to lay them out in plain english rather than reading the intentionally vague explanation from her script.
There were, for example, these things called "Regulatory Cost Recovery Fee" and "Federal Universal Service Charge", which prompted the question from me "why aren't these under the section for surcharges and taxes.
The response was that these aren't mandated fees. These aren't required by any state or federal body at all. These represent money that stays in AT&T's coffers.
So, what are they?
In a nutshell? They are amounts that AT&T, in their sole discretion, is allowed to tack on to the bill to defray the cost of certain things. The "Regulatory Cost Recovery Fee", for example, is a fee they tack on to defray the expense of complying with state and federal regulations. The "Federal Universal Service Charge" is one they tack on to help with the cost of maintaining cell towers and other infrastructure.
Now, there's no documentation about exactly what costs are being defrayed and, as far as I can tell, not much accountability to the consumer on these. Sure, there are regulations about what they can include in these items, but there doesn't seem to be a requirement that they itemize or explain the charge, or how they arrived at the amount, to the consumer. Basically, these line items can be used to arbitrarily and randomly increase their income. If you multiply those charges (over $5 for me this month) by the millions of customers, it comes out to a fairly substantial amount of money.
This irks me in the same way that "fuel surcharge" by an airline or package delivery service or an "airport recovery fee" from a rental car does. Complying with federal regulations, fuel, and leasing space in an airport are all fucking operating expenses. They should be factored into the price of the product or service, not tacked on after you've agreed to the purchase based on the artificially low price that doesn't include random operating costs. When you hide the true cost in "recovery fees" and "surcharges", you make it impossible for the consumer to know what their actual real bill will be and impossible to intelligently compare competing products or services.
Wouldn't it be nice if you could do this with your paycheck? "Hey, Boss? Yeah, the head gasket on my car blew this month, you have to pay me extra this month as an 'Employee Transportation Recovery Cost'."
So, let me just break from tradition and chime in with one big "Fuck You, AT&T" to make myself feel better. The second the iPhone is available from another carrier in the U.S., I am kicking their ass to the curb. The next carrier may not be any better, but maybe if there's a mass exodus from AT&T when the iPhone is no longer exclusive they will consider changing their ways. Not likely, but the power to take our money elsewhere is the only power a consumer really has.
And now that I've said that, let me take a step back and say that AT&T is not the real culprit here. If you give a corporation the option of tacking on an additional fee that doesn't have to be advertised in the cost of their product or service or explained to the customer, they will use it, and almost certainly at times abuse it. Corporations are soulless entities that exist for a single reason: to make a profit. Individuals are motivated by other intangible things, such as "pride in craftsmanship" and "common decency", but those things are meaningless to a large corporation.
The real problem is the incompetent and mostly unnecessary FCC, which has become little more than Big Business's bitch. It's certainly not responsive to the taxpayers, but it is responsive to the big media and communication corporations. Sure, they occasionally waste taxpayer money "guarding the airways" against anything that might offend small-minded people in middle America, but their real mandate seems to be to help big media corporations make more money at the expense of the people who pay taxes to fund them. If the FCC's regulations were really designed to help the consumer, wireless providers would be forced to have a pricing model without inherent surprises and without intentionally planned nooks and crannies specifically designed to let the carriers steal extra profit. If you made a contract with a wireless carrier for $50 a month, you'd pay $50 a month plus, maybe, sales tax.
But, rather than say "Fuck you, FCC" in my own crass way, I'll let the far more eloquent Eric Idle say it in a moderately dated, but still very funny way:
Tuesday, November 11, 2008
If you're in the Bay Area
Just spotted this on Scott Stevensons blog: this month's CocoaHeads meeting will have a special treat. Apple's Evangelist for Developer and Performance Tools, Michael Jurewitz, who is also the man behind Apple's iPhone Tech Talks, is going to give an "Introduction to iPhone Development" presentation.
Note that they are not meeting at their normal location, they're at Intuit in Mountain View this month.
Note that they are not meeting at their normal location, they're at Intuit in Mountain View this month.
Sunday, November 2, 2008
Interesting Blog
Here's an interesting idea: Two fellows who are developing iPhone games are going to do so with a completely transparent process - they are going to document their expenses, time spent, and income on a regular basis on their blog.
It's an interesting read, especially recommended for game developers and wannabe game developers:
Here's the link.
It's an interesting read, especially recommended for game developers and wannabe game developers:
Here's the link.
Wednesday, October 29, 2008
500%
I didn't run the press release yesterday, but apparently other bloggers took the bait. Basically, this company called "oDesk" (which I had never heard of before receiving their press release) claims that the demand for iPhone Developers is up 500% in six months.
Of course, this is based on "internal data" with a sampling size that is admittedly too small to be valid. Besides, six months ago, the SDK wasn't even stable and you couldn't distribute apps yet. It was the era of first-wavers, and with the exception of a few large companies that Apple got on board with them, most of the first-wavers were individuals and small Mac development shops.
Now with huge App Store success stories running rampant and general consensus being that the App Store is a runaway success (albeit with few hiccups along the way), of course everyone wants in! There's gold in them thar hills! It's no longer risky to jump into the fray. Those of us who saw the opportunity for what it is from the start and jumped in with both feet (in my case, turning my back on a client-base I had been developing for almost a decade in the process) got a head start because we took a chance. We trusted our judgment and jumped.
Now, all this press release really says is that some johnny-com-lately company has realized we were right and wants to cash-in on that missed opportunity. And though the numbers look good on the surface (or would if they were statistically valid), crap like this actually sucks for our platform. This is the kind of things that college and high-school students read and say "Oh, I want to be an iPhone developer". And, of course, most of them don't want to be an iPhone developer because they love tinkering or programming or problem solving. They want to be an iPhone developer because they envision themselves making big bucks with little effort, spending their days sitting in hot tubs with playmates, driving expensive cars, and otherwise living the high life.
(Just for the record, that is not the life of any iPhone developer I know, except maybe Wil Shipley, but I only know him by reputation.)
It's like those Microsoft Certified Training programs with the radio ads that promise to take somebody who doesn't know jack shit about computers and in six weeks turn them into a "certified" guru who can handle any job that needs to be handled.All this shit floods the market with people who don't know their ass from a hole in the ground. It drives up rates in the short term and causes them to crash in the long run, and it makes it miserably hard for companies to find developers who knows what they're doing unless they happen to already have somebody who's technically knowledgeable about the SDK who can weed out the chaff.
I guess it's inevitable. Success attracts. And, in the long run, it's probably good for the platform, but there's going to be some rough times ahead as a result. I wish success only attracted the right people and for the right reasons.
Of course, this is based on "internal data" with a sampling size that is admittedly too small to be valid. Besides, six months ago, the SDK wasn't even stable and you couldn't distribute apps yet. It was the era of first-wavers, and with the exception of a few large companies that Apple got on board with them, most of the first-wavers were individuals and small Mac development shops.
Now with huge App Store success stories running rampant and general consensus being that the App Store is a runaway success (albeit with few hiccups along the way), of course everyone wants in! There's gold in them thar hills! It's no longer risky to jump into the fray. Those of us who saw the opportunity for what it is from the start and jumped in with both feet (in my case, turning my back on a client-base I had been developing for almost a decade in the process) got a head start because we took a chance. We trusted our judgment and jumped.
Now, all this press release really says is that some johnny-com-lately company has realized we were right and wants to cash-in on that missed opportunity. And though the numbers look good on the surface (or would if they were statistically valid), crap like this actually sucks for our platform. This is the kind of things that college and high-school students read and say "Oh, I want to be an iPhone developer". And, of course, most of them don't want to be an iPhone developer because they love tinkering or programming or problem solving. They want to be an iPhone developer because they envision themselves making big bucks with little effort, spending their days sitting in hot tubs with playmates, driving expensive cars, and otherwise living the high life.
(Just for the record, that is not the life of any iPhone developer I know, except maybe Wil Shipley, but I only know him by reputation.)
It's like those Microsoft Certified Training programs with the radio ads that promise to take somebody who doesn't know jack shit about computers and in six weeks turn them into a "certified" guru who can handle any job that needs to be handled.All this shit floods the market with people who don't know their ass from a hole in the ground. It drives up rates in the short term and causes them to crash in the long run, and it makes it miserably hard for companies to find developers who knows what they're doing unless they happen to already have somebody who's technically knowledgeable about the SDK who can weed out the chaff.
I guess it's inevitable. Success attracts. And, in the long run, it's probably good for the platform, but there's going to be some rough times ahead as a result. I wish success only attracted the right people and for the right reasons.
Friday, October 24, 2008
Captain Obvious Strikes Again
In the Xcode editor pane (the part of the window where your source code is displayed), you can option-double-click any term to search for it in the Documentation Browser. You can also command-double-click any term to open up its definition in the public header files.
That is all.
That is all.
Wednesday, October 22, 2008
You Shouldn't, but You Will...
Class-Dump is an essential tool in the Cocoa Programmer's arsenal. It will read a compiled Objective-C binary and print out the header files for all classes used in that file. Depending on the settings used to compile, it may not have the correct variable names, but it will have the correct method signatures, even those that are not declared in the public headers.
Now, for the iPhone, we can't use Class-Dump, because it doesn't recognize binaries compiled for the ARM6 processor. Additionally, we shouldn't use it, because it means we're poking around in private stuff that could get our Application banned from the App Store.
But, for the curious, I thought I'd point out that you can actually use Class-Dump on iPhone frameworks; you just have to run it on the framework that's in the SDK for the simulator rather than the device. The iPhone simulator is NOT an emulator.. it's not running ARM6 byte codes, it's running X86 byte codes (except for those naughty people who installed the SDK on a PPC Mac).
So, want to see the headers from the UIKit in all their glory?
But, shhhh.... You didn't learn it from me.
Now, for the iPhone, we can't use Class-Dump, because it doesn't recognize binaries compiled for the ARM6 processor. Additionally, we shouldn't use it, because it means we're poking around in private stuff that could get our Application banned from the App Store.
But, for the curious, I thought I'd point out that you can actually use Class-Dump on iPhone frameworks; you just have to run it on the framework that's in the SDK for the simulator rather than the device. The iPhone simulator is NOT an emulator.. it's not running ARM6 byte codes, it's running X86 byte codes (except for those naughty people who installed the SDK on a PPC Mac).
So, want to see the headers from the UIKit in all their glory?
cd /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.1.sdk/System/Library/Frameworks/UIKit.framework
class-dump UIKit > ~/Desktop/UIKit.txt
But, shhhh.... You didn't learn it from me.
Tuesday, October 21, 2008
Idle Timer
If you're making a game, please, please, please remember to turn off the idle timer. The Force Unleashed, a big-budget game loosely modeled after the console game of the same name, is a moderately fun, very polished game, but the screen constantly dims during the game in cutscenes and other places where you're not touching the screen for a while.
C'mon, folks: it's one line of code. Use it.
C'mon, folks: it's one line of code. Use it.
[UIApplication sharedApplication].isIdleTimerDisabled = YES;
Monday, October 20, 2008
Device vs. Simulator
The iPhone Simulator is a really cool piece of software. Although I do most of my development testing on an iPhone or iPod Touch, I really like having the option to run code when I don't have a device handy. It's a really cool piece of technology.
Sometimes, it can be downright annoying, though. Today, I hit an example of that. I'm working on a project that needs to run on both the Mac and the iPhone, and it does a fair bit of mucking around in the runtime. I've written programs using for both the Mac and the iPhone with no problems, but periodically would get e-mail from someone asking if I could make it work for the iPhone.
Well, it turns out *blush*... I must have never actually tested the code on an iPhone or iPod Touch, and only used this particular code in the simulator and on the Mac. You see, I have this line of code:
And that code works just fine and dandy for the Mac, and for the iPhone Simulator. But, guess what? obj/objc-runtime.h doesn't seem to exist in the iPhone SDK, so when you switch the SDK to the device and then compile, the build goes down in a blaze of gory (no, not glory, gory... it's ugly).
Fixing it was relatively trivial once I found the problem. The file objc/objc-runtime.h is a very simple header file. Here is what it looks like on the Mac:
That's it. And both of those files do exist for the device SDK. So, I simply replaced the one #import <objc/objc-runtime.h> statement with the two #import statements it contained, and voilá, it started working again. Mostly.
It compiled with no errors, but I got a whole bunch of warnings, all centered around the use of two methods it couldn't find: -className and +className. These methods do nothing more than return the name of the class, one is implemented as an instance method, the other as a class method. I have no idea why these two methods don't exist for the device SDK, but this was also easy enough to fix, since the class name is available through runtime calls.
I added the two methods, but wrapped the code in a pre-compiler conditional statement so it only gets used when compiling for the iPhone:
So, in the header file:
Currently, this resides on the class where I needed it, but I'm going to move it into a category on NSObject. The implementation of these two methods is nearly as short:
And that's all for today, I'm going to bed.
Sometimes, it can be downright annoying, though. Today, I hit an example of that. I'm working on a project that needs to run on both the Mac and the iPhone, and it does a fair bit of mucking around in the runtime. I've written programs using for both the Mac and the iPhone with no problems, but periodically would get e-mail from someone asking if I could make it work for the iPhone.
Well, it turns out *blush*... I must have never actually tested the code on an iPhone or iPod Touch, and only used this particular code in the simulator and on the Mac. You see, I have this line of code:
#import <objc/objc-runtime.h>
And that code works just fine and dandy for the Mac, and for the iPhone Simulator. But, guess what? obj/objc-runtime.h doesn't seem to exist in the iPhone SDK, so when you switch the SDK to the device and then compile, the build goes down in a blaze of gory (no, not glory, gory... it's ugly).
Fixing it was relatively trivial once I found the problem. The file objc/objc-runtime.h is a very simple header file. Here is what it looks like on the Mac:
#import <objc/runtime.h>
#import <objc/message.h>
That's it. And both of those files do exist for the device SDK. So, I simply replaced the one #import <objc/objc-runtime.h> statement with the two #import statements it contained, and voilá, it started working again. Mostly.
It compiled with no errors, but I got a whole bunch of warnings, all centered around the use of two methods it couldn't find: -className and +className. These methods do nothing more than return the name of the class, one is implemented as an instance method, the other as a class method. I have no idea why these two methods don't exist for the device SDK, but this was also easy enough to fix, since the class name is available through runtime calls.
I added the two methods, but wrapped the code in a pre-compiler conditional statement so it only gets used when compiling for the iPhone:
So, in the header file:
#if (TARGET_OS_IPHONE)
- (NSString *)className;
+ (NSString *)className;
#endif
Currently, this resides on the class where I needed it, but I'm going to move it into a category on NSObject. The implementation of these two methods is nearly as short:
#if (TARGET_OS_IPHONE)
- (NSString *)className
{
return [NSString stringWithUTF8String:class_getName([self class])];
}
+ (NSString *)className
{
return [NSString stringWithUTF8String:class_getName(self)];
}
#endif
And that's all for today, I'm going to bed.
Another Couple of Tips by Captain Obvious
The iPhone SDK is so large, it's easy to miss things that other people think are obvious. Because of that, I'm going to post another tip that most people probably know already, but that some people might now.
If you create a PNG file of size 320x480 and call it "Default.png" (spelled exactly that way, making sure you have the first letter capitalized), you can then add that image to your Xcode project's Resources group and it will act sort of like a splash screen for our application - it will show that image until your application is fully loaded.
Although I'm not a big fan of splash screens, it's a good idea if you've got a slow-loading application to let the user know everything is proceeding okay. If you've got a slow-loading application, and you don't know why, it may be because you have a lot of resources in your project. The iPhone seems to do some kind of check on application launch, and the more individual files you have in your application bundle, the longer it takes. The actual size of the files doesn't seem to matter, but the number of files definitely does. If you're in this situation, consider reducing the number of files in your bundle somehow. A fairly easy way to do that is to store all those files as blobs inside a single SQLite database. You can use a read-only database from your bundle without copying it to the Documents folder, but you must make sure not to write to it, because if you change anything in your application bundle, code signing for the application will stop working and the user will not be able to launch it again. You can use a separate SQLite database in your application's Documents folder for user data.
If you create a PNG file of size 320x480 and call it "Default.png" (spelled exactly that way, making sure you have the first letter capitalized), you can then add that image to your Xcode project's Resources group and it will act sort of like a splash screen for our application - it will show that image until your application is fully loaded.
Although I'm not a big fan of splash screens, it's a good idea if you've got a slow-loading application to let the user know everything is proceeding okay. If you've got a slow-loading application, and you don't know why, it may be because you have a lot of resources in your project. The iPhone seems to do some kind of check on application launch, and the more individual files you have in your application bundle, the longer it takes. The actual size of the files doesn't seem to matter, but the number of files definitely does. If you're in this situation, consider reducing the number of files in your bundle somehow. A fairly easy way to do that is to store all those files as blobs inside a single SQLite database. You can use a read-only database from your bundle without copying it to the Documents folder, but you must make sure not to write to it, because if you change anything in your application bundle, code signing for the application will stop working and the user will not be able to launch it again. You can use a separate SQLite database in your application's Documents folder for user data.
iPhone "Optimized" PNGs
For the most part, Apple's developer documentation for both the Mac and iPhone is excellent. They are well-written, accurate, and provide excellent code samples. There are, of course, always gaps, especially with newer areas. Sometimes these gaps are simply a matter of resource constraints; the volume of documentation the documentation teams have to maintain is staggering, and frameworks are constantly being added and updated.
At other times, Apple is tight-lipped about stuff not because of resource constraints, but rather intentionally, though it's not always clear why. Do you want to know how fast the processor in your iPhone is, or how much memory is available to your application? Both of these are obviously relevant to developing for the iPhone, but don't look to Apple for that information. The information is available (processor | memory), just not from Apple.
Here's another area where Apple is less than fully forthcoming: When it comes to the iPhone's use of PNG images, Apple tells you that Xcode "optimizes" PNGs as part of the build process and, as a result, you should always use PNG images in your iPhone projects. PNG images will usually be bigger than JPEGs, causing your application to be a little larger, but you'll be rewarded by some mysterious kind of improvement.
Since this information is not documented, what follows is something of an educated guess based on research and observations. I will gladly be corrected on any inaccuracies, so don't hesitate to ping me if you see something wrong.
During the build, Xcode basically screws up your PNG image, turning it into something that's technically no longer a PNG image. Xcode doesn't change your original file, but when it copies it to the Resources folder of your application bundle, what it does is it byte-swaps the red and blue octets and also "premultiplies the alpha" (if that doesn't make sense, don't worry, we'll talk about it in a moment). The PNG specification does not support either of these changes, which is why the image is no longer technically a PNG and can't be loaded by most image editing software. Not that it really matters, since the new version only exists inside your application bundle, but it does mean that any PNG file that you include in your app bundle should not be, for example, FTPed or e-mailed from your application directly, because the file will be corrupt as far as most software is concerned.
Byte swapping is exactly what it sounds like. Uncompressed computer graphic images are most-often stored as sequences of three or four bytes or "octets" representing each pixel in the image. Each byte in the pixel represents one of the three additive primaries (red, blue, and green), plus there's often another byte called "alpha", which we'll look at in a moment. There are other ways to store images, but this is the most common technique. The most common byte-ordering used in this technique is RGB (or RGBA) which stands for Red-Green-Blue(-Alpha). This means that a single pixel is represented in memory by four bytes, the first representing the intensity of red, the second representing the intensity of green, and the third representing the intensity of blue (we'll ignore alpha for now). The PNG specification uses this byte-ordering, as do many other image formats.
However, the iPhone's video memory uses a non-standard byte-ordering of BGR or Blue-Green-Red (I don't believe there's an alpha component in the iPhone's vRAM). In order to copy from an image in memory using RGBA to the video memory using GRB is more computationally expensive than just copying from, for example, BGR to BGR, which can be done with a single, fast memory move (or "blit") operation. By doing this byte-swap in the Copy Files Build Phase, your application is (in some situations) able to ignore the alpha component when loading the file into memory so it can use the faster memory move operation to get the image into video memory (and hence onto the screen).
Okay, that makes sense, but what about this "premultiplying the alpha" thing? That one sounds kind of mysterious, doesn't it? As mentioned in the previous section, the iPhone's vRAM has no alpha component, so if we're going to ignore that component, we still need to take it into account somehow. Remember that PNG Images that have been optimized for the iPhone are stored as four values, representing the Blue, Green, Red, and Alpha components (in that order). Although it's called a "component", Alpha isn't really a color component at all. It's more like a modifier that acts on the other three values, and it represents how much of whatever is beneath the color will show through. So, a color that looked like this:
Would represent the color blue, but at 50% opacity. In order for the computer to use the alpha component, it has to multiply the alpha times the other three components (and possibly by other values) before putting them into video memory. This multiplication process is more computationally expensive than just copying the value into video memory. So, Xcode also premultiplies the alpha by the three components and stores the multiplied value. As a result, the color above would look like this after the Copy Files Build Phase:
Notice that the Blue component in this new pixel is equal to the Blue component of the previous version multiplied by the alpha. The result of this premultiplication, is that the alpha component can be ignored when loading the image into memory and the image can then be blitted directly to video memory without having to do the expensive floating-point multiplications to calculate the alpha. Well, at least, sometimes. This pixel is what the pixel would look like when drawn over white.
So, what happens if there's a color beneath that needs to show through? This is where things can get a little confusing. If your application is drawing the image on top of something else, or if you're using the alpha channel in the image as a mask, then the iPhone can't use this optimization. It has to do the alpha calculations (which is why the alpha channel is left intact in the pre-multiplication process), the the byte-swapping still offers some improvement. For the most part, you don't have to worry about this - it all happens under the hood. The thing you should take away from it though, is that you can help your iPhone know when it is safe to use the optimization. The way to do that is to make sure you check the "opaque" checkbox in Interface Builder for your image views, or other views that contain images, or set the opaque property of your UIImageView to YES in code. This tells the iPhone that it's safe to do the faster blit operation and ignore the alpha channel because nothing below shows through an opaque object and there's no need to do any expensive floating point alpha calculations for that object. Of course, if you are using the alpha channel in your image, or if you are doing complex image compositions in your app at run-time, you shouldn't make the view opaque. But, if you're just displaying an image in an UIImageView, checking that opaque checkbox is a really, really good idea.
An awful lot of the time, PNG images have 1.0 for the Alpha value in every pixel. As a result, more often than not, program runs faster and use less memory because of the PNG "optimizations" done by Xcode.
When you use any other file type (or if you load a non-optimized PNG files), your iPhone has to do the byte-swapping and alpha premultiplication at load-time (and possibly re-do the alpha multiplication at display time). Your application basically has to do the same processing that Xcode does, but it's doing it at run-time instead of at build-time. This is going to cost you both in terms of processor cycles and memory overhead. One of the reasons why Mobile Safari is the biggest memory hog of the built-in iPhone applications is because the images it has to load in order to display web-pages are all non-optimized images, mostly JPEGs. Since JPEG is a compressed format, it has the added extra step of having to decompress the image into memory before it can do the premultiplication and byte-swapping.
At other times, Apple is tight-lipped about stuff not because of resource constraints, but rather intentionally, though it's not always clear why. Do you want to know how fast the processor in your iPhone is, or how much memory is available to your application? Both of these are obviously relevant to developing for the iPhone, but don't look to Apple for that information. The information is available (processor | memory), just not from Apple.
Here's another area where Apple is less than fully forthcoming: When it comes to the iPhone's use of PNG images, Apple tells you that Xcode "optimizes" PNGs as part of the build process and, as a result, you should always use PNG images in your iPhone projects. PNG images will usually be bigger than JPEGs, causing your application to be a little larger, but you'll be rewarded by some mysterious kind of improvement.
Since this information is not documented, what follows is something of an educated guess based on research and observations. I will gladly be corrected on any inaccuracies, so don't hesitate to ping me if you see something wrong.
So, just what is this magical, mystery "optimization"?
During the build, Xcode basically screws up your PNG image, turning it into something that's technically no longer a PNG image. Xcode doesn't change your original file, but when it copies it to the Resources folder of your application bundle, what it does is it byte-swaps the red and blue octets and also "premultiplies the alpha" (if that doesn't make sense, don't worry, we'll talk about it in a moment). The PNG specification does not support either of these changes, which is why the image is no longer technically a PNG and can't be loaded by most image editing software. Not that it really matters, since the new version only exists inside your application bundle, but it does mean that any PNG file that you include in your app bundle should not be, for example, FTPed or e-mailed from your application directly, because the file will be corrupt as far as most software is concerned.
Byte Swapping
Byte swapping is exactly what it sounds like. Uncompressed computer graphic images are most-often stored as sequences of three or four bytes or "octets" representing each pixel in the image. Each byte in the pixel represents one of the three additive primaries (red, blue, and green), plus there's often another byte called "alpha", which we'll look at in a moment. There are other ways to store images, but this is the most common technique. The most common byte-ordering used in this technique is RGB (or RGBA) which stands for Red-Green-Blue(-Alpha). This means that a single pixel is represented in memory by four bytes, the first representing the intensity of red, the second representing the intensity of green, and the third representing the intensity of blue (we'll ignore alpha for now). The PNG specification uses this byte-ordering, as do many other image formats.
However, the iPhone's video memory uses a non-standard byte-ordering of BGR or Blue-Green-Red (I don't believe there's an alpha component in the iPhone's vRAM). In order to copy from an image in memory using RGBA to the video memory using GRB is more computationally expensive than just copying from, for example, BGR to BGR, which can be done with a single, fast memory move (or "blit") operation. By doing this byte-swap in the Copy Files Build Phase, your application is (in some situations) able to ignore the alpha component when loading the file into memory so it can use the faster memory move operation to get the image into video memory (and hence onto the screen).
Premultiplied Alpha
Okay, that makes sense, but what about this "premultiplying the alpha" thing? That one sounds kind of mysterious, doesn't it? As mentioned in the previous section, the iPhone's vRAM has no alpha component, so if we're going to ignore that component, we still need to take it into account somehow. Remember that PNG Images that have been optimized for the iPhone are stored as four values, representing the Blue, Green, Red, and Alpha components (in that order). Although it's called a "component", Alpha isn't really a color component at all. It's more like a modifier that acts on the other three values, and it represents how much of whatever is beneath the color will show through. So, a color that looked like this:
B:1.0
G:0.0
R:0.0
A:0.5
Would represent the color blue, but at 50% opacity. In order for the computer to use the alpha component, it has to multiply the alpha times the other three components (and possibly by other values) before putting them into video memory. This multiplication process is more computationally expensive than just copying the value into video memory. So, Xcode also premultiplies the alpha by the three components and stores the multiplied value. As a result, the color above would look like this after the Copy Files Build Phase:
B:0.5
G:0.0
R:0.0
A:0.5
Notice that the Blue component in this new pixel is equal to the Blue component of the previous version multiplied by the alpha. The result of this premultiplication, is that the alpha component can be ignored when loading the image into memory and the image can then be blitted directly to video memory without having to do the expensive floating-point multiplications to calculate the alpha. Well, at least, sometimes. This pixel is what the pixel would look like when drawn over white.
So, what happens if there's a color beneath that needs to show through? This is where things can get a little confusing. If your application is drawing the image on top of something else, or if you're using the alpha channel in the image as a mask, then the iPhone can't use this optimization. It has to do the alpha calculations (which is why the alpha channel is left intact in the pre-multiplication process), the the byte-swapping still offers some improvement. For the most part, you don't have to worry about this - it all happens under the hood. The thing you should take away from it though, is that you can help your iPhone know when it is safe to use the optimization. The way to do that is to make sure you check the "opaque" checkbox in Interface Builder for your image views, or other views that contain images, or set the opaque property of your UIImageView to YES in code. This tells the iPhone that it's safe to do the faster blit operation and ignore the alpha channel because nothing below shows through an opaque object and there's no need to do any expensive floating point alpha calculations for that object. Of course, if you are using the alpha channel in your image, or if you are doing complex image compositions in your app at run-time, you shouldn't make the view opaque. But, if you're just displaying an image in an UIImageView, checking that opaque checkbox is a really, really good idea.
An awful lot of the time, PNG images have 1.0 for the Alpha value in every pixel. As a result, more often than not, program runs faster and use less memory because of the PNG "optimizations" done by Xcode.
What happens when you use different file types
When you use any other file type (or if you load a non-optimized PNG files), your iPhone has to do the byte-swapping and alpha premultiplication at load-time (and possibly re-do the alpha multiplication at display time). Your application basically has to do the same processing that Xcode does, but it's doing it at run-time instead of at build-time. This is going to cost you both in terms of processor cycles and memory overhead. One of the reasons why Mobile Safari is the biggest memory hog of the built-in iPhone applications is because the images it has to load in order to display web-pages are all non-optimized images, mostly JPEGs. Since JPEG is a compressed format, it has the added extra step of having to decompress the image into memory before it can do the premultiplication and byte-swapping.
Tuesday, October 14, 2008
I'm really horrible at keeping up with Twitter. I recently had an influx of new people following me (lord knows why, but it's cool!), which made me realize that I hadn't tweeted since WWDC! Anyway, if you want to follow me, my Twitter name is jeff_lamarche, and I promise to try and get better about keeping it up, though I don't promise it will be even the slightest bit interesting.
In the works: An iPhone tutorial for creating applications that use SQLitePersistentObjects, which I hope to make some enhancements to in the near future.
In the works: An iPhone tutorial for creating applications that use SQLitePersistentObjects, which I hope to make some enhancements to in the near future.
Another ADC Article Online
Dave and I wrote this one a while back, and it's finally percolated onto the ADC web site. Pretty happy with this article, and it feels good to have another one see the light of day, even without a byline.
http://developer.apple.com/webapps/articles/creatingrestfulclients.html
http://developer.apple.com/webapps/articles/creatingrestfulclients.html
Thursday, October 9, 2008
Circles, Ellipses, and Regular Polygons in OpenGL ES
The iPhone's use of OpenGL ES means that a lot of games and other programs can be ported relatively quickly. Unfortunately, the iPhone uses a relatively old version of OpenGL ES (1.1), and by the very nature of an embedded graphic engine, a lot of the niceties of the expansive OpenGL have been removed, including functions to draw a lot of standard primitive shapes.
Lines and squares are pretty easy, of course, but what about more complex shapes? Well, you're on your own for those, so unless you're comfortable with doing a little math, you're going to have problems with OpenGL ES. Here's one example - how do you draw an ellipse or circle in OpenGL? I'm not talking about a sphere (we'll look at that in a later post, maybe), but a two-dimensional circle? Or a triangle?
These two functions draw (respectively) an ellipse and a circle (which is just an ellipse with equal height and width) at a given location, either filled, or outlined. But, they actually do more then that. You can specify how precise you want the ellipse to be using the segments argument. If you specify, three, for example, it will draw a three-sided polygon (aka a triangle). If you specify 360, you'll get a 360-sided regular polygon, which is going to look like a circle on all but the biggest displays. For most purposes on the iPhone, a value above 12 will look like a circle. A value less than 3 won't work, but the error checking is your responsibility. :)
Lines and squares are pretty easy, of course, but what about more complex shapes? Well, you're on your own for those, so unless you're comfortable with doing a little math, you're going to have problems with OpenGL ES. Here's one example - how do you draw an ellipse or circle in OpenGL? I'm not talking about a sphere (we'll look at that in a later post, maybe), but a two-dimensional circle? Or a triangle?
These two functions draw (respectively) an ellipse and a circle (which is just an ellipse with equal height and width) at a given location, either filled, or outlined. But, they actually do more then that. You can specify how precise you want the ellipse to be using the segments argument. If you specify, three, for example, it will draw a three-sided polygon (aka a triangle). If you specify 360, you'll get a 360-sided regular polygon, which is going to look like a circle on all but the biggest displays. For most purposes on the iPhone, a value above 12 will look like a circle. A value less than 3 won't work, but the error checking is your responsibility. :)
void GLDrawEllipse (int segments, CGFloat width, CGFloat height, CGPoint center, bool filled)
{
glTranslatef(center.x, center.y, 0.0);
GLfloat vertices[segments*2];
int count=0;
for (GLfloat i = 0; i < 360.0f; i+=(360.0f/segments))
{
vertices[count++] = (cos(degreesToRadian(i))*width);
vertices[count++] = (sin(degreesToRadian(i))*height);
}
glVertexPointer (2, GL_FLOAT , 0, vertices);
glDrawArrays ((filled) ? GL_TRIANGLE_FAN : GL_LINE_LOOP, 0, segments);
}
void GLDrawCircle (int circleSegments, CGFloat circleSize, CGPoint center, bool filled)
{
GLDrawEllipse(circleSegments, circleSize, circleSize, center, filled);
}
Subscribe to:
Posts (Atom)