Adding a Background Image to and/or Changing the Tint Color of the iPhone Tab Bar (UITabBar)

iPhone Screenshot

The default UITabBar on iPhone has a black translucent tint which is suitable for most UI designs. However, there my be some times when you want to change the tint color, or even add a background image or pattern to the tab bar, to better suit your UI design. Here is how to accomplish this simple task:

You can change the tint color of the tab bar as follows:

CGFloat width = self.tabBarController.tabBar.bounds.size.width;
CGFloat height = self.tabBarController.tabBar.bounds.size.height;
UIView *tabBarTint = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, width, height)];
[tabBarTint setBackgroundColor:[UIColor blueColor]];
[self.tabBarController.tabBar insertSubview:tabBarTint atIndex:0];
[tabBarTint release];

The trick is to insert the subview at index 0, behind the actual view of the tab bar. Optionally, you can try changing the alpha property of tabBarTint object to fine tune the color effect you want.

With a slight variation of the above code, you can also add a pattern or a background image to the tab bar to have a more dramatic effect, as follows:

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"concave.jpg"]];
[self.tabBarController.tabBar insertSubview:imageView atIndex:0];
[imageView release];

Here, I created a UIImageView, which is a subclass of UIView, and inserted that at index 0, instead of the generic UIView in the previous example. The result is the same, the tab bar now has a background image. It is also possible to combine the two methods shown above in order to add a background image and change its tint at the same time.

You can find a sample project implementing the above code here.

Posted in Software | Tagged | 4 Comments

Redirecting NSLog Output to a File on Demand for iPhone Debugging

NSLog can be a great tool for debugging when developing iPhone applications. It outputs a formatted message to StdErr, which is the console view in Xcode by default. However, that doesn’t help much when you want to collect information in a file on a real device over several hours of real world usage. Sure, you can write separate routines to log information to a file yourself, but why muddy your code with all that extra code, when, instead, you can simply redirect existing NSLog output to a file?

Whenever you want to redirect NSLog output to a file, you can do so by using a simple freopen statement to redirect StdErr to a file, like this:

