Tag: idevblogaday

Let’s say you’re making HTTP requests and handling responses as we described last time. Parsing the results is usually pretty easy, but what happens when you have a large blob of data, be it XML or JSON or whatever? Any lengthly processing on the main thread, more than a couple hundred milliseconds, will introduce a noticeable hiccup in the UI. Adding a worker thread would help, but perhaps the easiest method is to use the non-blocking NSOperationQueue. With NSOperationQueue you simply package up the work to be done into an NSOperation instance and add it to the queue.


Continue reading…

It’s common for iPhone apps to need to make HTTP requests and receive results in either JSON or XML format. There are several excellent full-featured tools ( ASIHTTPRequest, RestKit, etc.) to help you with this task, but sometimes all you need is NSURLConnection. NSURLConnection is a simple class that provides easy to use high-level asynchronous request/response handling.  I’ll describe a simple wrapper I’ve been using to make it easy to handle multiple requests easily.

When using NSURLConnection there are only a couple of things to deal with. Unless you are using the synchronous version (not recommended) you will typically set up an object, such as your application delegate or a view controller, as a delegate to receive the NSURLConnectionDelegate callbacks. The main delegate message you need to handle are connection:didFailWithError:, connection:didReceiveData:, and connectionDidFinishLoading:.

One potential issue you face here is using a single object as delegate for multiple connections. Then your delegate message handlers will become messy as they attempt to determine which response goes with which request, etc. Now instead consider creating a utility class with just two public methods, like this:

@interface myConnectionController : NSObject {
    NSMutableData* receivedData;
}
@property (nonatomic, retain) id connectionDelegate;
@property (nonatomic) SEL succeededAction;
@property (nonatomic) SEL failedAction;
- (id)initWithDelegate:(id)delegate selSucceeded:(SEL)succeeded selFailed:(SEL)failed;
- (BOOL)startRequestForURL:(NSURL*)url;
@end

In this sample class receivedData is where the response will be stored, the connectionDelegate refers to what will be the target of the succeededAction and failedAction messages. After all, that’s all I really care about when making this request: success or failure notification. Now your connection controller can be instantiated like this:

id delegate = self;
myConnectionController* connectionController = [[[myConnectionController alloc] initWithDelegate:delegate
                                                                                   selSucceeded:@selector(connectionSucceeded:)
                                                                                      selFailed:@selector(connectionFailed:)] autorelease];
[myConnectionController startRequestForURL:[NSURL URLWithString:@"http://request.org/somequery.php"]];

You also need to implement the callbacks. These will take the response data and parse it, typically, or handle any error conditions. Although the request is handled asynchronously by the URL Loading System, your callbacks are signalled on the main thread, and you may not want to tie it up parsing large chunks of XML or JSON. Next time I’ll write about using NSOperationQueue to do the parsing in a background thread so the UI remains responsive.
- (void)connectionSucceeded:(NSMutableData*)data {
    // data contains response, e.g. JSON to be parsed
}
- (void)connectionFailed:(NSError*)error {
    // error contains reason for failure
}

This is a totally trivial example, but you can see how easy it will be to a) define multiple callback handlers for any given class, and thus allowing for multiple NSURLConnections, and b) subclass myConnectionController for specialized request handling. This is what the default implementation looks like:
@implementation myConnectionController
@synthesize connectionDelegate;
@synthesize succeededAction;
@synthesize failedAction;
- (id)initWithDelegate:(id)delegate selSucceeded:(SEL)succeeded selFailed:(SEL)failed {
    if ((self = [super init])) {
        self.connectionDelegate = delegate;
        self.succeededAction = succeeded;
        self.failedAction = failed;
    }
    return self;
}
-(void)dealloc {
    [connectionDelegate release];
    [super dealloc];
}
- (BOOL)startRequestForURL:(NSURL*)url {
    NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
    // cache & policy stuff here
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setHTTPShouldHandleCookies:YES];
    NSURLConnection* connectionResponse = [[[NSURLConnection alloc] initWithRequest:urlRequest delegate:self] autorelease];
    if (!connectionResponse)
    {
        // handle error
    return NO;
    } else {
        receivedData = [[NSMutableData data] retain];
    }
    return YES;
}

And finally, the standard delegate methods for NSURLConnection are hidden inside the myConnectionController implementation. These should be familiar if you’ve ever used NSURLConnection directly:

- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
    [receivedData setLength:0];
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
    [receivedData appendData:data];
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error {
    [connectionDelegate performSelector:failedAction withObject:error];
    [receivedData release];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
    [connectionDelegate performSelector:succeededAction withObject:receivedData];
    [receivedData release];
}
@end

That should be enough to get you started. Hopefully you won’t find it too hard to extend this to add the ability to cancel a request, etc.


This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two new posts per day. You can keep up with iDevBlogADay through the web site,RSS feed, or Twitter.

3 Years On The App Store

This week marks the 3rd anniversary of the App Store launch. It sounds, and feels like a lifetime ago. It’s sometimes hard to remember how “unconnected” our lives were before the iPhone, but I can say that prior to June of 2007 I absolutely hated every cell phone I owned. There was the Qualcomm clunker, the Motorola junker, the Samsung clamshell, etc. More often than not the phone was merely a device to slap the carrier’s label on to. People got a “verizon phone,” or an “at&t phone” if you lived in the U.S. We were, and still are, captives of the telcos, but that’s starting to change finally.


