Selasa, 08 September 2009

Joy of Tech

I don't know if anybody noticed yesterday's Joy of Tech, but if you look closely in panels two and three, you can see the cover of Beginning iPhone 3 Development. In the lower-left right corner of both frames, there is clearly a black book with a grapefruit.

I think this counts as two of our fifteen minutes of fame.

Minggu, 06 September 2009

Backwards Compatible OpenGL ES 2.0

Here is an ambitious open source project intending to make OpenGL ES 2 code on the iPhone backward compatible. I haven't had time to check this out yet, but I plan to when I get some free time. It seems like this could be a godsend for developers facing the decision to use ES 1.1 or 2.0.

All the Little Lies

On my latest AT&T rant, I had a few people remark, basically, "who cares about MMS?".

The fact is, I don't. I have no plans whatsoever to use MMS. I'd like tethering, but I'm not willing to pay an additional charge to use it; I'm already paying for "unlimited data transfer" on my plan. I'm not exactly sure about the math involved, but I'm pretty certain that tethering won't cause me to use more than "unlimited" and it's not really AT&T's business just how I use that transferred data. Even when they do get it working, unless AT&T changes their policy with regards to tethering, I'll just forego it.

But, my earlier rant wasn't really about MMS. It wasn't about AT&T missing a deadline by two days. Hell, I've missed deadlines by two days before; I'm behind schedule on More iPhone 3 Development (which is why I'm sitting at my desk on a Sunday morning). At its core, my rant was s about something bigger.

It's about AT&T's approach to interacting with their customers. It's about the way they treat us and the complete lack of respect they show for us. AT&T has no qualms about flat out lying to their customers. They have a pattern of never taking any responsibility for problems their customers have, even ones that can't possibly be anybody else's fault but theirs. If you talk to customer service, it's like they all took a course in Defensive Talking as part of their employee training.

Here's just one little example. I logged on to AT&T to pay my iPhone bill this morning. This is the message we all get when we log on to pay (you've probably seen it):


You can click on the image for a bigger version if it's too small to read, but it says:
Your login is being verified. Depending on your Internet connection speed, it may take a few minutes for this process to complete.

And it does take a fair length of time to login - much longer than any web site that I use on a regular basis. But, that has nothing to do with my Internet speed, and the person who typed that message almost certainly knew that. I'm on a cable modem, and I paid this bill very early on a Sunday morning. Cable modems are shared bandwidth, so the less people online, the faster your service:



The transfer speed for pages, like AT&T's payment page that are mostly text, is meaningless when you're pulling down 12 megabits per second. Of the twenty seconds or so it took to log in, less than a second was due to my "Internet connection speed" Pinging that server resulted in a ~25ms round trip, which is 0.025 seconds. Worst case scenario, maybe a second or two was eaten up by transfer time and latency, or about a tenth of the time it took to log in.

AT&T obviously realized that logging in to their system would take longer than most users would expect it to take. Instead of fixing it, or just saying "hang on a second, we'll be right with you", they try to push the blame off of themselves and onto their customer and their customer's ISP. Believing, possibly rightly so, that most of their customers either wouldn't be savvy enough to realize that they were being lied to or just wouldn't care.

When it comes down to it, I don't hate AT&T because of their spotty coverage, failure to predict reasonable growth in 3G usage, or any of the other things that I've complained about here. Those are all just symptoms of a much bigger problem.

I hate AT&T because they seem to hate me (and you, too). At very least, they don't respect me, and they certainly don't take responsibility for their actions. We wouldn't accept this type of behavior from the real people in our lives. If I went to my publisher and told them I was behind on the book because of something my publisher did that was only tangentially related to my writing, they wouldn't believe me, and they'd be pissed off at me to boot.

Why don't we hold corporations like AT&T to that same standard we hold individual people? Why have we become so tolerant of abuse and disrespect from large corporations?

Sabtu, 05 September 2009

Saving Tabs

I've been so ranty lately that I thought I should take a short break from writing More iPhone 3 Development to put up something technical. This is a relatively beginner-level tutorial, but it's one of those little features we take for granted but really hate when it's not there (at least I do).

I'm talking about saving the selected tab. When you start Apple's Clock application, for example, it always takes you to the tab you were on when you last used it. In most cases, this is a very good idea. There may be cases where a specific tab should have preference, but generally, you should bring the user back where they left off.

If you're using a tab bar controller, it's relatively simple to implement this. In viewDidLoad or applicationDidFinishLaunching:, you need to do something like this:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger whichTab = [defaults integerForKey:kSelectedTabDefaultsKey];
tabBarController.selectedIndex = whichTab;

