Friday, 30 March 2012

Can't get Unity3D 3.5 to work on my iPhone for XCode 4.3.1 [Updated]??

Unity 3D is having a special offer to download Unity3D 3.5 for free. I tried it, installed on my MacBook Pro. But can't get it to run properly on my iPhone 3GS, tried friend's iPhone 4, also same issue. I can see the splash screen comes up ok, but then it crashed, the screen dump is as below.

At first, this was with the demo project AngryBots. I thought may be it's too complicate, so I tried that tutorial from Ray Wenderlich. Even with a blank scene in a brand new project, it still crashed when I tried to run it on my iPhone.....

Any one got any idea how to fix that? Looks like 3D Game development is not as easy as I first thought...

[Update 02/04/2012]
After some research, actually most of time spent in learning about transferring my developer profile from MacBook to old box (OS X 10.6.7 with XCode 4.0), I was finally able to get the demo project AngryBots running on my iPhone 3GS (iOS 4.3.5), yeah!

Lucky I left the phone with old version as if I have updated it to iOS 5, probably can't get it to run with XCode 4.0. I can understand Apple would like to push for everyone to upgrade all their devices to the latest version, but to be more flexible, there should be options which allows developers to "down grade" their iOS device to older version, plus should also allow XCode 4 on Snow Leopard to run latest XCode (4.3.1), well, that's a different topic...

So, while waiting for Unity to fix the issue with XCode 4.3.1, at least I got a backup work around to play with. Who says those old boxes are useless? :-)

Screen dump from iPhone 3GS shown below:

[Update 25/04/2012]
I think the link about the problem has been updated to this link

It says:
All these issues were fixed by Unity 3.5.1f2 release and we highly recommend upgrade to it. 
This release also adds iPad3 (aka The New iPad) high-res splashscreen and icon support. 

[Update 27/04/2012]
Tested with Unity 3.5.1 and confirmed it's working ok now. Now, how do you do Hello World in Unity?
Damn, a lot more new things to learn....

Sunday, 11 March 2012

Be ware of issue with Microsoft Word

Was following the example by Sean Berry on Ray Wenderlich's site about how to Localize an iPhone app, and found it quite interesting.

I was playing around with Google translate on my PC to translate a few text messages to Japanese. Urh... no, I don't understand anything about Japanese, so I got absolutely no idea what it says...

As Notepad can't copy those special characters, I just copy and paste it into a Microsoft Word document.

However, after I copied the file to Xcode on my Mac, I was then stuck with this strange error for a while: "Validation failed: The data couldn't be read because it has been corrupted." What the???!!!

I tried a few things (remove a few lines here and there) and finally confirmed it's something to do with these few lines... Then stared at it for a long time as I got no idea what those characters said...

Finally, I noticed the colour difference with the part as highlighted below. The ending semi-column should be in black colour, not red. Why? because bloody Microsoft Word converts the double quotes to special characters that Xcode can't recognise! ^$$@$%#^%%&*!

Friday, 9 March 2012

Yes! XCode 4.3.1 (4E1019) comes with iPad Retina (a.k.a. iPad 3) simulator!

Just installed XCode 4.3.1 (4E1019) and as expected, it comes with iPad Retina (a.k.a. iPad 3, the "new" iPad) simulator, YES!

Unfortunately the resolution is just too high (I think about 1536x2048 in portrait and 2048x1536 in landscape) for my 13" MacBook Pro, even if I adjusted the scale to Max of 50%, it's still too big for the screen... I wish apple can also provide another 25% or 10% scale, otherwise developers shouldn't buy 13" MacBook Pro or Mac Air as the screen is too small....

As it's installed under "Application" instead of "Developer" as in version 4.2, it took me a while to find it.

Also noticed it only comes with 5.1 simulator, you have to install the 4.3 and 5.0 simulators separately.

As it requires OS X 10.7.3, make sure you upgrade your Mac OS to the latest version.

