blog.planetsucko.com

Deep Thoughts on Code

Porting iPhone Apps to iPad

June10

I finally started porting my iPhone apps to the iPad. At first I avoided the subject like the plague… mostly because i thought it was going to be a pain in the ass and didn’t think I had the time to do it. But its really simple.

Assumptions:

  • You’ve been developing for iPhone and have submitted an app or 2 to the iTunes store.
  • You want an app that will work for both iPad and iPhone. Not an separate iPad application with enhanced features.

Step 1: Download and install iPhone 3.2 SDK

You can find it here on Apple’s site. (unless they change the link)

Step 2: Change the SDK and Targets

  • Change Base SDK to iPhone OS 3.2
    You can find this under Project Properties.
  • Change Targeted Device Family:
    Select the Targets item and click the info button. In the Build tab under the Deployment section, select “iPhone/iPad” for the Targeted Device Family.
  • Change iPhone OS Deployment Target to iPhone OS 3.2
    If you are worried about your iPhone customers that have NOT upgraded to the latest and greatest, select a lower OS Deployment Target. For example: iPhone 3.0

Step 3: Update your views to support iPad

The good news is, iPad uses the exact same code as iPhone. What you will need to do is change your code to support both iPhone (320×480) and iPad (1024×768) resolutions. I’m not going to go into specifics of how to change your view (because each app will differ), but here are some tips on detecting iPad vs iPhone.

Detecting the Device:


if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
     // iPad
} else {
     // iPhone
}

This is all you need if you only want to target the 3.2 OS. But if you are worried about your iPhone customers that have NOT upgraded to the latest and greatest, this will not work.

When you try to test using a lower iPhone OS Deployment Target (for example iPhone OS 3.0), this will throw an error and not compile because these properties do not exist in older SDKs.

The way I get around this is to define these properties in my Prefix header for all source files (xxx_Prefix.pch):


#ifndef __IPHONE_3_2

typedef enum {
     UIUserInterfaceIdiomPhone,
     UIUserInterfaceIdiomPad,
} UIUserInterfaceIdiom;

#define UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPhone

#endif

Now you should compile fine with any SDK.

Cocos2D Developers

If you are using a framework such as Cocos2d, you can use the frameworks ability to detect screen resolution instead. For example:


CGSize winsize = [[CCDirector sharedDirector] winSize];
if ((winsize.width == 1024 && winsize.height == 768 ) || (winsize.width == 768  && winsize.height == 1024)) {
     // iPad
} else {
     // iPhone
}

You will still need to use the UI_USER_INTERFACE_IDIOM technique described above if you are trying to detect the device from your app delegate. For example, setting the screen orientation if you want your app to run in portrait if iPad and in landscape if iPhone. Probably because the view has not been created yet.

Disclaimer & Support

I’m not Yoda when it comes to iPhone development. I just like sharing my thoughts and experiences with other developers. If I’ve made a mistake, email me and ill update the blog if I have time. I disabled comments because of spammers.

If this was helpful, please support my ass by buying one of my 99 cent apps. Search for “Planet Sucko” in the iTunes store.

Blogging from my shiny new iPad… Star Trek style…

April10

I’m currently using the Wordpress app, blogging to my Wordpress blog. This device reminds me of something out of Star Trek. I feel like Jorde Laforge or Lt. Data typing away with one hand on a thin device with a virtual keyboard.

I’m just not as fast because I’ve only been practicing with one hand for a couple of days. One hand typing isn’t too hard on a virtual keyboard about 8 inches wide. The keys are large enough to not make many mistakes and if you do, auto correction knows what you meant.

Virtual keyboard, one hand typing, and a little bit of voice recognition is all you need.

The future just started!

posted under iPhone | No Comments »

Nexus One: Second Thoughts

March6

I saw a random lady next to me holding a Nexus One. Having never actually played with the device (except in the emulator), I uninhibitedly asked her if I could touch her phone. Under normal circumstances it would have been borderline creepy, but she was also a gadget geek and totally knew what i meant.

It felt really nice holding it in my hand. It was heavy (which i like), yet thin and smooth. Very solid. Very Sleek. The trackball like I imagined seemed out of place. In fact, it almost cheapened it.