Then, either when the selection changes, or when the application quits, you have to store off the tab in the preferences so it'll be there next time. I prefer doing it whenever the tab selection changes because then we've captured it, even if there's a crash or phone call, but doing it when the application finishes is fine for most purposes. Here's how you reverse the process:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger whichTab = tabBarController.selectedIndex;
[defaults setInteger:whichTab forKey:kSelectedTabDefaultsKey];

But what if you're just using a UITabBar and not a UITabBarController? That's a touch more difficult because tab bars don't work by indices. It's relatively easy to add the exact same functionality that's on the tab bar controller to the tab bar by using a category, however:

UITabBar-Index.h
#import <Foundation/Foundation.h>

@interface UITabBar(Index)
- (NSUInteger)selectedIndex;
- (void)setSelectedIndex:(NSUInteger)newIndex;
@end



UITabBar-Index.m
#import "UITabBar-Index.h"

@implementation UITabBar(Index)
- (NSUInteger)selectedIndex {
return [self.items indexOfObject:self.selectedItem];
}

- (void)setSelectedIndex:(NSUInteger)newIndex {
self.selectedItem = [self.items objectAtIndex:newIndex];
}

@end


Once you have that, you can import this category and use the exact same code from above on the tab bar rather than the tab bar controller.

Here's an example project. It includes a functioning tab bar application that saves the tab position, and also contains the category above.

Debugging Drawing

Apple has a nice little utility called QuartzDebug in /Developer/Applications/Graphics Tools, and one of the features of this program is that it will highlight all redrawing that gets done in every application. Every time a view is redrawn, it flashes. This is a great tool for determining if you're doing unnecessary drawing in your drawRect: method, or if you're somehow triggering unneeded redraws some other way.

I've had a lot of people ask me about doing this on the iPhone. I've been told by several people that they saw this functionality demonstrated at the iPhone tech talks, which had me stumped. I completely forgot that you can get very similar functionality by passing an argument called NSShowAllDrawing to your application on launch. This is mentioned in this excellent technote on debugging.

Michael Fey has a (somewhat holder) blog post, complete with video, that shows how to use NSShowAllDrawing. His example shows using it in a Cocoa application, but the process is exactly the same for using it in an iPhone application.

Update: A couple of people pointed out in the comments that this option is also available using Instruments. If you run with the Core Animation template, there's a checkbox labeled "Flash Updated Regions", which is checked in the screenshot below:



I haven't been able to get the Core Animation template to work for me on the Simulator, though. I'm not sure if that's by design, or a problem with my installation.

Jumat, 04 September 2009

Apologism from AT&T

AT&T has posted a video on YouTube where their resident blogger, "Seth", claims to "take head on" our complaints as AT&T users.



The explanation sounds okay...

That is, if you don't actually let your brain function while "Seth" talks. The fact that AT&T conveniently left out of their explanation is that all that massive growth they've been seeing equates to massive growth in their monthly income. In other words, they had the resources, but they didn't plan well enough or spend enough of that massive gross income to actually provide the service all those people are paying $100 a month or more for. Their competitors in this country and all over the world somehow managed to do what AT&T didn't, and they try to make it sound like it's not AT&T's fault.

I can't speak for anyone else, but I don't find this video particularly satisfying or mollifying. In fact, to me, it looks like apologism of the worst sort. Don't make lame, after-the-fact excuses. Tell me when it's going to be better and say you're sorry for fucking up. Say you're sorry for taking gobs of cash from all of us each month and for not providing even halfway decent service much of the time.

Own up or don't bother talking. Don't tell us that by sending you all this money every month, we caused this problem. That's over-the-top ridiculous.

I don't put much faith in rumors, but I really do hope the ones about AT&T's exclusivity ending soon are true, because I'm about fed up with AT&T.

Sigh

Microsoft's marketing brain trust continues to look like a 40 year old with a combover trying to look cool at a high school dance.

C'mon Microsoft. You're not selling tupperware or cosmetics. Most sane people aren't going to celebrate a software release that they weren't directly involved in by inviting friends over and playing pin-the-tail-on-the-donkey. Even if you do manage to bribe some people with a free copy of Windows 7 and a chance at fabulous cash and prizes… well, the parties aren't going to look anything like this:


Sheesh. How can a company with so much money and so many smart people working there keep coming up with consistently moronic ideas?

That picture and the advertisement it's part of is a beautiful demonstration of what Jeff Atwood recently blogged about.

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Lady Gaga, Salman Khan