""

Category: IPhone

initialize that view: Storyboard

This post is about a problem that is basic but starters are likely to fall into if not careful. When using a tableview, there will be a time when there will be a need to use custom table cell class. There will be outlets defined for views inside cell. Now there will be a time for need of initializing views. Now there is a chance of falling into one common problem when trying to initialize views of cell that is being loaded from Storyboard. What could be happening is stuff doesn’t get initialized when cell is created. Only one thing comes to mind is that init is not getting called at all. So lets see how init method looks like when xcode creates UITableViewCell subclass for us:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

Yeah so we have initwithstyle for intializing our stuff. But when we write any initializing code then it doesn’t work. Thing is that when your views are being loaded from storyboard then initWithCoder is used not initwithstyle. So what we need is this:

- (id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {
        // Initialization code
    }
    return self;
}

Thanks.

That’s my unique identity: IPhone

Recently i had a requirement to send unique identifier for device to my web service. I was going through the documentation of UIDevice class at apple’s developers site. Apple has depreceated the “uniqueIdentifier” property from IOS 5 onwards. My application project traget was IOS 5 onwards. I did a search on alternatives on web and forums, got many options. In this post i am not giving any tutorial, just about what option i chose and what silly mistake i made while integrating it into my project. One good option was recommended to me by many sources and after using it i would myself recommend this to others. I read Unique Identifier Is Dead, Long Live Unique Identifier”, author has stated the recommendation provided by apple, its pros and cons and better way to use them. Author has implemented the class that encapsulated all the work of getting and storing identifier. So i would recommend to read that blog.

It was very simple to integrate into project, just need to copy and reference one header and implementation file. So now time to state what silly mistake i made, after integrating those implementation files, i ran my project and got so many errors. I am posting some of errors below:

Undefined symbols for architecture i386:
“_SecItemUpdate”, referenced from:
+[BPXLUUIDHandler storeUUID:] in BPXLUUIDHandler.o
“_SecItemAdd”, referenced from:
+[BPXLUUIDHandler storeUUID:] in BPXLUUIDHandler.o
“_SecItemCopyMatching”, referenced from:
+[BPXLUUIDHandler UUID] in BPXLUUIDHandler.o
+[BPXLUUIDHandler reset] in BPXLUUIDHandler.o
“_SecItemDelete”, referenced from:
+[BPXLUUIDHandler reset] in BPXLUUIDHandler.o
“_kSecAttrAccount”, referenced from:
_CreateKeychainQueryDictionary in BPXLUUIDHandler.o
“_kSecAttrService”, referenced from:
_CreateKeychainQueryDictionary in BPXLUUIDHandler.o
“_kSecClass”, referenced from:
_CreateKeychainQueryDictionary in BPXLUUIDHandler.o
“_kSecClassGenericPassword”, referenced from:
_CreateKeychainQueryDictionary in BPXLUUIDHandler.o
“_kSecReturnAttributes”, referenced from:
+[BPXLUUIDHandler UUID] in BPXLUUIDHandler.o
+[BPXLUUIDHandler reset] in BPXLUUIDHandler.o
“_kSecReturnData”, referenced from:
+[BPXLUUIDHandler UUID] in BPXLUUIDHandler.o
“_kSecValueData”, referenced from:
+[BPXLUUIDHandler storeUUID:] in BPXLUUIDHandler.o

So it seemed “SecItemAdd”, “SecItemUpdate” etc were not being processed or recognized. After experiencing similar “Undefined symbols for architecture i386” errors many times in past, i can tell what could be the primary reason. The most primary cause could be that appropriate framework hasn’t been linked up to target. So my first job was to search on SecItemAdd and all above stuff and look for framework they belong to. It seemed that they belong to security farmework. So once again i happened to forgot including the framework. Once everything goes fine then just do:

import "BPXLUUIDHandler.h"

and

[BPXLUUIDHandler UUID]

So anyone who happens to fall into this pitfall like me, don’t forget to link “Security.framework” to your project target.

Thanks.

Phonegap doing facebook

I am here again to write on few more pitfalls that i fell into while setting up facebook-phonegap plugin. Set up is explained in the github project site. Just read the steps carefully and follow them one by one, don’t skip steps just for safety. Steps are clear enough to have setup your facebook plugin with phonegap project on xcode. My story starts when i finished all steps and finished setting up my project. So after everything was covered i built my project and fell straight into issues (not many issues and this particular one wasn’t any big):