Performance wise, it was no different than the Motorola Droid… chunky… And unlike the iPhone, it still lacks the intimacy between the hardware and OS. Like a truck driver in a race car. It works fine, but is unlikely to win a race. If you dont already own an iPhone (owned… not played with for a little), you’ll probably be impressed.

The hardware does feel impressive… and I’m looking forward to Google’s next rev.

Flex: Drawing API and UIComponent

February19

I’ve been reading a lot about drawing circles and lines using the Flash Player drawing API. Most of the examples out there are pure ActionScript 3.0 Flash Player APIs. When trying examples and sample code in Flex, I kept getting run-time errors when i try to add the drawing object to a DisplayObject with addChild().

For Example:


var line:Shape = new Shape();
line.graphics.lineStyle(4, 0xffffff, .75);
line.graphics.moveTo(0, 0);
line.graphics.lineTo(100,100);
this.addChild(line);  // Gives Errors in Flex

So basically, Flex DisplayObject’s cannot be drawn on. Instead, you need to draw on a UIComponent. Here are 2 suggestions to achieve this.

Solution 1:
In your mxml document, add a UIComponent.

<mx:UIComponent id="uic" width="100%" height="100%"/>

And add your drawings to that.


var line:Shape = new Shape();
line.graphics.lineStyle(4, 0xffffff, .75);
line.graphics.moveTo(0, 0);
line.graphics.lineTo(100,100);
uic.addChild(line);

Solution 2:
Use code and create the UIComponent.


var line:Shape = new Shape();
line.graphics.lineStyle(4, 0xffffff, .75);
line.graphics.moveTo(0, 0);
line.graphics.lineTo(100,100);
var uic:UIComponent = new UIComponent();
uic.addChild(line);
this.addChild(uic);

posted under Flex | No Comments »

Flex: Creating an Image Reflection Effect

February11

Here’s a quick one on how to create an image reflection effect in flex.

In your mxml document, create 2 image objects, one for the main image and the other for the mirrored image.


<mx:Image id="mainImg" />
<mx:Image id="mirrorImg" />

Next, let’s create a bind-able string for the image path and bind the image path to the source of both image display objects.


[Bindable]
private var imgpath:String;


<mx:Image id="mainImg" source="{imgpath}" />
<mx:Image id="mirrorImg" source="{imgpath}" />

This will create 2 images that are identical.

Finally, add the bells and whistles to make the mirrored image look like a reflection.


<mx:Image id="mainImg" source="{imgpath}" scaleContent="false"/>
<mx:Image id="mirrorImg" source="{imgpath}" scaleContent="false" scaleY="-1" alpha=".3" top="{mainImg.height*2}"/>

Setting scaleY=”-1″ will create a vertical flip on the image.  Setting alpha=”.3″ will create a faded effect.  Setting top=”{mainImg.height*2}” aligns the mirrored image to the bottom of the main image.

The final product should look something like this.

For added effect, you shorten the reflection.  There are many ways to do this, but a quick and dirty way is to wrap your image and reflection with a canvas and setting the height to be shorter.


<mx:Canvas height="140" verticalScrollPolicy="off">
<mx:Image id="mainImg" source="{imgpath}" .... />
<mx:Image id="mirrorImg" source="{imgpath}" .... />
</mx:Canvas>

Don’t forget to set verticalScrollPolicy=”off”…  Otherwise the vertical scrollbar will show up.

If you want to get real tricky…  You can apply a gradient mask to your reflection so it looks like this.

If you don’t know how to apply a gradient mask, check out my tutorial on Masking Display Objects.

posted under Flex | No Comments »

iPhone: Loading Images from the Web

February10

Here’s an easy one…

How to load an image from the web on the iPhone.


image = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: @"http://www.planetsucko.com/images/myimage.jpg"]]];

posted under iPhone | No Comments »

Android: Playing Sounds Quick and Dirty

January9

Here’s a quick one.

To play sound within your andriod app, Put the sound file into the res/raw folder of your project.

And do this:


    MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
    mp.start();

To stop playback:


    mp.stop();

To replay the sound:


    mp.reset();
    mp.prepare();
    mp.start();

posted under Android | No Comments »

Flex: Masking Display Objects

January7

