Transitioning from Android to iOS4

Figure 1. XCode Compiler of iOS

In some ways trying to learn to code for the iPhone after coding for the Android Phone may be more difficult than simply programming the iPhone from scratch. On the other hand, there are enough similarities between coding for both platforms that your knowledge of Android programming can be leveraged to programming for the iPhone. So there is a balance between letting go of your assumptions of how things should work using Objective C and iOS4 and transferring the concepts that you have learned from programming the Android Phone to programming the iPhone. I do not plan to write a tutorial on iPhone programming. Instead, I hope to point out how programming in Objective C differs in programming in Java and how programming for both devices use similar architectural constructs. This is a work in progress!


 Android iOS
Memory Management
Java uses automatic garbage collection so that objects that are no longer "touchable" are deleted when memory runs low.iPhone Objective C uses reference counting so that we may need to manually manage retain counts. When the retain falls to zero, the object is eligible for deletion.
PropertiesJava allows access to object variables using the dot notation.
Objective C supports the concept of a property. You can use properties to set and get instance values using the dot notation.
Invoking Methods
Your class is in a single file in Java and you define the methods in the file You call a function in Java.
In Objective C each class file is divided into a public header file MyClass.h and a private implementation file MyClass.m. You send a message to an object in Objective C.
In Android, you can wrap a primitive value in the corresponding object and call toString().
In iOS, you can use NSString's appendFormat command to get the string value of a primitive.
Options Menu
In Android we can implement the options menu to navigate to sub screens.In iOS we can add a UITabBar to the main AppDelegate.
Hiding the Virtual Keyboard
In Android, the virtual keyboard can be dismissed with the back button.In iOS, the convention is to create an invisible button that fills the screen, set it to custom, and send it to the back (Layout --> Sent to back) and connect it to an action that releases all of the possible first responders.
Connections to Widgets
In Android we programmatically create a "connection" between a reference and a UI widget.
In iOS we declare the reference to a text field in MyViewController.h We then graphically create a connection by opening MyViewController.xib in Interface Builder.
Sending Delayed Messages
In Android, if we want to wait for the screen to refresh we can send a delayed message to the main thread handler as in:


Or we can add a delayed runnable to the message queue using postDelayed defined as:
public final boolean postDelayed (Runnable r, long delayMillis)
In iOS, we can post a delayed message to the main message queue using


and blocks. Or you can use selector as in:

[lError performSelector:@selector(setText:) withObject:@"" afterDelay:0.5];

Launching Threads
Message Passing Communication with immutable objects,  Asynch Task
Shared memory communication with NSOperation
Saving Application State
Application Context


