Adapting the Facebook API for the iPad

by Christopher Gregory posted on August 9 2010 12:51

So recently I was wrapping up development work with the same iPad app port for Mobile Innovations as I had mentioned in my last post, when I ran across a rather interesting problem.

We make use of multiple APIs for allowing you to share what you’ve made in our Applications with all of your friends. However with the iPad things take on a new dynamic. Before everything would be displayed as its own full-screen view controller but the iPad allows us to focus more into a single view. Popovers are a great way to add extra controls that are relevant to on-screen content but not important enough to take up the whole screen.

We currently make use of Facebook, twitter and email as means for sharing. The last two are relatively easy to display inside a popover. Facebook however, is a bit more of a challenge. The Facebook API, of which they have yet to make a native iPad port, displays a series of procedurally generated dialogs that are meant to take up almost the entire screen. This simply won’t do for the iPad, since it has so much screen real-estate doing something like that would break the design theme of centralizing all the content onto as few views as possible and making use of contextual  items to display related content.

Facebook doesn’t make this easy though. Since everything is generated in code, and not from a xib file, we’ve got to dig around to find the parts we need to alter to make it work. We just need to make a few key modifications to FBDialog.m and we’ll be set. As with my last post I’ll be using the self-defined preprocessor macro TARGET_OS_IPAD to separate the code out, so that the FB API remains usable for either device based on your build target.

First step, sizeToFitOrientation is the main function called to generate the main FB dialog window. We’ll just add this here:


 
I’ve excluded everything after the else, as it’s just the main body of the function. In this case we’re just telling it to set a static frame for all dialogs, you can alter this of course to size it however you’d like. Since all of our dialogs should be appearing inside a view we’ve already set up in the view controller we’ll be presenting in the popover it’s easy to just set a static size. Next:


We need to remove this because we don’t want the facebook dialog to try and re-orient itself on orientation change since our popover will automatically handle repositioning itself. Next we’ll add some important code to our Init function

 



By setting ourselves as the active popover delegate this lets us automatically dismiss any open dialog when the popover is dismissed.
And this goes at the end of dismiss method



The above returns the popover delegate to its original source and removes the FB dialog from our view hierarchy.  It’s important to remove the FB dialog’s view from the superview because otherwise you’ll get a memory exception later when the View Controller tries to deallocate the view again as part of its cleanup. This frees everything up in order so we don’t have anything lingering in memory. Now when assigning and removing the Facebook view your implimentation of the above may be slightly different. In my case my main controller view was given the tag 8426 and 9999 is a container view I created just for the Facebook API dialogs, which I move back and forth in the hierarchy as necessary. For the code to work that also means that the view you're adding the dialogs to must already be a part of the view hierarchy.

Normally you might not see this but there’s a grey border typically drawn along the outside of the facebook dialogs. Depending on your app you may want to remove this. If so just put the following code at the start of the drawRect method like so:


 
There’s still one more part of the code that tries to resize our view. Now, you can either do this the way I did, which was to comment out the body like so:

Using preprocessor statements. Or you can just do it in the add/removeObservers methods, which add the keyboard change notifications. Either way it’s important that the above code doesn’t get called for the keyboard notifications as it’s another point where the FB dialog tries to resize and orient itself according to the main screen.

This last part is from the end of the show method:

 

This adds our dialog to our specified view, and removes the last instances of it trying to dynamically size and orient itself. Now no matter where it appears, no matter what size it is, all of our facebook dialogs will appear inside our special view controller, which in our case will appear inside a popover.

One last important tip. When adding any dialog to a popover, it’s always a good idea just in case to have the top level view as a scroll view with the content size set to the frame’s proper width and height. Popovers will try and move to avoid the keyboard when it appears, and that can cause the view to get shrunk. So using a scroll view will ensure that you can scroll while the keyboard’s up, in case it obscures anything important.

Tags: , , , ,

Porting your iPhone/iPod Touch app to the iPad

