Thursday, November 29, 2012

Making app iPhone5 compatible

I recently ported my iPhone app to iPhone5. I required to change quite a few things. Porting experience was not that much smooth as I was expecting.

In this post I am listing what all changes I made to make my universal app iPhone5 compatible.

Enable iPhone5 support

If you have not done anything to your application for iPhone5 support, it should work fine but your app will be launched in letterbox mode. I mean you will see black area around your app.

If you want to remove those black bar and want to use whole iPhone5 screen then you need to supply iPhone5 specific launch image. Image name should be Default-568h@2x.png and resolution should be 640x1136.

When you supply this image, iOS6 knows that your app is iPhone5 resolution compatible.
You can supply that image using project screen.



Once this is done your application will be able to use whole screen area.

You will also need to create other background image with above resolution, however they will not be used by default. You will need to load and display them manually.

Detecting iPhone5

While porting we will need to detect if phone is iPhone5 or not. I am using following code for detecting iPhone5.

+(BOOL) isTall
{
   return  ([ [ UIScreen mainScreen ] bounds ].size.height == 568);
}

Changes in App Delegate

There are some changes in iOS6 to handle orientation change.

In your app delegate class you need to use UIWindow's setRootViewController api to set view controller, rather than using addSubview

Now my applicationDidFinishLauncing method looks like following. I also required to create UIWindow instance manually else touch event was not working properly.

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{        
    self.window = [[[UIWindow alloc] initWithFrame:
       [[UIScreen mainScreen] bounds]] autorelease];
    
    self.viewController = [[ViewController alloc] 
       initWithNibName:@"ViewController" bundle:nil];
    
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // for older version
        [window addSubview: viewController.view];
    }
    else
    {
        // use this method on ios6
        [window setRootViewController:viewController];
    }
    [window makeKeyAndVisible];
}

Handling Orientations

Api to detect orientation change is also changed in iOS6. shouldAutorotateToInterfaceOrientation method is replaced by supportedInterfaceOrientations and shouldAutorotate in iOS6.

I left implementation of shouldAutorotateToInterfaceOrientation method as it is as those will be used for old platform.

Following is how I handled the orientation change.

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

// for iOS6
- (NSUInteger) supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}

-(BOOL) shouldAutorotate {
    return YES;
}

Handling nib file

My application is universal application and I have different nib file for iphone and ipad. There are many view for my application and each view has background and different layout. For iPhone5, you either have to create separate nib file to handle iphone5 specific layout and background image. Or you can go ahead with auto layout but this will work only for iOS6 and onwards.

I wanted to support old platform in the same code base so I ended up creating separate nib file for iPhone5 and specified iphone5 specific background and layout manually.

I am using following code for loading different nib file according to platform.

+(NSString*) getPlatformNibName:(NSString*) origNibName
{
    NSString* fileName = origNibName;
    if( [Util isIPad] == YES ) {
        fileName = [fileName stringByAppendingString:@"-iPad"];
    } else if( [Util isTall] == YES ) {
        fileName = [fileName stringByAppendingString:@"-iphone5"];       
    }
 
    return fileName;
}
After making these changes, my application was working fine for iPhone5.

No comments:

Post a Comment