public class MyApp extends Application {
    private String myString="";   
    public MyApp() {;}
    public String getMyString() {
        return myString;
    // ASSERT s not null
    public void setMyString(String s){
        if (s == null){throw new IllegalArgumentException();}
        myString= s;

 In iOS you can write user preferences to NSUserDefaults as in:

NSUserDefaults *userDefaults= [NSUserDefaults standardUserDefaults];
    NSString *plainText= tvPlainText.text;
    [userDefaults setObject:plainText forKey:@"plainText"];
    [userDefaults synchronize];

You can also write data to a .plist or Core Data.


 Concept Android iOS
Separating out the presentation into a xml file In Android we have main.xml. In iOS we have MyViewController.xib (formerly known as a .nib file).
 Both OS support a separation of concerns into a Model, View and Controller in which the Controller owns the Model and View.  In Android we have: (Controller)
main.xml (View) (Model)

In iOS we have:

MyViewController.h/MyViewController.m (Controller)
MyViewController.xib (View) 
MyModel.h/MyModel.m (Model)

Localized Strings  

and the resource file strings.xml

<string name="string_id">DefaultString</string>


and the resource file Localization.strings
 Both Android and iOS support wiring actions in xml.  In Android you can manually specify what method should be called in main.xml in response to a UIWidget action such as onClick. The following code snippet declares a Button that connects the onClick action to the method confuseTextOnClickHandler in

<Button android:text="@string/confuse_text_button"
android:onClick= "confuseTextOnClickHandler">
In iOS you can visually create an action connection using Interface Builder (IB) from a UIButton to an existing method such as MyViewController.MyButtonHandler(). To create an action connection in IB, select the button and choose Tools --> Connection Inspector. Select the action "Touch Up Inside" and click drag to the File's Owner icon in MyViewController.xib. You can then examine this connection using Interface Builder by again selecting the UIButton and selecting Tools --> Connection Inspector. An example in Button Connections that is the equivalent of onClick is:

Touch Up Inside --> MyButtonHandler().

We can initialize variables In Android we can initialize variables in onCreate as in:

/** Called when the activity is first created. */ 
public void onCreate(Bundle savedInstanceState) { 
    model= new Model();
In iOS we can initialize variables in init and save/retrieve view state in viewDidLoad and viewDidUnload as in:

-(id)init { // NOT called after resurrection from low memory
    self= [super initWithNibName:nil bundle:nil];
    if (self) {
        UITabBarItem *tbi= [self tabBarItem];
        [tbi setTitle:@"Main Window"];
        UIImage *image= [UIImage imageNamed:@"main.png"];
        [tbi setImage:image];
        model= [[Model alloc]init];
    return self;

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil    {
    return [self init];

We release the resource in dealloc as in:

- (void)dealloc { 
    [model release]; // works on nil? 
    [super dealloc]; 

Note: init IS NOT CALLED after resurrection of a view from a low memory warning. Save and restore view instance state in viewDidLoad and viewDidUnload.
 Both Android and iOS support Logging.  In Android we write to the LogCat window as in:

In iOS we write to the Console window. Given a pointer to an NSString as in:

password:(NSString *)pw

We can log the value as in:

NSLog(@"Password is: %s",[pw UTF8String]); // %s expects a C String
NSLog(@"Password is: %@",pw); // %@ expects an object with -description

For password as "password" we see:

[Session started at 2011-06-02 20:59:51 -1000.] 
2011-06-02 20:59:54.846 EncryptSMS[1464:207] Password is: password 
2011-06-02 20:59:54.883 EncryptSMS[1464:207] Password is: password


NSLog(@"Can send SMS: %@",(isCanSendSMS? @"YES":@"NO"));
  In Android we can set hints in xml or programatically. In iOS we use the IB Inspector window to set the placeholder value.
 Both iOS and Android support simple copy and paste of strings to and from the clipboard.  
In Android we can copy and paste a string to and from the clipboard as in:

    private ClipboardManager clipboard;        
    clipboard= (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);


     final CharSequence chars= clipboard.getText();
     if ((chars != null) && (chars.toString().length()>0)) {
 In ios we can do:

-(IBAction)copy:(id)sender {
    UIPasteboard *gpBoard = [UIPasteboard generalPasteboard];
    gpBoard.string= cipherText.text;
-(IBAction)paste:(id)sender {
    UIPasteboard *gpBoard = [UIPasteboard generalPasteboard];
    cipherText.text= gpBoard.string;
 Both Android and iOS support auto renaming of variables or refactoring of variable names In Android uou can quickly rename variables in a class by selecting the text and choosing Refactor --> Rename.  In iOS, select the variable name and right click --> Refactor...
 Both Android Eclipse and iOS XCode can backup a project.  In Android select the PROJECT FOLDER, click File -->Export Choose Archive File.  In iOS select the PROJECT FILE, click File -> Make Snapshot
 Both Android and iOS support a view menu. In Android we can use an options menu. In iOS we can use a TabBar for the same purpose.
 Both Android and iOS support auto-rotation of views In Android the scroll view will automatically be enabled, if needed, in the landscape mode.  In iOS, IT IS POSSIBLE, to enable scrolling ONLY in the landscape view by having each sub view message the application on pending rotation and then having the application message ALL the subviews of the needed scroll view state.
Both Android and iOS support enforcing minimal OS requirements.
 In Android the minimal OS requirements are in the AndroidManifest.xml file as in:
<uses-sdk android:minSdkVersion="4" />
 In iOS, the minimal OS requirements are spelled out in Project Settings as: Deployment --> iOS Deployment Target --> iOS 4.0.

This is separate from the target SDK which is in Architectures --> Base SDK --> Latest iOS (iOS 4.3)


Hope you are still having fun!

Misc. Errors:

1) In iOS we can add a framework by right clicking on the Frameworks folder and choosing Add. WARNING: If you drag a framework to the project it may be copied to the project folder resulting in the error:

missing required architecture i386 in file

This in turn will lead to a link error with missing symbols to the added framework.

2) Xcode uses Clang to analyze code (Build and Analyze) and Instruments (Run with Performance Tool) to find leaks. For instance, the default template for iPhone View leaks memory on rotation when tested on an iPad2 device when rotation is enabled with the addition of a single line of code. This suggest a leak in the iPhone "simulator" on the iPad2.