1) “SenTestingKit.h not found”, yeah so some files from facebook sdk were using SenTestingKit.h which wasn’t created on my project. So to solve this issue, i had to link SenTestingKit.framework from Build phases tab -> Link Binary with libraries to project target.

Now my above issue was resolved. But real pain came next and new issue arose:

2) Undefined symbols for architecture i386: “_OBJC_CLASS_$_SenTestCase”, this gave me pain in my wherever you can think of, for hours. To be honest i was totally blank on this and didn’t know what to do. So i searched forums for this. It seemed that similar kind of problem was faced by many people. I tried every available answers and fixes but none worked for me. I even created and setup project from scratch again just to make sure if i hadn’t skipped any steps. But again, (yeah there is always a but somewhere) nothing worked. So i dig more deeper into my source files of facebook sdk. It seemed all the source files inside test folder were using this “SenTestingKit”. So i simply deleted that test folder from my project navigator, and it really resolved this issue or i removed the source of issue. No more such errors and no more pain and i don’t know about any gain.

But i wasn’t still sure if it didn’t break up the project as you don’t simply delete files and folders from external libraries without knowing. So i tested my project and performed all facebook activities and it seemed to worked fine. I haven’t found any issue till now but lets see.

I was setting up facebook-phonegap plugin with my phonegap project on xcode. After everything was setup accordingly, i ran the project and many funny things happened after that. Following are the issues that happened:

1) On first attempt run, my xcode stuck on “attaching to myapp” part. I waited and waited and yeah that, but it was stuck.
2) On second attempt i stopped the process and ran the project again. This time app opened up on simulator.

Now i thought it was one time minor issue with simulator or xcode. So i began working on project. After doing my stuff i ran my project again and same above things happened. And this was happening every cycle. I couldn’t understand why xcode build and run process was getting stuck at “attaching to myapp” on first attempt and runs on second attempt after stopping the process. After all this i found third issue:

3) On Application menu of simulator there were two launcher icon for the app, one having image icon(default phonegap icon) and other was blank. When i clicked launcher with image then app closed very quickly after opening, and when i clicked launcher without image then app opened up. This was very strange and brought questions on my mind.

I spent hours and yeah lotsa hours to fix it. I searched stackoverflow for this problem and solution. After lotsa digging around it, i found the answer on one of the forum topic and it did save my life 😛
Solution is:

“Go to Project Navigator -> Select your project name(on top) -> In right pane, select project name under targets -> Select Build Phases Tab -> Expand ‘Copy Bundle Resources'”

Now if you find “Info.plist” within the list then congratulation its your lucky day, Just delete it from list, then clean the project(optional) and run it.

I really hope it works for you too.

Gracias.

This way or that way. When working on web service based application, we make a request to a service and expect a response. So this time i have something to share on this. Most common way to make a request to service is using POST. How would you send an image to service ? In my case i was using php based web service and client is iphone application. We generally send image by writing data to http message, where we mainly mention header and body of message. Our image data goes with the message body of http request. This is how normal http message
is composed in objective-c.

NSString *boundary = @"---------------------------14737809831466499882746641449";
        
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
        
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
// end of what we've added to the header
            
NSMutableData *body = [NSMutableData data];
    
// the body of the post
UIImage *contactImage = self.originalImage;
NSData *imageData = UIImagePNGRepresentation(contactImage);
            
