NSMutableData, File Detection, and Downloading

I would like to take a moment to apologize to you, Drew, if you are reading this post, because we had a discussion the other day about what we both need to be focusing on, and I have definitely allocated a few crucial hours towards a different focus, and I’d like to talk about a few topics from this new project. I’d like to discuss a few delegate methods of the NSURLConnection class and there applications.

NSURLConnection has a very useful delegate method called connection:didReceiveResponse: which is capable of providing the developer with an instance of a very useful class called NSURLResponse. I encourage you to look at the documentation for this class, because it can provide some very useful information about the file you are trying to load across an NSURLConnection. Two very cool properties of this class are suggestedFilename and expectedContentLength. With suggestedFilename we can determine the type of the file we are trying to load, then decide what to do with it from there. Let’s say, for example, your user enters “http://tumblr.com” in a UITextField you’ve created which triggers a method that creates a NSURLRequest object with the initializer: [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:textField.text]]; If we load this request into an NSURLConnection object and start the request, once the object calls this delegate method upon response of the URL, the suggestedFilename property of the NSURLResponse object will be something like: “tumblr.com.html,” which is cool, because we can now determine from that string that the file that the user is trying to load is of the type “HTML.”

So if you’re brain is working a little faster than you are reading, you’ve probably already thought about the gravity and potential of this knowledge. If your user wants to load something other than an HTML or PHP file, we can use methods to display those in a way that is more appealing to the user. For example, if the file is a JPEG, you could download that file and add it to a queue of other images that are stored locally to display in a photo album. Or if the file is an MP3, why not download that file and add it to a local playlist, or even stream the file using AirPlay? Get creative. There are a couple of different methods you’ll want to acquaint yourself with. If all you want to do is load the HTML file into a UIWebView, you could use the method: [webView loadRequest:request]; where request is the NSURLRequest object we allocated earlier, and webView is your instance of UIWebView. If you do load the web page this way, make sure to call: [connection cancel]; where connection is the NSURLConnection object passed by connection:didReceiveResponse:. You’ll also want to look at the NSURLConnection delegate method connection:didReceiveData:. You can use the suggestedFilename property I mentioned earlier, as well as an NSMutableData object and its property length to calculate the progress of a download by using [theData appendData:data]; where theData is your NSMutableData object and data is the NSData object passed by this delegate method.

Good luck, and feel free to ask me something at http://daltonclaybrook.tumblr.com/ask

Being the richest man in the cemetery doesn’t matter to me … Going to bed at night saying we’ve done something wonderful… that’s what matters to me.

Steve Jobs

URL Requests and Delegate Protocols

I’ve found that most of the bugs I run into during coding prove to be a vital learning experience and the one I discovered several days ago is no exception. There are pros and cons to asynchronous URL requests, but the pros most certainly outweigh the cons. Asynchronous requests allow me to instantiate NSURLConnection (either directly, or through subclassing), assign an NSURLRequest to the connection, perform the request, and wait patiently until the connection returns a result in the form of a NSURLConnectionDelegate method call.

Every developer has their own unique style of writing code. I happen to prefer to create instance variables of UIViewControllers and their subclasses as apposed to global variables within a superview controller. This makes memory management a bit easier for the application, but also releases and destroys a view controller at the time that it resigns. The problem I was having several days ago was that often times, I would set the delegate of my NSURLConnection object as the instance variable of UIViewController. If the view happened to resign before my NSURLConnection object had a chance to call a delegate method, my code would generate an exception when a delegate method was eventually called. Clearly, I couldn’t call a method on a deallocated instance.

The solution: I created an array of all active connection requests, and removed those connection items from the array once they had returned a result. My next idea was to attempt to intercept the button push of the back button on that particular UINavigationItem. My attempts were unsuccessful as A) you cannot set the delegate of a UINavigationBar that is owned by a UINavigationController, and B) you apparently cannot set the action of the UIBarButtonItem assigned to the backButtonItem property of a UINavigationBar if that navigation bar is owned by a UINavigationController. What I ended up doing was creating a global boolean variable called didPushController, setting the value to YES every time the instance of the view controller pushes and object, and setting the value to NO every time viewWillAppear: is called on the instance of the view controller. This way, when viewWillDisappear: is called on the instance of the view controller, I can check to see if the view controller is popping, and set the delegate of all active connections to nil.

