6. When making first view controller as landscape

When we make games, usually we go for landscape orientation. So if you have selected the project template as “View based Application”, Interface builder automatically creates ViewController in Portrait mode for you, which you can make as landscape by clicking on top right “arrow” icon in view controller xib at Interface builder. But still you don’t see exact behavior on simulator when you run the app, it shows you misplaced view.

To avoid this problem you just need to change your “shouldAutorotateToInterfaceOrientation” method as follows:

– (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight)||(interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

Thats it!

5. iPhone Server Communication

We can communicate in many ways with server. One way is using JSON, this is explained as below:

1. Starting Communication

[[[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:
[NSURL URLWithString:urlStr]] delegate:self startImmediately:YES] autorelease];
//urlStr is NSString ref

2. Start receiving data

- (void)connection:(NSURLConnection *)connection didReceiveResponse:
   (NSURLResponse *)response{
    [receivedData setLength:0];
}
//receivedData is NSMutableData ref

3. Get data in chunks

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [receivedData appendData:data];
}

4. After getting complete data

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{

    // json data retrival complete    (received data is NSMutableData)
    if(receivedData == nil || [receivedData length] == 0){
      //handle error in getting response, may be no network
        [self showAlertViewWithTitle:@"No network" andMessage:@"Could not open the
        page, because internet connection was not found." andTag:0];
        return;
    }

    NSString *responseBody = [[[NSString alloc] initWithData:receivedData
      encoding:NSUTF8StringEncoding] autorelease];
    ////NSLog(responseBody);
    NSError *jsonParsingError = [[[NSError alloc] init] autorelease];
    NSDictionary * jsonData = [NSDictionary dictionaryWithJSONData:
                                 [responseBody dataUsingEncoding:NSUTF8StringEncoding]
                                     error:&jsonParsingError];

    NSDictionary *serverError = [jsonData objectForKey:@"error"]==[NSNull null]?
                                   nil:[jsonData objectForKey:@"error"];

    if(serverError==nil || [serverError count]==0){
        // no error found else
        NSDictionary *response = [jsonData objectForKey:@"response"]==[NSNull null]?
                                   nil:[jsonData objectForKey:@"response"];
        NSArray *array = [response objectForKey:@"array"]==[NSNull null]?nil:
                              [response objectForKey:@"array"];
// I have left the code incomplete, its just for understanding

5. Check for null values
Never forget to check null values from JSON data as follows:

NSString *dataValue =  [[[array objectAtIndex:i] objectForKey:@"key"]==[NSNull null]?
                         @"0":[[array objectAtIndex:i] objectForKey:@"key"] intValue]; 

Please let me know if you require further explanation..

4. iPhone Physics Engine Library

We have open source Chipmunk library to implement physics engine in iPhone gaming apps.
Here is the source

This source is the powerful physics 2D engine to use in iPhone game programming. We can have every motion of any real world object in whatever place it is. We can add gravity, friction, external force which will reflect in the motion of the object. And also we can have collision detection between objects present in the current screen.

The source is self explanatory, but I have summarized the usage of this api for handy use and i’ll keep updating this as far as I explore.

rigid bodies: A rigid body holds the physical properties of an object. (mass, position, rotation, velocity, etc.) It does not have a shape by itself. If you’ve done physics with particles before, rigid bodies differ mostly in that they are able to rotate.
collision shapes: By attaching shapes to bodies, you can define the a body’s shape. You can attach many shapes to a single body to define a complex shape, or none if it doesn’t require a shape.
joints: You can attach joints between two bodies to constrain their behavior.
spaces: Spaces are the basic simulation unit in Chipmunk. You add bodies, shapes and joints to a space, and then update the space as a whole.

Please let me know if you want further explanations.

3. Changing UIView’s Coordinate System

Some times in our app we want to change the coordinate system of UIView, mostly when we change the orientation of iPhone like Landscape Right or left, So that time, coordinate system as well as appearance of UIView should also change, so here is the code to do that…

application.statusBarHidden=YES;

[application setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];

myUIView = [[MyUIView alloc] initWithFrame:CGRectMake(0,0,480,320)]; //as now width and height is changed

[window addSubview:myUIView];

CGAffineTransform transform=CGAffineTransformIdentity;
transform=CGAffineTransformRotate(transform, (90.0f*22.0f)/(180.0f*7.0f));
transform=CGAffineTransformTranslate(transform, 80, 80);
[myUIView setTransform:transform];

Now all your subview’s of myUIView will also get transformed. and you will get CGPoint’s of new coordinate system on touch events.

2. UIImage Tips…

There are several things which we need to keep in mind when we use UIImage as follows:
1. UIImage has 4 class methods to create its autorelease instance and 3 instance methods to load image.

2. When you want to cache the image, so that it can be easily loaded in no time whenever required, you should use:
UIImage *tempImage=[UIImage imageNamed:”test.png”]; where test.png is the image which will get cached at the first time and will remain in the memory untill app exits. But this should be used only when the image is less in memory size, otherwise your app will have less real and virtual memory for further use. This returns autorelease instance of UIImage that means you do not need to care about its release.

3. When you want to load the big memory sized images you should use:
UIImage *tempImage=[UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”test” ofType:@”png”]];
this will not cache the image in the memory for the next time use i.e. when you again load this image this will be loaded from file.

4. When you don’t want autorelease instance i.e you want to manage its alloc free things on your own you should use:
UIImage *tempImage=[[UIImage alloc] initWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”test” ofType:@”png”]];
but you have to release it when you are done with it as follows:
[tempImage release];

5. Whenever you set the UIImage’s instance to UIImageView’s image property, the retain count of UIImage’s instance increases by 1. So never forget to nil the UIImageView’s image property when you are done with it otherwise the UIImage will remain in the virtual memory and will leak.
Example:
UIImageView *imgView=[[UIImageView alloc] initWithImage:tempImage];
//now tempImage’s retain count will get increase by one. So nil the imgView’s image property whenever you are done with tempImage like this:
imgView.image=nil;

The difference b/w autorelease and normal instance is that we have to release the normal instance by calling release method to free up the memory.

1. UIImageView AnimationImages Memory Leak Mistry Solved:

We all know that to do animation using UIImageView, we load images in the NSArray and then set it to animationImages property of UIImageView and then call function startAnimating.
But when you try to repeat animation by loading again and again with different images using this method, you start experiencing Crash on iPhone device with status 101 at Xcode debug. Again, we all know why it crashed, just because of no more memory available for our app in the iPhone device.
But where did our memory went. Here is the answer for that. Every time when we set NSArray to animationImages, the whole data gets copied to it because animationImages is copy property of UIImageView. And if we try to again set same animationImages with some other NSArray, we try to nil it first then set with new array. But here we are wrong, when we nil this property, the real time memory decreases but the virtual memory doesn’t decrease because garbage collector is not there.
So instead nil we should call release method of this property which will force it to get freed from the virtual memory too. One more thing you should remember, don’t call release method of this property or don’t try to nil this property in dealloc method where your UIImageView’s reference is released, otherwise either you will get Bad Parameter warning or again virtual memory will not get freed.

Sample code:
UIImageView *imgView;

NSArray *firstArray, *secondArray;

firstArray= [NSArray arrayWithObjects:[UIImage imageWithContentOfFile: [[NSBundle mainBundle] pathForResource:@”1″ ofType:@”png”]], [UIImage imageWithContentOfFile: NSBundle mainBundle] pathForResource:@”2″ ofType:@”png”]], [UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”3″ ofType:@”png”]], nil];

secondArray=[NSArray arrayWithObjects:[UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”11″ ofType:@”png”]],[UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”22″ ofType:@”png”]], [UIImage imageWithContentOfFile:[[NSBundle mainBundle] pathForResource:@”33″ ofType:@”png”]], nil];

imgView=[[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[imgView setAnimationImages:firstArray];
[imgView setAnimationDuration:1];
[imgView setAnimationRepeatCount=0];
[imgView startAnimating];
[self addSubview:imgView];

After Some time, some where in your code u want to change the animation, then you should do as follows

[imgView.animationImages release];
[imgView setAnimationImages:secondArray];
[imgView setAnimationDuration:1];
[imgView setAnimationRepeatCount=0];
[imgView startAnimating];

And At the dealloc method you should do as follows:
[firstArray release];
firstArray=nil;

[secondArray release];
secondArray=nil;

[imgView removeFromSuperView];//If you not already removed this from super view.
[imgView release];
imgView=nil;

So, if you try this you will definitely gain your virtual memory and you app will never crash due to low memory. Any suggestions are always appreiciated.

Thanks,
Sanniv.