Any way, surely got a few more things to try and extra huge images to create...

[Updated 9/3/2012 with images and screen resolution info added]

Friday, 2 March 2012

App Store going to have 25 billion download!

25 billion download coming soon! Who is going to win??!!

Insurgent Games released all their games as open source!

In case you are not aware, Insurgent Games kindly released all their games as open source. Further info available in this link.

Would another good source to learn new techniques as some of them used GameSalad and some used Cocos2D-iPhone.

It's sad but true as they mentioned -
For a couple of years they happily made iPhone and Android games. They quickly realized that unless you’re incredibly lucky, it’s hard to make enough money developing indie mobile games to pay San Francisco rent. So Micah got a full time job and Crystal moved on to other things.

Looks like being a full time indie developer and make a living out of it is indeed not a simple thing...

Tutorial - How to setup MathJax locally - "slim" edition

This post is a follow up of the previous MathJax tutorial, but with extra settings to make it "slimmer" as suggested by Davide Cervone, plus using the latest 2.0 release instead of the previous 1.1a version.

Also, in case you are creating multiple projects all using MathJax, I think it might be easier to manage if you "don't" copy the whole MathJax library into your project, as it makes your code base smaller. Of course this comes at the price that if someone copied your project to another machine without MathJax or if it's in different location, there will be some complications - but should be still manageable.

Ok, let's start.

Step 1. Same as before, start a new project in Xcode with single view, I call mine "MathJaxLocal2".

Step 2. Download MathJax from this link, under "Downloads for Local Installation" section, select the link which at this time of writing, says "Current Version: MathJax-2.0 (17.6MB)".

Step 3. Expand the downloaded .ZIP file. My downloaded .ZIP file is called "" and the expanded folder is "mathjax-MathJax-c9db6ac". Again to make it easier to differentiate between different version, I renamed the folder to "mathjax-MathJax-v2.0".

I checked the folder size using "Get Info", it says "Size: 21,895,871 bytes (136.6 MB on disk) for 30,963 items". Holy sugar, that is a lot of files!

Step 4. Now the fun part - trim all the fat!! Don't worry if you made a mistake or stuffed up something, as we still have the .ZIP file as backup. The things I deleted are listed below:

Delete everything under the following folders (including the folder itself):
4a. "mathjax-MathJax-v2.0/fonts/HTML-CSS/TeX/png"
4b. "mathjax-MathJax-v2.0/unpacked"
4c. "mathjax-MathJax-v2.0/test"
4d. "mathjax-MathJax-v2.0/docs"

Checked the folder size again, it's now "Size: 7,705,058 bytes (9.2 MB on disk) for 739 items". Mumm, much better, but still a long way to go from the "2.5 MB" target? Let's do some more research...

Following the info mentioned here, I also deleted the following 2:

4e. "mathjax-MathJax-v2.0/fonts/HTML-CSS/TeX/svg"
4f. "mathjax-MathJax-v2.0/jax/output/HTML-CSS/fonts/STIX"

Checked the folder size again, now it says "Size: 6,191,493 bytes (7.2 MB on disk) for 492 items"... I could have remove a few more ".js" files but they are all quite small and won't make much difference, plus don't have time to do further research, so will leave it as it is for now. At least we are far below the 20MB limit!

Step 5. Edit the config file "mathjax-MathJax-v2.0/config/default.js" using any text editor

5a. Find this line

imageFont: "TeX",

add "//" at the front to disable it, then add a new line below. don't forget the "," at the end

imageFont: null,

5b. because we deleted "4f." above, I checked the config file and confirmed there's a "imageFont:null" inside the "HTML-CSS" section. So no action required for this step.

Step 6. Next is to add the library to your project. Drag and drop the whole "mathjax-MathJax-v2.0" folder into your Xcode project. At the popup screen as shown below, make sure you "disable" the option "Copy Items into destination group's folder (if needed)". And "select" the "Create folder reference for any added folders". Otherwise the folder structure won't be created properly.

