Tuesday, March 1, 2011

Adding JS code to your iPhone projects

IF you ever had a problem like this before, then there is a simple solution.

!! Warning: no rule to process file '$(PROJECT_DIR)/SomeJSFile.js' of type sourcecode.javascript for architecture i386

You can just ignore this warning, as you know that it isn't going to compile this code anyway.

But another odd thing you may think is that

NSString *path = [[NSBundle mainBundle] pathForResource:@"SomeJSFile" ofType:@"js"];

doesn't work either. It will always return nil.

Go to targets, and look under Compile sources, and drag the JS file into Copy Bundle Resources. And Bingo! Both issues resolved.

The sun is shining again.

Friday, February 4, 2011

Finding Missing Snapshots in Xcode

The snapshot feature in XCode is very convenient way to change code in a project to try something out, and easily revert the changes (remember to clean all before a build and run). It is not a substitute for source code management like GIT or SVN, but it is really fast to change back and forward between versions - especially when you have a project manager who wants quick changes on previous released versions and then get back to the new features.

But there are times when things can go a bit wrong. For example, you need to spring clean your drive when it is running out of space and so you change around the project directories.

Then look at all the snapshots, and SHOCK! HORROR! All gone! What happened? Where did they go?

Of course, they are not gone, it is just that they are not linked up to the new paths for the projects. The good news is that this can be easily fixed.

XCode stores all the snapshots in a sparse image - an OS X way of having a dynamically expandable disk image. This is automatically mounted each time you startup XCode. It is located under the Library folder in your user account.


An easy way to see sparse image location is to launch Disk Utility. This indicates the mount point.

/private/var/folders/Rt/RtLAi33nHOmxhqgrelqmWk+++TM/-Tmp-/XcodeSnapshots


As the /private directory path is hidden in Finder, use Terminal to cd to the path.


But there is a problem. if you try to cd into the "-Tmp-" dir, you can't.


Macsat:RtLAi33nHOmxhqgrelqmWk+++TM ronanocsono$ cd "-Tmp-/"

-bash: cd: -T: invalid option

cd: usage: cd [-L|-P] [dir]


You can cd to the full path though, so do that. Next open the file SnapshotArchive.plist and check for the project paths that have changed.

You can open this directory in Finder if you type the "open ./" command.

See in this file that there are only 2 critical paths that need to be changed for each snapshot:

<key>SourceDirs</key>
<array>
<string>/Users/ronanocsono/Documents/code/herriazsoto/trunk/OmmWriter</string>
</array>

and

<key>ProjectPath </key>

<string>/Users/ronanocsono/Documents/code/herriazsoto/trunk/OmmWriter/OmmWriter.xcodeproj</string>


Make the changes and save the file. Quit XCode and restart it. Your snapshots are restored!

At a boot note, if you were wondering why your Time Machine backups take so damn long and the files are huge, consider that all the snapshots from XCode are stored in one sparse disk image - and this is considered a single file. If you make any changes to this then the next backup will have to save the whole sparse image. For example, a project I am working on is say 25MB of code and some images. I have been making snapshots for 2 years. This is now a total size of 964MB that must be backed up in TimeMachine. It is probably better to only make snapshots at a minimum, and delete the ones you don't need. And of course a clean up of the snapshots of projects dumped is a good idea.










Thursday, October 14, 2010

Security policy error

run

Running…

Error launching remote program: security policy error.

Error launching remote program: security policy error.

The program being debugged is not being run.

The program being debugged is not being run.


If, when you are in the middle of debugging an app on iPhone or iPad, this error catches you, check the mobile provisioning profiles installed on the device and delete any ones that may be expired. Even though they would have nothing to do with the current project you are on, it blocks the device like a poison.

Monday, October 11, 2010

Hint: iPhone / iPad plist properties

If you are trying to add additional properties to the info.plist of a project, but the automatic plist type seems to be wrong, the fix for it is a simple trick.

ctrl-click the plist type to open as plain text file, then to text property list, and then from the menu select View > Property List Type > iPhone Info.plist.

If the values are not selectable, just repeat the process. It seems like a strange bug in Xcode.

Saturday, January 23, 2010

Simple internationalization / localization with LWUIT and JME

If you want your application in a range of languages, it is really simple using the LWUIT framework.


Create a resource file using the resource editor.

- create a new res file.

- select the L10N tab and click the plus button to create a new localization file (call it "Lang")

- add locale: "es".

- add property... and so on.


Note that the soft key bar labels must be defined in this file. For example when using a pop up menu, "Menu", "Select" and "Cancel" are displayed in the soft key bar. These should be localized using a resource file.


For example, add property "Menu", and for the locale "es", save as "MenĂº".

Key: "Select", value "Seleccionar". And so on.


For this example, save the resource file as "lang.res" and in the project, select Properties and then under build > Libraries and Resources, select "add folder".


In the midlet startApp method call:

try {

r = Resources.open("/lang.res");

UIManager.getInstance().setResourceBundle(r.getL10N("Lang", "es"));

} catch (IOException ex) {

ex.printStackTrace();

}


For each the labels used in the app, LWUIT can automatically set the language. Just remember the key used when setting the label:



Label myLabel = new Label(new String(“someKey”));


Note that if you use bitmap fonts, remember to include the letters with accents if you are using them. If you forget this, then words displayed will be missing those letters.


To know the locale of the handset use:


String defaultLocale = System.getProperty("microedition.locale");


