Tuesday, June 7, 2011

Building a step up/down notched slider for iPhone

If you implement the following delegate method with similar code then you will gain the desired effect as you move the slider with your finger on-screen.

- (IBAction) sliderValueChanged:(UISlider *)sender {
    float value = [sender value];
    if (value < 0.5) {
        value = 0;
    } else if (value > 0.5 && value <1.5) {
        value = 1;
    } else if (value > 1.5 && value <2.5) {
        value = 2;
    } else if (value > 2.5 && value <3.5) {
        value = 3;
    } else if (value > 3.5 && value <4.5) {
        value = 4;
    } else if (value > 4.5 && value <5.5) {
        value = 5;
    } else if (value > 5.5 && value <6.5) {
        value = 6;
    } else if (value > 6.5 && value <7.5) {
        value = 7;
    } else if (value > 7.5 && value <8.5) {
        value = 8;
    } else {
        value = 9;
    self.slider.value = value;

SIGABRT when opening URLs in iPhone App

The code for opening URLs from an iPhone app is relatively simple:
NSURL *url = [NSURL URLWithString:@"http://pulkitsinghal.blogspot.com"];
[[UIApplication sharedApplication] openURL:url];

Yet the 1st time I tried to use it, I kept running into the SIGABRT exception.
Ofcourse I blame the code right? Yup!
But after many searches on Google yielded no clues at all, I went back to the stack trace:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[IconDetailsViewController gotoAuthorWebSite:]: unrecognized selector sent to instance 0x4e619b0'

For the life of me, I couldn't figure out why it was claiming that the method/selector gotoAuthorWebSite was not present when I could see it in my code and the webpage was launching as well! How could it do what it was supposed to do and still claim that the code that was supposed to do the work didn't exist?

Turns out that at some point of time there was a case-sensitive discrepancy between the signatures in my .h and .m files!
- (IBAction) gotoAuthorWebSite:(UIButton*)sender;
- (IBAction) gotoAuthorWebsite:(UIButton*)sender{...}

And I happened to have resolved this inconsistency but only after I had already wired up both these methods to the UIButton component in the NIB file! So the problem was that the non-existent method (with the incorrect casing) had not been auto-removed as the following picture shows:
After manually deleting this incorrect mapping from the NIB file, everything was peachy!

Wednesday, June 1, 2011

Building IconFinder App for iPhone

After having gone through more than half of the Stanford 2010 Fall lectures on iTunes University, the urge to branch out and write something meaningful struck me. But I found myself sorely lacking on any fundamentals for getting data off the web! This is where a friend recommended RestKit and while trying to make a "real" app I also ran across IconFinder. This quickly turned around into a project where I decided to integrate with the IconFider API using RestKit to make an app that lets users explore the goodness of IconFinder as an app.
  • Initial Demo # 1
  • Revised Demo # 2
  • Get an up to date copy of the RestKit source code:
    • git submodule add -b 67-object-mapping-2.0 git://github.com/twotoasters/RestKit.git RestKit
    • cd RestKit
    • git pull
  • In order to validate the idea, I used this approach to quickly get an image to show up in the table. But surprisingly half of the images were coming over while the other half weren't, looking more closely at the JSON data I realized that the URLs with spaces in them were the ones that weren't showing up in the table so I started searching and found the right set of clues along with the solution here.
  • But overall the simplistic approach for loading images synchronously is a bad idea as I read in detail here. So having made sure things looked the way I wanted them to I moved on to refine the code some more. I got lucky and found a SDWebImage library/framework that already did this in an asynchronous and efficient manner.
    • git submodule add git://github.com/rs/SDWebImage.git SDWebImage
  • So far I had searched only using a static string, in order to see if I could get a nice & simple table view to be populated with an image and some text. Now, I wanted to add a search bar to make this into a meaningful icon browsing/finding app that it was supposed to be. I had read a lot about how to do this using NIB files but luckily I also found some guidance on how to add the UISearchBar programatically.
    • - (void)addSearchBar
          if(!_searchBar) {
              _searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 41.0)];
              _searchBar.showsCancelButton = YES;
              _searchBar.delegate = self;
              self.tableView.tableHeaderView = self.searchBar;
  • Just because I had started out with a barebones "Window based Application" project in XCode with the intention of keeping things simple, it did not mean that I was thrilled at the idea of having to tackle all the UI work programatically now. It was time to take it up a notch.
    • I knew how to work programatically and I knew how to work with NIB files if I started my project with everything in-place courtesy of XCode ... BUT as is the case with many beginners, these were two mutually exclusive approaches in my mind and it is difficult to make a mental leap where the two are one & the same. With a little help and a bit of experimentation I got over that hump. I'll try to post a quick screencast to show it in action.
  • Now it was time to make the search a bit more specific by allowing the users to search for the icons based on size that could be controlled by a slider to jump between ranges like 16x16px, 48x48px, 512x512px etc. Once again I had some help from the web and ended up developing my own simple scheme.