// Now we need to append the different data 'segments'. We first start by adding the boundary.
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            
// Now append the image
[body appendData:[@"Content-Disposition: form-data; name=\"userfile\";filename=\"picture.png\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
            
// We now need to tell the receiver what content type we have
// In my case it's a png image. If you have a jpg, set it to 'image/jpg'
[body appendData:[@"Content-Type: image/png\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
            
// Now we append the actual image data
[body appendData:[NSData dataWithData:imageData]];
            
// We now need to tell the receiver what content type we have
            
// and again the delimiting boundary
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

// adding the body we've created to the request
[request setHTTPBody:body];

That is straight-forward and there is nothing very different with code. Now suppose you have to send some other information data along with image using same above process, so for first and few attempt i tried to write other data to message body too but i failed. I was missing something and couldn’t get it to work. So at that time i had only one solution which was working for me. The idea was to send my other data like strings and all in query string and image data via post message. So what i did was made an query string with my name balue pairs and hit this new url via post message and post message body had my image data. Ofcourse i should have been sending everything in post body but somehow it wasn’t working since i was writing all data in some wrong way as i could send only image at that time. But definitely i found the correct way and i made it right, but i’l come to that part later. For now i want to show where exactly my problem came and where i found the solution. Now my requirement was to send json object/string representation and image to server via post. Good way to do this was again writing both json and image to post message body but i wasn’t able to write both so i decided to send json string representation with query string and image data on post message body. It was definitely working. This is how i was making my json string for my array of objects and creating query string url.

NSString *jsonStr = [self.studentArray JSONRepresentation];
NSMutableString *urlString =[NSMutableString stringWithString:urlStr];
[urlString appendString:@"?student_details="];
[urlString appendString:[NSString stringWithFormat:@"%@", [jsonStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
NSURL *url = [NSURL URLWithString:urlString];

I was hitting this url and sending image data via post, things were going fine until one big bang. If i was making json representation of 40 students inside students array and each student object has 5 members, so json representation comes out really long and big. Sending this long very long string to query string always failed. My nsurlconnection was always getting lost. Now i was left with only one option at that time, it was that i had to send both image and json on post request message body. So after many trials i finally had it working.

responseData = [[NSMutableData data] retain];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url 
                                                                cachePolicy:NSURLRequestUseProtocolCachePolicy 
                                                            timeoutInterval:60]; 
    
[request setHTTPMethod:@"POST"];
    
NSString *boundary = @"---------------------------14737809831466499882746641449";
        
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
        
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
// end of what we've added to the header
            
NSMutableData *body = [NSMutableData data];
    
// the body of the post
UIImage *contactImage = self.originalImage;
NSData *imageData = UIImagePNGRepresentation(contactImage);
            
// Now we need to append the different data 'segments'. We first start by adding the boundary.
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            
// Now append the image
[body appendData:[@"Content-Disposition: form-data; name=\"userfile\";filename=\"picture.png\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
            
// We now need to tell the receiver what content type we have
// In my case it's a png image. If you have a jpg, set it to 'image/jpg'
[body appendData:[@"Content-Type: image/png\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
            
// Now we append the actual image data
[body appendData:[NSData dataWithData:imageData]];
            
// and again the delimiting boundary
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"student_detail\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:@"Content-Type: application/json\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", jsonString] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        
// adding the body we've created to the request
[request setHTTPBody:body];
        
//[connection start];
conn = [[NSURLConnection alloc] initWithRequest:request delegate:self ];
    
[request release];

So that was it. Keep one thing in mind that “name=student_detail” matches with your request variable in web service, so whatever request variable you have in web service, just put that name here. You can write other data to post request message body too now.
Hope this works for you too.

Gracias.

I learned new concept, so this post will be about something…lets move on. I have used (retain) @property for objects before, on many tutorial codes i have seen (copy) semantics used for NSMutableArray, NSString etc. I wanted to know the difference between (retain) and (copy) and when to use on what situation? I did search online forums, tutorials etc for informaion and found that:
(retain) retains the object before assignment and takes the ownership. If i assign object (setter) and change the state of object, it will reflect on same original object that was being assigned. But (copy) creates a new(another copy) of object, if i change state then it won’t reflect on first object that was assigned but to new(another copy) object. For example:

NSMutableString *name = @"Leonard";
//@property (retain, nonatomic) NSMutableString *characterName;
self.characterName = name;
[characterName setString:@"Sheldon"];

name object will have value “Sheldon”, since characterName is taking the ownership of the object by retaining it before assignment.

//@property (retain, nonatomic) NSMutableString *characterName;

name object will remain “Leonard”, since characterName has been assigned another copy upon assignment.

There is more but i’l come to problem that i faced. So i had an mutable array member of a my class, I used (copy) semantics for creating setter and getter, so as usual i assigned an mutable array to my member (synthesizer). Now later on i was adding object to my mutable array member, and program crashed. Yes program crashed, and it was very intersting find when i saw the nature of crash. Nature of crash was that i was adding object to NSArray not NSMutableArray, and as we know NSArray is immutable which cannot be modified hence a crash. So later i found that since i am using (copy) semantics so my implicit synthesizer makes a copy instead of retaining it but the real thing is that copy returns a immutable object, even if copy is being called on mutable. So the object whom i was thinking as mutable turned up as immutable and my program crashed.

Using (retain) makes it work if u want mutable, but there is a mutablecopy also, i haven’t tried that yet but you can write your own mutator, use mutablecopy and see if it return mutable or immutable. The implicit synthesizer will always use copy and assign immutable object.

Thanks.

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":"[email protected]"},{"student_name":"Student2","student_id":2,"email":"[email protected]"}]

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.

Getting to know memory leak

Long time no see. Been busy. I have been playing Borderlands (farming crawmerax), doing lots of advanced android learning and just started in getting my hands dirty with Iphone development. So what was my first impression of Objective-C, well man this language is so so, UGLY. Yeah I didn’t feel comfortable with whole syntax in beginning and still coping up with it. But the learning experience has been good and ugly till now, challenging and especially memory management and memory management will be the topic of this post.

Here I will be telling about some of concepts that I learned or am still learning and problems that I faced as a beginner. I am from java background and hadn’t dealt with managed codes so “memory management” was a new candy for me. So I’ll start from the code that gave me a hell-of –a-start information on the topic.

-(void) viewDidLoad{
        	[super viewDidLoad];

        	self.favoriteFilms = [[NSArray alloc] initWithObjects: @”The Lost Boys”, @“Remember The Titans”, nil];
}

I was getting a memory leak on line where I was allocating and initializing my “favoriteFilms” array. Well, the excitement thrill passed through me when I got the exception and crashed :D.
Well so I pulled up my sleeve and got into the work to find the reason and fixing the stuff.
First thing that came to my mind was “My object wasn’t getting released” and that object was “favoriteFilms”. So here are the things that I did:

1) I called “autorelease” on “favoriteFilms” after initializing array and assigning reference to favoriteFilms. Yes, ofcourse memory leak was still there. I got this error/warning: “autorelease sent too many times”. I am still very new to “Objective C memory management” and learning, so at that time, from this error I concluded that autorelease has already been called somewhere. So again calling “autorelease” didn’t worked.

2) I called “release” on “favoriteFilms”. Still the “memory leak” was dancing. It seemed that “retain count” was still above 0 even after calling “release” or I was calling “release” on wrong thing or something else.

3) Lastly I override dealloc method and called “release” on “favoriteFilms” there and yeah “memory leak” was still trolling me 😛

Then I did something, to be honest I didn’t knew why it worked that time but it worked. So I changed my code to something like this:

self.favoriteFilms = [[[NSArray alloc] initWithObjects: @”The Lost Boys”, @“Remember The Titans”, nil] autorelease];

Hmmm what was that ? It worked?…Well it worked! So what I could tell was instead of calling “autorelease” on “favoriteFilms” object, I was supposed to call on the array object that I allocated. Hmmm, I never understood myself what the above conclusion meant. I mean the array that I allocated is also the reference by “favoriteFilms” object. Isn’t it? So why would “autorelease” call on “favoriteFilms” gave error while calling on allocated object itself worked. So let’s again go back to the error/warning: “autorelease sent too many times”. So it could mean this that when I am calling “autorelease” on “favoriteFilms” then getter method is already returning an autoreleased object to me and I am calling “autorelease” again on it 😀 Someone might shed some more light on this 😛

Now the second way worked too. Here is the second way to improve the code:

NSArray *flims = [[NSArray alloc] initWithObjects: @”The Lost Boys”, @“Remember The Titans”, nil];
self.favoriteFilms = films;
[films release];

How is above different than original code ? How did it fix our memory leak issue? What it seemed to me was that I allocated the array and stored its reference on local variable “films”, now when I assigned “films” to “favoriteFilms” then setter method is retaining the object. After that “release” was called on “films” because retain count is 2 now so you have to release it once it’s been used. The concept is still not fully accurate to me so I could be wrong here. Doing more studying on this topic. But from the above second way, I concluded that it is best to approach this way as its more safer and elegant, allocating and assigning object directly to member variable of class might give you trouble if you don’t take measures, so creating the local variable is safer.

Well I have been following this till now so no issues have been faced yet. I am still new and learning and enjoying IOS and Objective-C . As I found one saying on Google “PROGRAMMING LANGUAGES ARE LIKE GIRLFRIENDS: THE NEW ONE IS BETTER BECAUSE YOU ARE BETTER”

Gracias