NSString *cachesDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *logPath = [cachesDirectory stringByAppendingPathComponent:@"application.log"];
freopen([logPath cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);

The above statements will cause all output for StdErr, including all NSLog output, to be redirected to a file called “application.log”. The file will be created if it doesn’t already exist, and the output will be appended to the file contents, if one already exists. If you use “w+” as the second parameter to the freopen call, the file will be truncated, its contents erased, each time this statement is called. Notice also that the file is created in <Application_Home>/Library/Caches folder, rather than the <Application_Home>/Documents folder. Caches folder is not backed up by iTunes in the later versions of iOS, and I think is more suitable for log files.

Please note that redirecting StdErr to a file will slow down your application, depending on how much and how often you output logging information. If you want to be able to redirect StdErr back to the console, you can do so by first saving the original StdErr like this:

savedStdErr = dup(STDERR_FILENO);

And then, later when you want to revert output, you can do so like this:

fflush(stderr);
dup2(savedStdErr, STDERR_FILENO);
close(savedStdErr)

You can download a sample project implementing the above ideas here.

You can retrieve the saved file easily when you connect the device to your Mac via USB. Open Xcode, click on menu item Window -> Organizer, and click on the name of your device when the Organizer window opens. You will see a list of all applications on the device on the lower right side, titled ‘Applications’. Click on the disclosure triangle to the left of your application’s name, and you should see a row titled ‘Application Data’ and if you click on the arrow to the right, you can download all of the application data on your Mac.

get_file_from_device.png

Posted in Software | Tagged | 8 Comments

BlackBerry Development on Mac OS X

tour_front.png

Recently, I started developing a new BlackBerry project at work. Naturally, I wanted to setup a build environment on my beloved MacBook Pro. BlackBerry development is Java based, and Java is cross-platform, and so I assumed it would be an easy setup. Was I wrong! It took a lot of research and trial-error; but in the end, I was successful and I wanted to share it here.

BlackBerry has an Eclipse plugin, but that plugin only works on Windows. Fortunately, it’s easy to manually setup eclipse to compile BlackBerry applications. And we can automate the whole process with bb-ant-tools. The more difficult part is to get the BlackBerry simulators run on Mac OS X. We’ll use wine for that. And we’ll use MacPorts to install wine.

Installing Eclipse, bb-ant-tools, and the JDE Plugin

First, download eclipse, unzip, and place the eclipse folder in your /Applications folder.

Then, create a workspace folder to hold your application projects and BlackBerry SDK. Personally, I prefer to keep my projects in ~/Development and I created a ~/Development/BlackBerry folder for my projects and a ~/Development/BlackBerry/SDK folder for the SDK.

You don’t have to mimic the above folder structures for your projects, nor you need to place the application in the /Applications folder, but I think this structure makes life easier for me.

Next, go to the BlackBerry development website and download the latest BlackBerry JDE component for eclipse, v4.7 as of this writing (you can download a previous version if you specifically need it).

We will not be installing the component package in a traditional way in eclipse though, as that requires a Windows environment unfortunately. Instead we’ll do a manual install, of sorts.

First unzip the downloaded package in Finder by double-clicking it. It will be unzipped into a folder of the same name. Go inside that folder and you’ll see two additional folders, features and plugins. Go inside the plugins folder and rename the net.rim.eide.componentpack4.7.0_4.7.0.46.jar file to net.rim.eide.componentpack4.7.0_4.7.0.46.zip file by changing the filename extension to zip (say yes when Finder asks you if you’re sure). Then, double click the new zip file you created and it will be unzipped into a folder of the same name. Move that folder into the ~/Development/BlackBerry/SDK folder you created earlier.

Now, fire up eclipse, select the ~/Development/BlackBerry folder as your workspace (and check ‘always use this folder’ checkbox) if you haven’t already done so, and then select Eclipse->Preferences menu to show the Preferences window.

Go to Java->Build Path->User Libraries and click New. Enter “BlackBerry 4.7″ as the library name. Next click Add JARs and browse to your ~/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/lib folder and select net_rim_api.jar file. Also make sure to set the javadoc location to ~/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/docs/api folder so that you’ll get proper documentation popups in eclipse.

userlib.png

Next, download the latest version of BlackBerry Ant Tools and unzip it. Place the folder in your ~/Development/BlackBerry/SDK folder. Next, open Eclipse->Preferences again and then go to Ant->Runtime and click Add External JARs and browse to bb-ant-tools.jar file. Click OK and close all dialog windows.

ant.png

You also need to download a Mac OS binary of the preverify.exe that is included in the BlackBerry JDE tools. The easiest way to do so is to download the mpowerplayer sdk, which includes the preverify binary for Mac OS X. Just copy the preverify executable to your ~/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/bin folder from the mpp-sdk/osx/preverify folder. You can discard the rest of the sdk files if you wish.

Finally, add the ~/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/bin to your $PATH by editing the ~/.bash_profile file as follows:

export PATH=${PATH}:/Users/aziz/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/bin

Building Your First BlackBerry App

You’re now ready to compile your first BlackBerry application on your Mac. Create a new Java project in eclipse (select File->New->Java Project). Name the project “HelloWorld”, and leave everything else untouched in the dialog box, and click Next. Select Libraries tab, click on JRE System Library and click Remove. Click Add Library, select User Library, click Next, check BlackBerry 4.7 (or whatever you named it above) and click Finish.

Create a new package, name it com.azizuysal.HelloWorld. Then create a new class and name it HelloWorldApp.java. Here is the source code:

package com.azizuysal.HelloWorld;

import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;

public class HelloWorldApp extends UiApplication {
	public HelloWorldApp() {
		MainScreen screen = new MainScreen();
		screen.add(new LabelField("Hello, World!"));
		pushScreen(screen);
	}

	public static void main(String[] args) {
		new HelloWorldApp().enterEventDispatcher();
	}
}

Now, create a build.xml for bb-ant-tools. Go to File->New->Other, select XML and name it build.xml. Enter the following:

<project name="Hello World App" default="build">
	<taskdef resource="bb-ant-defs.xml" />

	<!-- rapc and sigtool require the jde.home property to be set -->
	<property name="jde.home" location="/Users/aziz/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components" />

	<!-- directory of simulator to copy files to -->
	<property name="simulator.home" location="/Users/aziz/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/simulator" />
	<property name="src.dir" location="src" />
	<property name="build.dir" location="build" />
	<property name="cod.name" value="com_azizuysal_HelloWorld" />

	<target name="build">
		<mkdir dir="${build.dir}" />
		<rapc output="${cod.name}" srcdir="${src.dir}" destdir="${build.dir}">
			<jdp title="Hello World" />
		</rapc>
	</target>

	<target name="sign">
		<sigtool codfile="${build.dir}/${cod.name}.cod" />
	</target>

	<target name="clean">
		<delete dir="${build.dir}" />
	</target>

	<target name="load-simulator" depends="build">
		<copy todir="${simulator.home}">
			<fileset dir="${build.dir}" includes="*.cod,*.cso,*.debug,*.jad,*.jar" />
		</copy>
		<exec executable="/bin/sh">
			<arg value="-c" />
			<arg value="${simulator.home}/9530.sh" />
		</exec>
	</target>
</project>

Go to Window->Show View->Ant to show the ant view and drag build.xml file into this view. You can now run the ant scripts by double-clicking on them. Double-click the build script, and you should see a BUILD SUCCESSFUL message in your Console window in eclipse.

success.png

Running the BlackBerry Simulator on Mac OS X

As I said before, we will be running the simulator in wine and we’ll use MacPorts to install wine. So, first, download and run the appropriate MacPorts installer for your system. Once you finish installing MacPorts, open Terminal and type the following command to install Wine via MacPorts (If you get an error message when you try to run port commands, make sure your .bash_profile is updated appropriately at the end of the MacPorts installation and your PATH variable contains the path to your MacPorts installation. Also make sure that you have an active internet connection):

sudo port install wine

After wine is installed, type the following to install the winetricks package which we’ll need in order to successfully run the BlackBerry simulator.

sudo port install winetricks

You’ll notice that MacPorts will also install quite a few more packages, as wine and winetricks depend on them.

We’ll need a shell script to run the simulator in wine easily, and the easiest way to create one is to copy the included windows batch file. Copy the ~/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/simulator/9530.bat file to 9530.sh file and edit it to read as follows:

#!/bin/bash
cd "`dirname $0`"
/opt/local/bin/wine fledge.exe /app=Jvm.dll /handheld=9530 /session=9530 /app-param=DisableRegistration /app-param=JvmAlxConfigFile:9530.xml /data-port=0x4d44 /data-port=0x4d4e /pin=0x2100000A

Save the file and set its execute permission:

chmod +x 9530.sh

Now, run winetricks and select gdiplus trick. Type in Terminal:

winetricks

Select gdiplus from the menu to install it. And finally, type the following to run the simulator in wine:

~/Development/BlackBerry/SDK/net.rim.eide.componentpack4.7.0_4.7.0.46/components/simulator/9530.sh

You should now see the BlackBerry simulator running in wine:

simulator.png

You can also try double-clicking load-simulator script in eclipse now and you should be able to see your project compiled and installed in the simulator.

Bonus Tip: Installing Additional Simulators

If you want to install additional BlackBerry simulators, you can download them from the BlackBerry website and use the following commands to install them:

wine ~/Downloads/BlackBerry_Simulators_4.6.1.79_8350i.exe /extract
wine msiexec /a ~/Downloads/SimPackageInstaller.msi /qn
mv ~/.wine/drive_c/Program\ Files/Research\ In\ Motion ~/Development/BlackBerry/SDK/

Create a .sh script file as shown above to run the new simulator, and don’t forget to update your build.xml file if you want to launch your projects in the new simulator automatically.

I’ll follow up with a second post that shows how to run the debugger and a couple of other more advanced tricks.

Posted in Software | Tagged | 62 Comments

Setting Up SSH Public Key Authentication for iPhone Remote Access

Lately, after jailbreaking my iPhone and installing the toolchain on my Mac, I’ve started doing some iPhone development. Currently, due to lack of official development tools and a device simulator, the development process involves frequently loading up the app you’re coding to your iPhone. I use the scp command to copy the app bundle as shown below.

scp -r ~/iPhone/Sample/build/Release/Sample.app root@10.0.1.1:/Applications

This works fine, except that it asks for the root password each time you execute the command. And this additional step can become an annoying time-waster when you end up issuing the command literally hundreds of times throughout the course of a coding session. So, SSH public key authentication comes to the rescue! A quick Google search revealed the solution at Game Over’s wiki.

Here are the few simple steps to enable this feature (please note that you must already have the BSD subsystem and the OpenSSH apps installed on your iPhone):

1) Start up your Terminal.app and run the following command on your mac to generate the keys. Accept the defaults when it asks for a place to save the keys on your machine. Enter a passphrase when asked if you like, but it’s ok if you leave it blank too.

