Friday, November 27, 2009

Finding keywords for your iPhone App

Having trouble coming up with more keywords to associate with your app? Trying using Google Sets.

http://labs.google.com/sets

Enter the keywords you have already thought of and see what Google can come up with for more!

Thursday, November 26, 2009

Detecting Airplane Mode on the iPhone

All,

There is a very simple way to add "airplane mode" detection to your iphone application without writing any code. You need to add a new property to your Info.plist property file called "SBUsesNetwork", set its property type to "boolean", and check the box. This will cause the iPhone to immediately present the "Disable airplane mode or use local wifi" dialog when the application starts.

To add this property, bring up Info.plist in the property list editor. Then use the "+" to add a new property. Type in the name "SBUsesNetwork" into the new property name. Then right click (ctrl-click) this property name and change its type to "boolean". Then make sure it is enabled.

Now, you may want/need to add more network detection to your application. The "Reachability" example code on the iPhone developer site provides a nice utility to help you further detect network availability. In fact, this code will allow you to monitor the availability of a specific web site and it will let you know if the reachability status changes.

Enjoy!!!

Wednesday, November 25, 2009

XCode failed to download app

If you are a new iPhone developer and you are trying to test your app on your device, you may sometimes get the error "failed to download app" from XCode. The odd thing is the app appears on the device and is runnable, but XCode failed at some point in the process of trying to launch the app was it was installed on the device. There is a simple solution:

Quit and restart XCode. This should clean it up.

Could not convert Apple ID account to iTunes store account.

So, you are trying to test your iPhone In App Purchase, and you are getting this error message when creating the test account in iTunes Connect: "Could not convert Apple ID account to iTunes store account."

This is apparently a bug in the iTunes Connect UI or server, not sure. It happens for me with both Safari and Chrome. I have not tested other browsers.

Here is the solution....Enter all of your dummy information for the test account and hit submit. You will receive this error. Next, simply change the email address to a different bogus email address and re-submit. It should work.

Another error you may see is: "The email address you entered already belongs to an existing Apple account. Please try again.". This error is more legitimate and implies the email address is already registered with Apple. Just change the email address to something different and re-submit.

Note also there is some suggestion out there that you are only allowed to have 1 test user per country. I did notice that when using different countries when setting up test users, this error did not occur. So, there could be some validity to this suggestion (even though it seems ridiculous).

Hope this helps!

Tuesday, November 24, 2009

Cocos2d Meets UIKit - you really can cross the beams

If you are getting started with Cocos2d, you are probably having a lot of fun. This is a great framework for developing games on the iPhone. But, you may find yourself wondering how to get more complex UI elements into your game. For example, you may want to collect some input from the user in a UITextField. Mixing UIKit and Cocos2d is possible! I have just scratched the surface so far, but I did come across a few articles that lead me in the right direction.

Below is a simple example of adding a UIKit Alert dialog and UITextField to a Cocos2d Scene. It turns out they play together quite well. The code below assumes you are in the "init" method of your Cocos2d Layer object. Normally, you would be adding Sprites, Labels, etc. here. But now, you want to add this dialog. Here is the code.....


- (id) init {
    self = [super init];
    if (self != nil) {

Sprite * bg = [Sprite spriteWithFile:@"blah.png"];
[bg setPosition:ccp(240, 160)];
[self addChild:bg z:0];

UIView* view = [[Director sharedDirector] openGLView];

NSString *score = [NSString stringWithFormat:@"You Scored: %d", gameScore];
UIAlertView* myAlertView = [[UIAlertView alloc] initWithTitle:score
                   message:@"High Score" delegate: self 
                   cancelButtonTitle: @"Cancel" otherButtonTitles: @"OK", nil];
[view addSubview: myAlertView];

CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0.0, 75.0);
[myAlertView setTransform: myTransform];

nameField = [[UITextField alloc] initWithFrame
                         CGRectMake(12.0, 45.0, 260.0, 25.0)];
[nameField setBackgroundColor: [UIColor whiteColor]];
nameField.text = @"Enter Name Here"s
nameField.clearsOnBeginEditing = true;

[myAlertView addSubview: nameField];
[myAlertView show];
[myAlertView release];
    }
    return self;
}


