""

Archive for August, 2012

Bad Url: Objective C

I was sending few data(strings) to server via query string. Everything was going fine then one time suddenly program crashed. It was “bad url error”. I didn’t know what happened at that time. I thought i was hitting bad url so i checked it again but it was correct. I run my program again, it was running fine. I followed this again n again to replicate that crash. Then it crashed one time again, and i noticed that it crashed only when i was sending string with space between on query string like london olympics. The crash was genuine since you can’t expect query string to have any “space”. So solution was to encode my string with percent(%) escapes as you see in regular query strings. There is a simple built-in method to do this:

[myString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]

This will make you string something like this: london%20olympics

Thanks.

Manage Navigation Stack: IPhone

While working on my first iphone project, on later stage i had a requirement to manipulate my navigation controller stack of my app. I’ll explain what i mean by manipulating ? My app consists of various screens, with it comes navigation between them. So for instance lets say “A” is the initial first screen or to be more precise first view controller inside navigation controller. Now from “A”, i navigate to “B” then “C” and finally “D”. On screen “D” i wanted to pop my current view controller i.e pop “D” from navigation stack. It is simple to do that, just call popViewControllerAnimated to pop “D”. Popping “D” would lead me to “C” and its natural since “C” is below “D” on the stack. But i wanted to navigate to “B” instead of “C” and also pop “C” when i pop “D” explicitly. This is what i am talking about manipulating navigation stack. So how do you this ?

I found that navigation stack is maintained in array. You can manipulate the array and assign that array to navigation controller, whole navigation stack of your app is defined by this array then. Here is the code:

NSMutableArray *allControllers = [[NSMutableArray alloc] initWithArray:self.navigationController.viewControllers];
        
NSArray *allControllersCopy = [allControllers copy];
        
for (id object in allControllersCopy) {
      if ([object isKindOfClass:[MyC class]])
                [allControllers removeObject:object];
}
        
[allControllersCopy release];
        
[self.navigationController setViewControllers:allControllers animated:NO];
[allControllers release];

I am getting array of view controllers within navigation stack. Next i am iterating through it and checking if a viewcontroller is “C”, if it is then i am simply removing it from array. Now i assign array back to navigation controller. After that simply popping my current view controller “D”.

[self.navigationController popViewControllerAnimated:YES];

Well it worked for me, and i am using it whenever such needs arise.

Thanks.

Iphone development has been a smooth ride for me, more smoother than when i started android :D. I am still playing and learning. I started with non-arc projects cuz i wanted to learn and grasp the concept of memory management, today i won’t be talking about memory management but JSON representation of your custom objects. Its a common topic and almost every person might had a requirement to create JSON array of your objects and send it to server. I was introduced to very awesome library called SBJson, after that i have been using this only because its been perfect for me till date. If you are working with non-arc project then i would recommend to use version 3.0.4, which is latest for non-arc.

Let’s begin, we have our class called Student. Student has got some properties like student id, photo, teacher id etc. So lets see how our Student class looks like:

@interface Student : NSObject{
    NSString *name;
    NSInteger sid;
    UIImage *simage;
    NSString *email;
}

Student has got four members: name, id, image and email. Now your requirement requires you to create list of students and send it to server on network. First thing that would come to mind is add all students to an array and send that array to the server. Second thought would be, how would i send an array to server ? Best bet would have been creating a json array of students. So lets call our array studentsArray which contains all students. Basically we are looking json representation something like this:

[{"student_name":"Student1","student_id":1,"email":"abc@email.com"},{"student_name":"Student2","student_id":2,"email":"def@email.com"}]

As you can see, its a json array of two students. Creating this representation isnt hard at all since SBJson does all work for you except you have to keep few things in mind else it will blow up. Code for creating json representation is this simple:

NSString *jsonString = [studentArray JSONRepresentation];

Yeah that simple. But above will crash your program. Error will be something related to serialization problem of one of your member of student object. If we look at our Student class definition above, there is member of type UIImage. It seems we have issues with serializing UIImage type. So things that work are strings, integers and booleans. Now what you can do is to remove that UIImage from definition but i don’t want to do that. If i don’t do that then how will i create json representation ? So someone comes to rescue:

#import "SBJson.h"

@interface Student : NSObject{
    NSString *name;
    NSInteger sid;
    UIImage *simage;
    NSString *email;
}

- (id) proxyForJson;

proxyForJson gets called when you ask for json representation of your object. Inside proxy you tell what members to serialize and give your custome key names for your member. Implemenation looks like this:

- (id) proxyForJson{
    return [NSDictionary dictionaryWithObjectsAndKeys:
            name, @"student_name",
            [NSNumber numberWithInt:sid], @"student_id",
            email, @"email",
            nil ];
}

So basically it will make json representation of your student object like this:

{"student_name":"value","student_id":value,"email":"value"}

As you can see that we have skipped UIImage type, so u can skip those members that cannot be serialized. So now you are free to call [studentArray JSONRepresentation] and it will give you your perfect json representation. You must also have noticed that i am using NSNumber from integer above, this is because dictionary takes pointer types aka objects not primitives.

I hope it helped you. Now i’l go back to play borderlands as i am still farming crawmerax for pearl aries revolver 😛

Gracias.