As shown below, still shows the folder in blue colour, same as previous one. So how do we know if it copied the whole library over or just created a reference link?

If you look inside "Finder", first compare with the previous "MathJaxLocal" folder above, you can see there's no "mathjax-MathJax-v2.0" folder in the new "MaxJacLocal2" project, and the folder size is only 53KB. This confirms it's using reference link. Good job!

Step 7. Finally the code change - I am combining all code changing steps into one as it's exactly the same as previous project (except folder name difference in step 7c).

7a. add a UIWebView declaration at the beginning of your UIViewController file.

UIWebView *myWebView;

7b. add the new method that handles writing HTML file locally "writeStringToFile".

-(void)writeStringToFile:(NSString *)dir fileName:(NSString *)strFileName pathName:(NSString *)strPath content:(NSString *)strContent{
    NSLog(@" inside writeStringToFile, strPath=%@", strPath);
    NSString *path = [dir stringByAppendingPathComponent:strFileName];
    NSString *foo0 = @"<html><head><meta name='viewport' content='initial-scale=1.0' />"
"<script type='text/javascript' src='";
    NSString *foo1 = @"?config=TeX-AMS-MML_HTMLorMML-full'></script>"
    NSString *foo2 = @"</body></html>";
    NSString *fooFinal = [NSString stringWithFormat:@"%@%@%@%@%@",foo0,strPath,foo1,strContent,foo2];
    NSLog(@"Final content is %@",fooFinal);
    [fooFinal writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];


7c. last change is add the following code into your "viewDidLoad" or whichever method which you think appropriate. Same as before, 2 examples from MathJax web site included, can change it to see the differences. 1st one is for "TEX" and there's more work as you have to change all the single slash "\" to double slashes "\\", the 2nd one is for "MathML". Please note that the folder name has changed...

     //content copied from
     NSString *xContent = @"<p>\\["
     "\\left( \\sum_{k=1}^n a_k b_k \\right)^{\\!\\!2} \\leq"
     "\\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)"
     "\\frac{1}{(\\sqrt{\\phi \\sqrt{5}}-\\phi) e^{\\frac25 \\pi}} ="
     "1+\\frac{e^{-2\\pi}} {1+\\frac{e^{-4\\pi}} {1+\\frac{e^{-6\\pi}}"
     "|{1+\\frac{e^{-8\\pi}} {1+\\ldots} } } }"
    NSString *xContent =@"When <math><mi>a</mi><mo>&#x2260;</mo><mn>0</mn></math>,"
    "there are two solutions to <math>"
    "<mo>+</mo> <mi>b</mi><mi>x</mi>"
    "<mo>+</mo> <mi>c</mi> <mo>=</mo> <mn>0</mn>"
    "</math> and they are"
    "<math mode='display'>"
    "<mi>x</mi> <mo>=</mo>"
    "<mrow> <mn>2</mn><mi>a</mi> </mrow>"
    //temp file filename
    NSString *tmpFileName = @"test1.html";
    //temp dir
    NSString *tempDir = NSTemporaryDirectory();
    NSLog(@"tempDirectory: %@",tempDir);
    //create NSURL
    NSString *path4 = [tempDir stringByAppendingPathComponent:tmpFileName];
    NSURL* url = [NSURL fileURLWithPath:path4]; 
    NSLog(@"Path=%@, url=%@",path4,url);
    //setup HTML file contents
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"MathJax" ofType:@"js" inDirectory:@"mathjax-MathJax-v2.0"];
    NSLog(@"filePath = %@",filePath);
    //write to temp file "tempDir/tmpFileName", set MathJax JavaScript to use "filePath" as directory, add "xContent" as content of HTML file
    [self writeStringToFile:tempDir fileName:tmpFileName pathName:filePath content:xContent];
    //create UIWebView
    CGRect webRect = CGRectMake(10,10,300,400);
    myWebView =[[UIWebView alloc] initWithFrame:webRect];
    myWebView.scalesPageToFit = YES;
    myWebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