ssh-keygen -t rsa -b 2048

2) Now, copy the generated public key to your iPhone. Don’t forget to substitute your phone’s ip address.

scp ~/.ssh/id_rsa.pub root@10.0.1.1:~/authorized_keys

3) Next, start the Term-vt100 app on your iPhone, and type the following commands.

mkdir -p ~/.ssh
chmod 0700 ~/.ssh
mv ~/authorized_keys ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod go-w /private/var/root

That’s it. From now on, you can login to your iPhone without entering a password. Try it. Type this on your mac.

ssh root@10.0.1.1

Don’t forget to substitute your own ip address. Also note that you may be asked for a passphrase if you entered one in the first step. If you check the box to store the phrase in your keychain, you will not be asked for it anymore.

Posted in Software | Tagged | 7 Comments

Ford Promotes “Vista Windows”

ford_vista_roof.jpg

Am I the only one who sees the pun here? A recent full-page Ford Edge advertisement in Newsweek magazine boasts “Vista” and “Windows” in its headline. It seems like Ford is paying Microsoft in more ways than one for the exclusive use of their Sync technology.

Posted in Marketing | Tagged

Changing WordPress Permalink Structure

permalink.png

After adding a few pages to my blog, I realized that the permalink structure of my blog (i.e. http://www.azizuysal.com/?p=7) is a bit ugly and uninformative. Particularly, reading statistics like Google Analytics becomes more difficult as it is hard to understand which page the reports are referring to from the ugly URLs. So I decided to make a change and I checked a few of my favorite blogs for inspiration. I found out that most of them use a “/year/month/day/postname/” structure for their permalinks.

Following the simple instructions I found here, I was able to change my permalinks to a much more friendly, and informative, “/year/month/postname/” structure. I also installed the Permalink Redirect plugin for wordPress so that any external references to old style links will be redirected to my new permalinks.

Posted in Software | Tagged

Installing iPhone Development Tools (Toolchain 0.30) on Leopard for iPhone 1.1.2

hello.png

After jailbreaking my iPhone recently, I’m now ready to install the development tools. At the end of this process, I’ll finally be ready to start developing my own applications for the iPhone.

I’m using a MacBook Pro with Mac OS X 10.5.1 (Leopard). My iPhone is an 8Gb model with 1.1.2 firmware which I jailbroke recently. I have already installed the Developer Tools on my system. If you didn’t, now is the time to do so. Insert your Leopard DVD, open Optional Installs folder, open XcodeTools folder, double-click XcodeTools.mpkg to start the installation.

I consulted iPhoneDevDocs.com site for installation instructions and the required files. Though the instructions are for 1.1.1 firmware, they worked, with a couple of small changes, for the 1.1.2 firmware as well.

Fire up your Terminal.app, you’ll be using it exclusively for this installation. And finally, check your bison and flex installations, they are required for the next steps.

$ bison --version
bison (GNU Bison) 2.3
Written by Robert Corbett and Richard Stallman.

Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ flex --version
flex 2.5.33

First, check out revision 42498 of LLVM SVN and build it. If the current directory is your home folder, this will create a llvm-svn folder in it. If you want to place it elsewhere, either cd to that directory first, or type it in the command below.

svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm-svn -r 42498
pushd llvm-svn
./configure --enable-optimized
make ENABLE_OPTIMIZED=1
sudo make install
LLVMOBJDIR=`pwd`
popd

Next, get a copy of the iphone-dev from Google Code repository.

svn checkout http://iphone-dev.googlecode.com/svn/trunk/ iphone-dev
pushd iphone-dev

The above command will create an iphone-dev folder in your home folder. Now, create a folder for the toolchain and build odcctools.

sudo mkdir /usr/local/arm-apple-darwin
mkdir -p build/odcctools
pushd build/odcctools
../../odcctools/configure --target=arm-apple-darwin --disable-ld64
export INCPRIVEXT="-isysroot /Developer/SDKs/MacOSX10.4u.sdk"
make
sudo make install
popd

At this point, you need to make a copy of your iphone’s filesystem. There are several methods for doing this, as outlined here, here and here. However, I discovered that using rsync is the easiest way to accomplish this.

rsync -avz --exclude=/private/var/root/Media -e ssh root@10.0.1.197:/ ~/Desktop/iPhone/

The SSH password for root is ‘alpine’. This will copy the contents of your iPhone (except the media, i.e your songs, photos, videos, etc) to a folder called iPhone on your desktop. You must substitute your phone’s ip address, which you can find out when you goto Settings->Wi-Fi and select the name of your network on your iPhone. Please note that this will only work if your iPhone is already jailbroken, and that you’ve installed openSSH.

When the copying is done, right-click on the iPhone folder on your desktop an select “Compress iPhone”. This will create a zip file of the folder contents. Copy the zip file to a safe place in case you need it again. Also, copy the filesystem for use by the toolchain.

sudo mkdir /usr/local/share/iphone-filesystem
sudo cp -Rp ~/Desktop/iPhone/* /usr/local/share/iphone-filesystem/

You can now delete the iPhone folder from your desktop. And type the following in your terminal:

HEAVENLY=/usr/local/share/iphone-filesystem

Now, patch and install the system headers.

pushd include
./configure --with-macosx-sdk=/Developer/SDKs/MacOSX10.4u.sdk
sudo bash install-headers.sh
popd

Next, install csu.

mkdir -p build/csu
pushd build/csu
../../csu/configure --host=arm-apple-darwin
sudo make install
popd

And finally, build and install LLVM-GCC. Note that both $HEAVENLY and $LLVMOBJDIR must be set as per above instructions before attempting this.

mv llvm-gcc-4.0-iphone/configure llvm-gcc-4.0-iphone/configure.old
sed 's/^FLAGS_FOR_TARGET=$/FLAGS_FOR_TARGET=${FLAGS_FOR_TARGET-}/g' llvm-gcc-4.0-iphone/configure.old &gt; llvm-gcc-4.0-iphone/configure
sudo ln -s /usr/local/arm-apple-darwin/lib/crt1.o /usr/local/arm-apple-darwin/lib/crt1.10.5.o
mkdir -p build/llvm-gcc-4.0-iphone
pushd build/llvm-gcc-4.0-iphone
export FLAGS_FOR_TARGET="-mmacosx-version-min=10.1"
chmod 755 ../../llvm-gcc-4.0-iphone/configure
../../llvm-gcc-4.0-iphone/configure --enable-llvm=`llvm-config --obj-root` --enable-languages=c,c++,objc,obj-c++ --target=arm-apple-darwin --enable-sjlj-exceptions --with-heavenly=$HEAVENLY --with-as=/usr/local/bin/arm-apple-darwin-as --with-ld=/usr/local/bin/arm-apple-darwin-ld
make LLVM_VERSION_INFO=2.0-svn-iphone-dev-0.3-svn
sudo make install
popd
popd

That’s it, you’re done. You now have a working iphone-dev toolchain, and you can build iPhone applications from source. To test your new environment, download a copy of the HelloWorld application and build it.

cd ~/Desktop/HelloWorld/
make

Congratulations! You’ve successfully built your first iPhone app. You can now copy the “Hello” file to your iPhone via your favorite FTP application (or you can use sftp from from the command line) and execute it using the vt-100 terminal application on the iPhone.

Stay tuned for windows installation instructions. I’ll be installing the toolchain on my Windows XP machine soon.

Posted in Software | Tagged | 1 Comment