This will return a string with a format of two lover case letters and to upper case ones.

Eg: en-US, es-ES.


Use the first 2 letters for the language in the res file.


if(defaultLocale.length > 2) {

defaultLocale = defaultLocale .subString(0,2);

}



UIManager.getInstance().setResourceBundle(r.getL10N("Lang", defaultLocale));


To test this out, go to the preferences in the WTK, select i18n and set the locale to "es-ES".



Other localizations issues can be handled by I18N API, if present. JSR 238 helps in date and currency formatting.


See http://www.ibm.com/developerworks/library/wi-globalapps/index.html


Tuesday, November 24, 2009

Getting a better picture in the emulator

It came to my attention on various web sites that when running demo apps using the WTK emulator (DefaultColorPhone for example) color gradients are displayed in low bit depth, and banding results.

This is easily fixed by changing the color depth of the device in the properties file by adding extra '0's to it.

On WTK 2.5.x it is at: <installDir> /wtklib/devices/DefaultColorPhone and open the properties file. I haven't checked where it is in the new WTK 3.x.

Change both colorCount=0x1000000 and alphaLevelCount=0x1000. The color gradients are now displayed in their full glory.

Wednesday, October 28, 2009

Viewing PNG files inside .ipa files

This is mainly for the curious people out there wanting to play around with iPhone apps downloaded from the App Store.

As many now know, and iPhone app consists of a zip file renamed with a the ‘ipa’ extension. On Macs all iPhone apps are downloaded to the users Music/iTuenes/iTunes Media/Mobile Applications folder.


To open the file, go to terminal and cd to that directory.

> cd “Music/iTunes/iTunes Media/Mobile Applications”

> mkdir ~/tmp

> cp [some iphone app].ipa ~/tmp/tmp.zip

> cd ~/tmp

> unzip tmp.zip

> cd Payload/[name of app].app

> cp *.png ~/tmp

> cp *.jpg ~/tmp

... and so on.


If you try to open the PNG files you will find that they are not normal PNG files, but rather “iPhone optimized” versions.


A good explanation can be found here:


http://modmyi.com/wiki/index.php/Iphone_PNG_images


and here:


http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html



A quick check for each of the PNG files can be done using the ‘strings’ command.


> strings [someImage].png


If this then returns with a line starting with ‘CgBI’ you know this has been optimized. A normal PNG image should always start with ‘IHDR’


Also you can check an image using the ‘file’ command:


> file testImage.png

testImage.png: PNG image data, 805314566 x 396263525, 0-bit grayscale,



To fix these images you can use the tool provided here (source code only):


http://www.cyberhq.nl/2007/07/05/iphone-png-fixer-upper.html


To compile this project you will also need to install libpng


http://ethan.tira-thompson.org/Mac_OS_X_Ports.html


Once installed copy over the png.h file from /usr/local/include to some place in your home folder. Then open the iPhonePNG project and fix the path to png.h and build.

Then copy the binary found in the build/Release folder to a location in your path, say ~/bin

(or add it to your path with > export PATH = $PATH:~/bin )


A simpler approach is to use the download from http://www.newsfirerss.com/blog/?p=176

Both source code and a binary are provided.


But an even more elegant approach is provided by atPurpose, a Canadian developer. See

atPeek


This app enables viewing the PNG resources directly, without having to convert them.


I haven’t tried the paid-for app as yet as it requires OS 10.6 but it looks very slick. At the bottom of the page there are 2 QL plug-ins and are free to download. They can be just placed into the /Library/QuickLook folder and should work immediately (check this).



Testing iPhonePNG


Usage for this app is simple adding the name of the PNG file to it and it will then append “-Decoded” into the name when completed. IF the image is not optimized it will give the following error:


ZLib error! -3

libpng error: Extra compressed data

[read_png_file] Error during read_image


However, the output file will be created anyway and will only contain garbled data.


Once the image has been decoded you can verify this with the ‘file’ command:


> file testImage-Decoded.png

testImage-Decoded.png: PNG image data, 50 x 33, 8-bit/color RGBA, non-interlaced



You can use the Quick Look plugin directly from the command line also if you so choose.


> qlmanage -p image.png >& /dev/null


For more info on qlmanage see:

http://www.macworld.com/article/131923/2008/02/qlterminal.html


This means that you could run a shell script to check each PNG image for "0-bit" using the file command and then if found call iPhonePNG to convert them.



Here is a small Perl script that with convert all the images in the current directory or a single image if it is specified as a parameter:




#!/usr/bin/perl -w

my $file = shift;
my @files = `ls -1 | grep png`;
my $iphonepng = "~/bin/iPhonePNG";
my $pattern = "0-bit";

if($file ne '') {
&fixPng($file);
} else {
# convert all files that are optimized.
foreach my $imageFile (@files) {
&fixPng($imageFile);
}
}

sub fixPng
{
my $thisFile = shift;
my $file_check = `file $thisFile`;
if($file_check =~ m/$pattern/) {
chomp($thisFile);
print "Convert: $iphonepng $thisFile\n";


`$iphonepng $thisFile`;
# move the decoded file to the original file.
my $decodedFile = $thisFile;
$decodedFile =~ s/.png/-Decoded.png/;
`rm $thisFile`;
`mv $decodedFile $thisFile`;
}
}




Place this in a file 'convert.pl' and then

> chmod +x convert.pl

> ./convert.pl [optional image file]


This will have now converted either a single image passed as a parameter, or all the images in the current directory.