//this line no longer required
//myWebView.delegate = self;
    NSURLRequest* req = [[NSURLRequest alloc] initWithURL:url]; 
    //original request to show MathJax stuffs
    [myWebView loadRequest:req];
    [self.view addSubview:myWebView];
    //this line no longer required if using ARC
    //[req release];

Step 7d no longer required
7d. Change the "ViewController.h" to add the "<UIWebViewDelegate>" at the end. Without this, you will receive a warning about the "Assigning to 'id' from incompatible type 'ViewController *'".

@interface ViewController : UIViewController <UIWebViewDelegate>

That's it, you can now run the project. The speed was extremely fast - definitely within a second - much, much faster than the previous one.

A few screen dumps shown below. First the iPhone one as before:

I also tried device rotation - in landscape mode as shown below:

Then another one I didn't try last time - the retina display version of iPhone - both portrait and landscape.

And yet another one I didn't do last time, iPad test!

Then the iPad landscape test.... Urhhh... Huston, we have a problem. The bottom part was cut off??!!

Something wrong somewhere, as it's not happening in iPhone... Strange...

Later, I found the problem. It's all because of this line:

CGRect webRect = CGRectMake(10,10,300,400);

After I changed it to bigger size:

CGRect webRect = CGRectMake(10,10,self.view.bounds.size.width,self.view.bounds.size.height);

Everything works... Yeah! Mission accomplished!

Ok, I was too excited with the excellent result... Calm down a bit...

A few things:

1) I still get that annoying warning "Assigning to 'id' from incompatible type 'ViewController *'"...

2) I didn't try the MathML example as it's 12:37am now, still have to go to work tomorrow morning... Will leave that with you...

As usual, hope you learned something from this tutorial and let me know if you have any questions or any better ideas (e.g. to cut it down to 2.5MB or get rid of that warning...)!

Off to bed now...z.z.z.z.z.z....

[Update 21/03/2012] This step no longer required
[Update 02/03/2012] I found the fix to get rid of the warning. Just need to change this line in "ViewController.h" header file

@interface ViewController : UIViewController

to this

@interface ViewController : UIViewController <UIWebViewDelegate>

Will also update the steps above (step 7d added) to cover this.

[Update 21/03/2013]
I have shared the source project at this link. Please note that as it's expecting the MathJax files in a separate directory, you might need some changes to make it work as your directory structure might be different from my machine.

Also please note that the latest version of MathJax is v2.1, and the example given above was using v2.0.

[Update 21/03/2013]
I tried MathJax v2.1 on Xcode 4.6 and following the same steps above, got it working on iPhone/iPad 6.1 simulator and on my iPhone 5 as well. Please see this post for other further info.

I think if you have to time to do more research, for example, follow steps mentioned in this post by Davide Cervone you should be able to trim down even more! Have a go and welcomed to share your experience with everyone.

[Update 10/May/2015]

Thanks to everyone who visited this blog. A few friends asked about doing the same example in Swift. Unfortunately I am quite busy with other stuffs at the moment and didn't really spend much time on learning Swift. Therefore not confident that I can provide any good quality Swift example yet.

However, there is this example from source which shows an example about "UIWebView load local html" and that is basically what we are doing here. Please try to change the content so that it covers the MathJax stuffs and that should be it.

Thursday, 1 March 2012

Not comfortable with result of UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)

Found that if I use the following method to check if the device orientation has changed, the result is not quite accurate.

UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)

Specially when you lay the iPhone/iPad down flat on the table, then slightly lift one side up and down. When you reached certain angle the result will change, specially bad with the iPad.

After a few trial, I found the "self.view.bounds.size" is actually more accurate in indicating whether it's in landscape of portrait mode, and have to combine the two.

Any one has similar experience or better idea?