Wednesday, August 27, 2008

How-To copy SDK headers to iPhone and compile SDK applications in iPhone

Pre-requisites:
(1) jailbreak iPhone with pwned firmware 2.0.x
(2) Install the following packages in Cydia Installer

  • GNU C Compiler

  • iPhone 2.0 Toolchain

  • Make

  • Link Indentity Editor

  • wget (... in order to download the following sample in iPhone)

  • zip (... in order to unzip the following sample in iPhone)



Here is the procedure on how to copy the iPhone SDK headers from your mac to iPhone GCC to have a SDK development environment in iPhone

I have installed the sdk header files to /var/sdk of iPhone

If you use Linux / Microsoft Windows, see this on how to get the header files from the SDK
http://www.theiphonewiki.com/wiki/index.php?title=Toolchain_2.0

Use this shell script in Mac Terminal to copy the installed SDK header files to iPhone directly
and you have to change IPHONEIP for your actual iPhone IP address

copySDKHeaders.sh : Select all

#!/bin/sh
IPHONEIP=10.0.2.2
sdkroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk/System/Library/Frameworks
sdkframeworks[1]=$sdkroot/AddressBook.framework/Headers/*
sdkframeworks[2]=$sdkroot/AddressBookUI.framework/Headers/*
sdkframeworks[3]=$sdkroot/AudioToolbox.framework/Headers/*
sdkframeworks[4]=$sdkroot/AudioUnit.framework/Headers/*
sdkframeworks[5]=$sdkroot/CFNetwork.framework/Headers/*
sdkframeworks[6]=$sdkroot/CoreAudio.framework/Headers/*
sdkframeworks[7]=$sdkroot/CoreFoundation.framework/Headers/*
sdkframeworks[8]=$sdkroot/CoreGraphics.framework/Headers/*
sdkframeworks[9]=$sdkroot/CoreLocation.framework/Headers/*
sdkframeworks[10]=$sdkroot/Foundation.framework/Headers/*
sdkframeworks[11]=$sdkroot/MediaPlayer.framework/Headers/*
sdkframeworks[12]=$sdkroot/OpenAL.framework/Headers/*
sdkframeworks[13]=$sdkroot/OpenGLES.framework/Headers/*
sdkframeworks[14]=$sdkroot/QuartzCore.framework/Headers/*
sdkframeworks[15]=$sdkroot/Security.framework/Headers/*
sdkframeworks[16]=$sdkroot/SystemConfiguration.framework/Headers/*
sdkframeworks[17]=$sdkroot/UIKit.framework/Headers/*
sdkframeworks[18]=/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/IOKit.framework/Headers/*
iphonesdkroot=/var/sdk
iphoneframeworksroot=$iphonesdkroot/include
iphoneframeworks[1]=$iphoneframeworksroot/AddressBook/
iphoneframeworks[2]=$iphoneframeworksroot/AddressBookUI/
iphoneframeworks[3]=$iphoneframeworksroot/AudioToolbox/
iphoneframeworks[4]=$iphoneframeworksroot/AudioUnit/
iphoneframeworks[5]=$iphoneframeworksroot/CFNetwork/
iphoneframeworks[6]=$iphoneframeworksroot/CoreAudio/
iphoneframeworks[7]=$iphoneframeworksroot/CoreFoundation/
iphoneframeworks[8]=$iphoneframeworksroot/CoreGraphics/
iphoneframeworks[9]=$iphoneframeworksroot/CoreLocation/
iphoneframeworks[10]=$iphoneframeworksroot/Foundation/
iphoneframeworks[11]=$iphoneframeworksroot/MediaPlayer/
iphoneframeworks[12]=$iphoneframeworksroot/OpenAL/
iphoneframeworks[13]=$iphoneframeworksroot/OpenGLES/
iphoneframeworks[14]=$iphoneframeworksroot/QuartzCore/
iphoneframeworks[15]=$iphoneframeworksroot/Security/
iphoneframeworks[16]=$iphoneframeworksroot/SystemConfiguration/
iphoneframeworks[17]=$iphoneframeworksroot/UIKit/
iphoneframeworks[18]=$iphoneframeworksroot/IOKit/

ssh root@$IPHONEIP "mkdir -p $iphoneframeworksroot"
scp -r /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk/usr/include root@$IPHONEIP:$iphonesdkroot
scp -r /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk/usr/lib root@$IPHONEIP:$iphonesdkroot

for index in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
do
echo "copying ${sdkframeworks[index]} to ${iphoneframeworks[index]}"
ssh root@$IPHONEIP "mkdir -p ${iphoneframeworks[index]}"
scp -r ${sdkframeworks[index]} root@$IPHONEIP:${iphoneframeworks[index]}
done


In order to avoid typing the password using ssh, you can install the ssh public key of your Mac to your iPhone using the following method

(a) keygen in Mac terminal and type (if you haven't generated it before)
Select all

ssh-keygen -t rsa


(b) create .ssh directory in iPhone (assume ip address of iPhone is 10.0.2.2)
Select all

ssh root@10.0.2.2 'mkdir -p .ssh'

then enter iPhone root password (alpine)

(c) copy mac public key to iPhone, and in Mac Terminal type
Select all
cat ~/.ssh/id_rsa.pub | ssh root@10.0.2.2 'cat >> .ssh/authorized_keys'

then enter iPhone root password (alpine)

(d) Edit the file /etc/ssh/sshd_config in iPhone

change these
Select all

#StrictModes yes
#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys


to

Select all

StrictModes no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys


(e)reboot iPhone

I have successfully compiled a modified SDK sample app UICategory (non-Interface Builder verison)

Here is the project folder to test your installation.

(i) copy it (using wget) and unzip it in iPhone
Select all

wget http://www.iphone.org.hk/attach/39773-UICatalog.zip
unzip 39773-UICatalog.zip


(ii) then run
Select all

cd UICatalog
make
make install


to build and install the project in iPhone

Friday, August 15, 2008

How To force Orientation to Landscape in iPhone

This is how to force Orientation to Landscape in iPhone.


AppDelegate.m : Select all

application.statusBarOrientation = UIInterfaceOrientationLandscapeRight;


Info.plist : Select all

<key>UIStatusBarOrientation</key>
<string>UIInterfaceOrientationLandscapeRight</string>

Tuesday, July 8, 2008

[How-to] print NSString to stdout

This is how to print the NSString to stdout so that it can display in debug console window of Xcode.


main.m : Select all

#import <Foundation/Foundation.h>

void NSPrint (NSString *str)
{
[str writeToFile:@"/dev/stdout" atomically:NO encoding:NSUTF8StringEncoding error:nil];
}

void NSPrintUTF8 (NSString *str)
{
printf("%s", [str cStringUsingEncoding:NSUTF8StringEncoding]);
}

void NSPrintMac (NSString *str)
{
printf("%s", [str cStringUsingEncoding:NSMacOSRomanStringEncoding]);
}

#if defined(TARGET_IPHONE_SIMULATOR)
#define LogMethod() printf("%s\n", [[NSString stringWithFormat:@"Simulator-[%@ %s]", self, _cmd] cStringUsingEncoding:NSUTF8StringEncoding]);
#else
#define LogMethod() NSLog(@"-[%@ %s]", self, _cmd])
#endif


int main(int argc, char *argv[]) {
NSPrint(@"Hello, World\n");
NSPrintMac(@"Hello, Mac Encoding World\n");
LogMethod();
}


This is how to print out the NSString and append to a text file.


appendtxt.m : Select all

NSFileHandle *aFileHandle = [NSFileHandle fileHandleForWritingAtPath:[@"/tmp/myapp.log" stringByExpandingTildeInPath]];
[aFileHandle truncateFileAtOffset:[aFileHandle seekToEndOfFile]];
[aFileHandle writeData:[[NSString stringWithFormat:@"Simulator-[%@ %s]", self, _cmd] dataUsingEncoding:NSUTF8StringEncoding]];
[aFileHandle writeData:[NSStringFromCGSize(contentSize) dataUsingEncoding:NSUTF8StringEncoding]];





Saturday, June 28, 2008

[How-To] Install gcc compiler in iPhone (1.1.x firmware)

Cydia is a new package management replacement to the existing Installer.app. And it now also brings the gcc compiler to iPhone in firmware 1.1.x

Although it is slow to compile in iPhone but it is stable and very native.

You can follow these steps to install the compiler and related headers and utilities:

1. Set your iPhone Auto-Lock to "Never"
2. Goto Installer and install the package called "Cydia Installer" (version 1.0). It will take some time to download and install, so you should have connected your iPhone to Wifi
3. After installation of Cydia, iPhone will reboot and you will find a new icon "Cydia" in your Home Screen. Start "Cydia" and it will tell you to update Critical Packages. Follow the instructions to "Update All"
4. After update of Critical Packages in Cydia, install the following 3 packages

GNU C Compiler
Make
iPhone 1.1.1 Headers

5. Then you can have gcc compiler in your iPhone now. You can use Mac Terminal or putty to access the terminal of iPhone and start building your application.

Please take note that after the installation of Cydia, your BSD subsystem is now changed to Fake BSD subsystem and also fixed a number of bugs. So don't update BSD subsystem from the Installer.app

You may want to try some HelloWorld example, and here is the project that you can try

copy and unzip it to your iPhone
then

cd HelloWorld
make install
./restart


Then you will have a new program HelloWorld.

To uninstall this HelloWorld

make uninstall



Enjoy!

Friday, June 27, 2008

Unoffical iPhone SDK (building iPhone OS2.0 app without using iPhone SDK)

It is possible to build iPhone OS 2.0 native application using open toolchain header and without using official iPhone SDK nor without Mac OS
Read this article
Upgrading the iPhone Toolchain


Hide Status Bar

This is how to hide the status bar in iPhone. For the Open toolchain api is available. However, for Official SDK API, edit the Info.plist is necessary.


Official iPhone OS 2.0 SDK headers version


Info.plist : Select all

<key>UIStatusBarHidden</key>
<true />

or. programmatically,

[[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO];


Open Tool Chain headers version


Hello.app : Select all


[UIHardware _setStatusBarHeight:0.0f];
[self setStatusBarMode:2 duration:0.0f];
[self setStatusBarHidden:YES animated:NO]; // hide status bar

Xcode Tips

1. Read the Xcode Workspace Guide, it is available after launching Xcode. It is under Help -> Xcode Workspace Guide

2. Make full use of Snapshots to keep different versions of the project. It is under File -> Make Snapshot

3. Make full use of code completion. It is under Xcode Preferences > Code Sense > Code Completion > Automatically Suggest _> immediate
Press esc key for auto suggestion

4. There are two ways to search for API reference from the Xcode text editor:
Option–double-click a symbol name
Select an expression and choose Help > Find Selected Text in API Reference

Command–double-click a symbol name
and goes to the header file (command-shift-w to close the header file)

5. Learn and use Refractor instead of Find & Replace

6. Use Project -> Class Browser

7. Use #pragma in source code to improve readability
#pragma mark PRINTING FUNCTIONS
To add a separator to the Function menu use:
#pragma mark -

8. Short Cut Keys in code editor
indent : Command-]
un-indent : Command-[
block select : Option key while clicking and dragging

9. Use this DEBUGLOG to replace NSLog

#ifdef DEBUGON
#define DEBUGLOG if (DEBUGON) NSLog
#else
#define DEBUGLOG
#endif


In the project settings of Debug add this user-defined setting (under Debug)

GCC_PREPROCESSOR_DEFINITIONS DEBUGON=1



Then, you can simply use DEBUGLOG(@"Testing output %.2f", myFloat); in your code
and in Debug Build NSLog will be used, but in Release Build or Distribution Build, no NSLog output.
.
.
.