Continue reading…

In With the New

The new shiny is here. At the annual WWDC recently, Apple unveiled three widely-anticipated new products. This year it was all about software, so hardware announcements will have to come later. In the keynote Steve Jobs mentioned OS X Lion, iOS 5, and iCloud. If you’re an iOS or Mac developer these changes will have a huge impact on you in the next few months. I’m not going to go into much detail about the announcements, but you should definitely check out the keynote if you haven’t seen it yet.


Continue reading…

The Annual Pilgrimage

WWDC 2011The annual pilgrimage to San Francisco is underway this week. I figure I’ve attended about a dozen in the past 21 years. All have indeed been awesome. Many long-time attendees seem to have mastered the week-long partying and a few have even published “survival guides.” My goal is not to get as many free drinks as I can, or to stay awake during the late-afternoon sessions. I’m here to see old friends, make new ones, and absorb the latest installment of greatness from Apple. I came prepared with questions, code problems, and and open mind about what’s next for iOS and OS X. Seeing a live Stevenote will be a bonus.


Continue reading…

I ran into an odd issue the other day and spent a little time getting to the bottom of it. It turns out I wasn’t taking good care of my Xcode project’s library search paths. Here’s what I had to do about it and why you might care. Note this problem has likely been lurking in my project for some months, and may have caused other unintended consequences.


Continue reading…

Like pay-to-play or in-app ads, prompting for a rating is controversial in that some developers frown upon it. Free apps tend to have an average 3 star rating. People rarely bother to go back to the App Store to rate an app. There’s always a small minority that will go out of their way to provide negative reviews. So why not solicit positive feedback by providing a reminder to rate the game? In my opinion, there’s nothing overtly annoying or obnoxious about presenting an alert view that can easily be dismissed.


Continue reading…

Another Year

A quick peek at the calendar reveals that it is exactly three months since my first iDevBlogADay post. Thus it’s time to relinquish my spot and move to the back of the list (thanks, @mysterycoconut!) so some other patient indie can have a turn. This has been a good exercise to get me writing again. Some of the more popular posts have included AdWhirl, Game Center, Localization, so I’ll continue to expound those topics. Three months feels like a decent amount of time in the iDevBlogADay spotlight, and even though there’s no term-limit, maybe there should be. Nah.


Continue reading…

Unsung Heroes

360Logo.png

Last weekend I had the privilege to be able to attend the inaugural 360MacDev conference in Denver. While many readers may only be beginning to think about deploying apps on OS X, there are many developers out there who’ve been happily making a living doing so for years. The overlap, or synergy, if you will, of the iOS and OS X communities was clearly evident at the conference.


Continue reading…

Don’t Let Me Down

[Guest post this week by Trish]

The Beatles!!! On iTunes!!!  Depending on what side of the fence you’re on, this was either a ‘day you’ll never forget,’ or a big yawn.  If I tell you that I’ve been a lifelong Beatles fan, and, in fact, saw them at the Baltimore Civic Center on Sep 13, 1964, you’ll know which end of the spectrum I fall on.

The national media picked up on the story. I saw the Beatles when I walked by my TV.  I saw the Beatles on the top internet news stories. I saw the Beatles on USA Today on my iPad.  Out of curiosity, I googled  ‘Beatles’ and ‘iTunes,’ and read that something like 28 Beatles tunes were in the top 200 downloads. That’s when it hit me – why are we here at Mundue LLC not taking advantage of all of those sales?

When I mentioned this to Mr Mundue (aka Matt), he said that Apple had sent out official iTunes Affiliate artwork.  That did it!  Apple was expecting us to monetize the event.  We got right to work creating a house ad to display in our app, and we were going to monetize the Beatles songs and albums using Apple’s affiliate program.  Brilliant!  And let’s not forget that  $149 box set.  Probably every third or fourth sale would be for the box set, right?

The dollar signs were swirling around in my head.  This was great!  Not only was the best group of all time finally on iTunes, but I was going to capitalize on it.  Let’s see, how many box sets would people have to buy in order for me to make back the money we plunked down to see Sir Paul in August? How many singles?

And if this works out, just think of all the future possibilities.  Every time a big album comes out, we create a house ad and, voila, the money starts rolling in.  Why hadn’t we thought of this earlier?  Well, nevermind, at least we thought of it now.  I couldn’t wait for the affiliate numbers to start coming in!

And then, they finally did.

So how much did this Great Beatles Experiment bring in?  Forty nine cents.  Yup. Forty nine cents.  I was devastated.  How could that be?

I can only venture a guess. Looks to me like most people download music at home, on their computer, not on their iPhone.  We had plenty of clicks, so I guess a lot of folks checked out the Beatles offerings from their phones, but waited until they got home to actually make their purchases. I dunno. They surely bought boatloads of Beatles tunes that day.  Just not on my watch.

Which leaves me with 49 cents.   And a deflated ego.  And a looong way to go to pay off those tickets.  But still a huge Beatles fan.

—-

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web siteRSS feed, or Twitter.