by Christopher Gregory posted on June 24 2010 09:02

With the release of the iPad back in April companies have been scrambling to take advantage of what this new platform has to offer. Only a little over a week ago the count of native iPad apps approved in Apple’s iPad store was over ten thousand.  So with this device flying off the shelves it’d be hard not to want to cash in with a native iPad app. We recently began work on such a port for Mobile Innovations, one of our clients.

In porting your app there are two very important things that need to happen. The first is that the App’s front end needs to be redesigned to take proper advantage of the iPad. With all the screen real estate it offers it gives you a chance to streamline your interface and reduce the number of controls a user has to click through to get where they need to go. Multiple pages can be condensed into a single page, and so on. But that’s not what I’m really here to talk about, I’m a developer and not a graphic designer so let’s talk about what we need to do to build our native iPad App from our iPhone source. So we can take fullest advantage of all the new features while re-using as much of our existing resources as possible.

First, open your project in Xcode and right click over your build target for the iPhone and click the option to upgrade your build target for the iPad.

Upgrade your build target

After which you’ll be presented with another prompt regarding how you want to handle your codebase.

Select to build two version specific apps.

Next select option number two and click “Ok.” Option number two makes the most sense in this case; if you choose the first option you’d be building both targets from the same everything. Now, this is fine for simple apps where you really just want to have the layout flow into the larger screen with only minor differences. Option number two will copy all of your nib files to a separate area, allowing you to customize your user interface for just the iPad, with the interface being built determined by the active build target.

When viewing your Nibs you’ll notice the bullseye icon heading a column of check boxes. The box checked indicates which Nib is being loaded for the current build target.

The checkboxes tell you which nib is in use for which target.

This gives us all the freedom we want to customize our interface for the iPad to take full advantage of its display. There are still a few more steps to go though before our app is ready. Not all resources will be relevant to a given version of the App. So the next thing to do is to navigate to your project directory and make a copy of your app’s info.plist file into the new Resources-Ipad subdirectory in your project folder (I’d also recommend renaming it to something like appname-iPad-info.plist), then add it to the iPad resources folder in Xcode.

Next we need to tweak some version specific settings. The first of which is setting up version detection since we’re sharing the same source files.  There are two methods of detecting which version of an app certain code should run on;  one for detecting at compile time and one at run time.
You can detect at run-time using something similar to the following pseudocode:

#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD NO
#endif


if (IS_IPAD)
{
// iPad specific code here
}
else
{
// iPhone/iPod specific code here
}

Of course in our case we’re loading separate nibs for two separate versions, so it’s going to be more appropriate to conditionally compile our code using the preprocessor.  Run-time detection is generally only useful for universal apps.
Highlight the build target for our iPad app and click the blue info button to open the project settings for it.  Scroll down and add a little something like this to your preprocessor settings.

Add a constant to your Macros defined for the new build target.


This way now when we need to run different code for different versions of our project we can just write

#ifdef TARGET_OS_IPAD
//iPad specific code
#else
// iPod/iPhone specific code
#endif

Depending on how much code you end up needing to be version specific performing version detection at compile time will offer a much better return speed wise. It also allows you to modify definitions in your header files as well, so that iPod/iPhone apps don’t need to load resources into memory that are only necessary on an iPad. Finally, let’s go back up in our project settings and change our info.plist for this build target.

And that’s it. From there it’s just a matter of reworking your nibs to fit the larger design. Code wise there are some things that do need changing between versions such as how modal inputs like the image picker need to be accessed via popovers in the UI. I can’t say what specific issues anyone else may run into when porting their apps over but with the above you now have everything set up so that you can build two separate apps from the same source and you can re-use as much or as little of your resources as necessary between either version. Just set your target and hit build.

Tags: , ,

Contact Us

We want to hear from you.  Our community is important to us and we want to make sure we give you the contact you want.  Please contact our team if you want to sent us feedback of any kind.  Enjoy reading!

RecentComments

Comment RSS