This strategy has not given me any problems yet. It would be a completely different issue if I were retaining my instances of UIViewController, but currently, I release them every time they pop from the UINavigation stack.

Please ask away: http://daltonclaybrook.tumblr.com/ask

Appeal

One cool thing that I’ve discovered about programming is that if I personally want an app for my iPhone and I can’t find one like it on the App Store, I can sometimes just make it myself, and maybe even distribute it and make some money.

I’m on tour with my band and we were all upset by the fact that we couldn’t find a poker app on the App Store that let’s groups play locally over Bluetooth, so I’ve started work on my own and I hope to have it ready to go by the end of the day tomorrow. Do you know a good algorithm for shuffling?

The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry.

Henry Petroski

The Bump app for iPhone allows the user to enable a feature that will send a friend request on Facebook upon a successful Bump.

How?

I…Have…No…Clue.

Any thoughts on file transfer over HTTP using multipart/form-data?

Progress

Today served to be a solid workday, despite having to sift through some six-month-old code. If there’s one thing you (and a future me) should take away from this post: learn to comment your code. I’ve been rewriting code for quite a while because I’ve learned a lot about Objective-C and the iPhone SDK in a very short amount of time. They say ignorance is bliss, but this is only true until you distribute 5000+ units and discover an app-crashing bug in your code.

The code that I made myself sift through today, however, took me too long to write originally to just discard. I had written a class to download a set of images asynchronously and I wanted to make sure my old code was as optimal as it could be. I was able to change quite a bit and free up some valuable space in memory, which is always good in mobile application development. If anyone ever reads this, we should have a discussion on multi-threading. I’d like to hear your approach on asynchronous downloads.

Intended Protocol

I was thinking about how often I’d like to update this blog and I’ve arrived on a formula: I’m going to do my best to write an update whenever I write a significant amount of code in a day. This will allow me to keep track of my progress and will perhaps train me to become more honest with myself.

That being said, today was the 4th of July and I did not write any code; however, last night I did do some work that turned out to be all for not and subsequently discovered that I’m an idiot. As I’ve said, I’ve been using the Tumblr API in a major project I’ve been working on for a while. The problem I’ve been having for the last several days is that when I make an API call to “http://*a-user*.tumblr.com/api/read”, the “regular-body” object is of an HTML type. To my knowledge, the iPhone SDK has no native methods for parsing an HTML string to return a plain text object, which is what I need. I had been thinking about all the possible workarounds for this problem and I arrived on one that I thought would work: I figured I could take the HTML string from regular-body, save it to NSTemporaryDirectory() as a “*.html” file, initialize an instance of NSURLRequest with this file as the URL parameter, create a synchronous request of NSURLConnection with the request, and the resulting NSData object (when loaded into an NSString object) would reflect an accurately processed string from HTML data. I was wrong.

Long story short: I didn’t read the Tumblr API documentation thoroughly. You can actually include the parameter “filter=text” to the API call and the resulting regular-body object will be of plain text type. I suppose the moral of the story here is read the documentation.

Goals

The short term purpose of this blog is to provide an avenue for myself to say the things I still want to say when I’ve already said them to all the people in my life who care and are interested. Another short term goal is to track my progress on a certain project I’m currently working on that employs the use of the Tumblr API.

I’m a software developer for the iOS platform (iPhone/iPad). I hate to say that I’m fascinated by the things I myself am doing, so I’ll just say that I’m fascinated by the things that everyone’s doing in the industry, because that’s definitely true. The growing trend in technology is one of open availability of new ideas. If you have an idea that’s awesome, and I have an idea that’s awesome, why not make our ideas available to each other and make something together that’s completely amazing?

In my optimistic opinion, the long term purpose of this blog is to create the framework for a community of people helping people with development related issues. I’d like for people to ask me questions so that I can discover those people and one day ask them questions. Then maybe with enough support, we can always find answers.