As you can see, you can get a UIView from the Cocos2d Director. Once you have that, you have entered the UIKit world. The only other trick is the "Transform" that is used to make sure the geometry is compatible. This works great for my app. There is a lot more to learn about mixing UIKit and Cocos2d. I hope to learn more in the future!

Primitive Sprites with Cocos2d

Cocos2d makes it easy to load an image into a Sprite and move it around the scene. But, what if you want some primitive sprites like circles, squares, or any other line-drawn shape. Cocos2d does provide a "drawing primitives" library to actually draw the line, circle, etc., but how do you use it like a Sprite along with your other sprites.

The answer is to create your own class that extends CocosNode and provide the simple primitive design. For example, here is a simple implementation called CircleNode. This gives you the simple ability to create a Circle of a specified radius and color, and to then treat this like any other Sprite (e.g. add it as a child to your scene, set it's position, etc.).

First, here is the class definition for CircleNode:


#import "cocos2d.h"


@interface CircleNode : CocosNode {

int radius;
int colorCode;
int priority;

}

@property (nonatomic, assign) int colorCode;
@property (nonatomic, assign) int priority;


-(id)init: (int)radius colorCode:(int)c priority:(int)pri;
-(void)draw;


@end


Finally, here is the example implementation:

#import "CircleNode.h"


@implementation CircleNode

@synthesize colorCode;
@synthesize priority;


-(id)init: (int)rad colorCode:(int)color priority:(int)pri {
if( (self=[super init]) ) {
radius = rad;
self.colorCode = color;
self.priority = pri;

// set up the geometry of this sprite
// this is necessary so the sprite indicates it's body size
// relative the center point (position)
CGSize size;
size.width = 2 * rad;
size.height = 2 * rad;
self.contentSize = size;
self.anchorPoint = ccp(0.5, 0.5);

}
return self;
}

-(void)draw {

glLineWidth(4);


//red
if (colorCode == 0) {
glColor4ub(255, 0, 0, 255);
}
// yellow
if (colorCode == 1) {
glColor4ub(255, 255, 0, 255);
}
// green
if (colorCode == 2) {
glColor4ub(0, 255, 0, 255);
}

// coordinates are relative to this sprites "position"
// the draw primitives origin are in the lower left corner relative to the anchor point
// so the center is "radius" pixels over and up on the x,y axis
CGPoint circleCenter = ccp(radius,radius);
drawCircle( circleCenter, radius, 0, 30, NO);

}

@end


There are a few important things to point out....

The draw method is where the magic happens. Simply put your drawing calls in there.

As you play with this implementation, one thing to get right is the physical characteristics of the "Sprite". For example, you need to set the appropriate "content size" of the object so that if you are detecting a "touch" of this object, the object's bounding rectangle is correct. Next, set the Anchor Point accordingly. This will establish the coordinate system for your drawing. By setting the anchor as (0.5,0.5), I am setting the anchor in the middle of the object. The (0,0) point is now in the bottom left of the object. In order to draw at the center of the circle, you would use ccp(radius,radius) as the middle of the circle.

With this simple extension of CocosNode, I have created a CircleNode that can be used like any other Sprite in the scene. You can use this basic technique to come up with your own primitive drawing Sprites. I have used it to create Arrows, and more complex drawing elements.

Enjoy!

iPhone In App Purchases

I recently integrated "In App Purchase" into my iPhone application. I'm not going to give a step by step guide here, there are plenty of those already. I wanted to share a few tips.

First, the biggest stumbling block for me was a dumb one. How do you test In App Purchases before your game is published to the App Store? In order to test, you need to register your In App Purchase in iTunes Connect. But in order to do that, you must have your App registered. This seems like a chicken and egg problem. However, the answer is simple. You need to "pre-register" your new app with iTunes. Go ahead and fill out that App Submission forms but check "Upload binary later". This will allow you to get your app registered with iTunes without actually submitting the App for review. You can go back later when the app is ready for review and update your metadata and submit your binary.

I found the "In App Purchase Programming Guide" provided by Apple to be very informative and all you really need to get it working. The "Adding a Store to Your Application" section provides step-by-step instructions and code samples that plug right into your code. Read carefully and follow the directions, and you will get it working.