A mask defines the viewable area of a maskee display object.  In this example, we will be using a image mask to mask another image.  Please note that masks are not limited to images.  Any display object can be used to mask another display object.

Step 1: Create the Image Mask

When creating an image mask, you are actually using the transparency of image to define the area the mask will reveal.  Thus, an image mask must be a in a format that supports transparency, either GIF or PNG.  The main difference between the two file types in terms of masking is that PNGs support gradients.  If your mask does not require a gradient, you should use GIF.  The file size will be much smaller(since your color index will only require 2 colors.

In photoshop, create a mask by drawing the area you want to reveal and export as either a PNG or GIF.  The color will not affect the mask itself since it is dependent on the transparency.  However, using multiple colors will affect the filesize of your mask.

Step 2: Create the Image to be Masked

The image can be in any format flash supports (JPG, PNG, GIF).  As I mentioned above, the mask and the maskee is not limited to an image and can be any display object.

Step 3: Apply the Mask

When applying the mask in flex, both the mask and the maskee can be either embedded or linked.  Having a mask linked is extremely powerful because it allows for dynamically masks which can be loaded at runtime.


<mx:Image source="images/my_maskee.jpg" x="300" y="300" mask="{myMask}" cacheAsBitmap="true" />
<mx:Image source="images/my_mask.png" x="300" y="300" id="myMask" cacheAsBitmap="true" />

Additional Notes:

When using a PNG mask (gradient),  you need to make sure that you set cacheAsBitmap=’true’ on both the mask and the maskee (object being masked).  If you are using a GIF mask (no gradient), you do not need to set cacheAsBitmap=’true’ on either objects.

posted under Flex | No Comments »

Nexus One: Inital Thoughts

January7

Alright, I’ll be honest, you had me at hello…  but once I got to know you…

I’m really tempted to get an unlocked Nexus One.  I’m thinking I can swap the Sim card from my iPhone and use it on the weekends.

But I was totally turned off by the trackball.  People tell me that having a trackball makes navigating Web pages faster and prevents fingerprint smudges.  But having a trackball is like saying, “We are not confident in our UI capabilities” or “I’m not 100% ready to be a next generation phone” or “I don’t get it…  I’m trying…  but am having problems understanding”  OK, enough about the trackball.

Being both an Android and iPhone developer, I wasn’t too impressed with the Android OS on Droid.   But the Nexus One made me do a double take.  The Nexus One looks almost as sexy as the iPhone…  Almost but not quite…  This coupled with Android 2.1, is well…  again…  almost as good as the iPhone.

I’m a huge Google fan, but seriously Google…  you had 2.5 years, the most brilliant engineers in the world, a ton of money …  and all you could do was come close?

Ok, that was a bit harsh…  Google, I’m grateful for all the great products you’ve given to me for free.  You’ve changed my life and the world.   I love you so much, I have you setup as my homepage.  I interact with you in some way every single day.

Will I trade my iPhone in for Nexus One?  NO.

Will I buy an unlocked Nexus One to play with and maybe use in addition to my iPhone?  Heck yeah! But only because I’m a developer, make tons of money, and don’t have any kids to spend it on.

iPhone vs. Android: History is repeating itself

January6

For mobile application developers, these are exciting times!  The new generation of smart phones makes the old handsets look like command line DOS.   And it’s opening doors for a new generation of applications as well as a new generation of application developers.

Both Google and Apple (and maybe Microsoft one day) will be industry leading forces in the smartphone market.   But as I watch  Google and Apple battle it out, I can’t help but wonder… is history repeating itself?

Google is doing what Microsoft did with Windows by taking an open approach with their Android OS.  So what if Apple has the better   OS?  Android will dominate in the years to come simply because Apple closed its platform.

In the 70s and 80s, we saw how Microsoft reaped the benefits of Apple’s innovations.   Unlike Mac OS, Windows ran on almost everyone’s hardware.   As popular as the iPhone is, it only accounts for a fraction of all the handsets in the world and Apple is just one of many hardware manufacturers.

Android is not a killer OS.   However, an open approach will surely create incentives for hardware makers and software developers alike.

Is history repeating itself?   One thing is for sure, Apple is…  Oh Snap!

posted under Android, iPhone | No Comments »
« Older Entries