Thursday, June 25, 2009

iPhone SDK dismiss the keyboard


Set the delegate on the text field that will bring up the keyboard. Add the following selector to the object that you set to be the delegate.

The controller's interface code
#import
@interface MyViewController : UIViewController {
IBOutlet UITextField *textField;
}
@property (nonatomic, retain) UITextField *textField;
@end
And the controller's implementation code
#import "MyViewController.h" 
@implementation MyViewController 
@synthesize textField;
-(BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == textField) {
[textField resignFirstResponder];
}
return YES;
}
@end

Thursday, June 11, 2009

Converting a J2ME MIDlet to a BlackBerry COD

Converting a J2ME MIDlet to a .COD involves the following steps:

  1. Download and install the RIM Java Development Environment
  2. Download and install Java SDK
  3. Copy the jad & jar files in question to the /bin/ directory of your BlackBerry JDE installation
  4. From the command line (make sure you are in the bin directory of your RIM JDE installation) type:
rapc import=“$your_JDE_dir\lib\net_rim_api.jar" codename=$your_app -midlet jad=$your_app.jad $your_app.jar
Where,
$your_JDE_dir  - is the directory of your RIM JDE installation,
$your_app          - is the name of the MIDlet you're trying to convert $your_app.jad        - is the name of the MIDlet descriptor and
$your_app.jar     - is the name of the MIDlet jar file
  1. The following files are generated:
$your_app.debug
$your_app.cod
  1. $your_app.cod is used to load the application onto the BlackBerry 
 To load the application onto the BlackBerry Simulator:
  • Launch the BlackBerry Device Simulator by selecting Start => Research In Motion => BlackBerry JDE => Device Simulator.
  • Once the simulator is loaded, install the .cod file by selecting File => Load Java Program and load the $YOUR_APP.cod from $JDE/bin/
  • On the BlackBerry Simulator desktop find your application and launch it. 

Android Application Lifecycle

In Android, the applications are run as a separate Linux process. So the application lifecycle is closely related to the process lifecycle. The application process lifecycle is handled by the system depending on the current system memory state.
In case of low memory, the Android system kills some less important process. The process importance is decided depending on the state of the process components.
The process types depending on the importance are as follows (from most important to least important):
1. Foreground process: A foreground process is the application process with which the user is currently interacting. The process is considered to be foreground if its Activity is at the top of the Activity stack (its onResume() has been called) or BroadcastReceiver is currently running (onReceive() method is currently getting executed) or its Service is executing callback functions like onCreate(), onStart() or onDestroy() methods.
2. Visible Process: A visible process is the process which has an Activity visible to the user (its onPause() method has been called).
3. Service Process: Service process contains a Service for which startService method is called and the service is running.
4. Background Process: The background process does not have any visible activities to the user. (Activity onStop() method has been called).
5. Empty Process: Empty process is the one that does not have any active application components. These processes are kept on for caching purpose.
It is important that application developers understand lifecycle of the application process. Not using these correctly can result in the system killing the application’s process while it is doing important work.

Thursday, May 28, 2009

The For-Each Loop in Objective-C

Loops are the gears of a
programming language, they help move the program to the next step. 
A For-Each loop is generally used when you
want your program to do something to a collection of objects.
For example, this For-Each loop prints out each string in an
array of strings:

    //For each loop
    //Create an array and add elements to it
    NSMutableArray *anArray = [[NSMutableArray alloc] init];
    [anArray addObject:@"Element 1"];
    [anArray addObject:@"Element 2"];
    [anArray addObject:@"Element 3"];
   
    //Use a for each loop to iterate through the array
    for (NSString *s in anArray) {
        NSLog(s);
    }
   
    //Release the array
    [anArray release];


  That is it!

Wednesday, May 27, 2009

For Loop in Objective-C

Loops are the gears of a programming language.

They help move the program to the next step. A For loop is generally used when you want your program to repeat an action a set number of times. 

Here is the syntax for the For Loop:
 
    for (int y = 0; y < 3; y++) {
        NSLog(@"y = %i", y);
    }
 
 
That is it!

Thursday, May 14, 2009

Sorting An Array in Objective-C

Arrays are structures used to hold a list of objects. Sometimes
though you may want to sort the order that the elements appear.

Doing this is actually pretty simple once you know how,
essentially you will be using the NSArray sortedArrayUsingSelector
method.

For example, if you create an array like so

NSMutableArray *anArray = [[NSMutableArray alloc] init];
[anArray addObject:@"B"];
[anArray addObject:@"A"];
[anArray addObject:@"C"];
and then write out the contents of the array to the log using a
foreach loop the results will look like this:

[Session started at 2009-03-25 16:57:55 -0400.]
2009-03-25 16:57:58.647 SortigArray[3403:20b] B
2009-03-25 16:57:58.648 SortigArray[3403:20b] A
2009-03-25 16:57:58.649 SortigArray[3403:20b] C

Obviously, the contents of the array stay in the same order in
which they were inserted.

What you could do is create another array, sorted, using the
sortedArrayUsingSelector method of NSArray. Here is how:
NSArray *sortedArray = [anArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
The odd (for some anyway) piece of this code is the
@selector(caseInsensitiveCompare:) component of the code. This is
a method passed to the function that instructions NSArray on how
to sort the array.

At any rate, if you run through the array as before and print out
the results to the log you will get this:

[Session started at 2009-03-25 17:07:18 -0400.]
2009-03-25 17:07:21.832 SortigArray[3537:20b] A
2009-03-25 17:07:21.833 SortigArray[3537:20b] B
2009-03-25 17:07:21.834 SortigArray[3537:20b] C

As you can see, the this array is sorted. There you have it!

Thursday, May 7, 2009

Adding Background Colors and Images to Your Table Views

Setting the background color of your table view is very easy.
All you need to do is set the backgroundColor property to the
color you want to see. For example, I have created a table view
here in the app delegate and simply set the background
property from here:

UITableViewController *tvc = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped]; tvc.view.backgroundColor = [UIColor redColor]; [window addSubview:tvc.view]; [window makeKeyAndVisible];
If you are using sub-classing, you may also rather set this property in the initWithStyle.

You can use also an image as your background to really spice things up.

Here is that code:

UIView *backgroundView = [[UIView alloc] initWithFrame: window.frame]; backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"TableViewBackground.png"]]; [window addSubview:backgroundView]; [backgroundView release];
yourTableViewController = [[ATableViewController alloc] initWithStyle:UITableViewStyleGrouped]; yourTableViewController.view.backgroundColor = [UIColor clearColor]; [window addSubview:yourTableViewController.view]; [window makeKeyAndVisible];

This one takes a little more code - essentially you are putting an image into a view, inserting that into the
app window and then setting the background to a transparent color. Simply setting the background
color of the table view to the image would produce artifacts.

That is it! I hope that this tip will add some more pizazz to your apps!

Monday, April 27, 2009

General Coding Tips

Avoid the Object.getClass() Method

Avoid using the Object.getClass() method, because it is not efficient and it produces garbage (the Class object) that is never collected. Also avoid using the example.class literal. Behind the scenes, this generates Class.forName(“Example”).

Writing Efficient Loops

You should always factor loop invariant code out of a loop, as in the following example:

    for(int i = 0; i < >
...

}

This code results in vector.size() getting called each time through the loop, which is inefficient. If your container is likely to have more than one element, it is much faster to assign the size to a local variable. In addition, this example using pre-increment (++i) results in smaller code than post-increment (i++). The optimized code appears below:

     int size = vector.size();
for(int i = 0; i < style=""> ...
}

Alternatively, if the order in which you iterate over items is not important, you can iterate backward. Iterating backward avoids the extra local on the stack, and the comparison is also faster, as the following example illustrates:

for(int i = vector.size() - 1; i >= 0; --i) {

...

}



Optimizing Subexpressions

If you ever use the same expression twice, do not rely on the compiler to optimize it for you. Use a local variable, as in the following example:

one(i + 1); two(i + 1); // Avoid
int tmp = i + 1; 
one(tmp); 
two(tmp); // Prefer

Avoid java.util.Enumeration
Avoid using java.util.Enumeration unless you are using it to hide data (in other words, returning an Enumeration of data rather than the data itself). The following example shows a typical use of an Enumeration:

for (Enumeration e = v.elements(); e.hasMoreElements();) {
   o = e.nextElement();
   ...
}

Asking a vector or hash table for an Enumeration object creates unnecessary garbage and is slow. Instead, you can iterate over the elements yourself, as in this example:

for(int i = v.size() - 1; i >=0; --i) {
   o = v.elementAt(i);
   ...
}

If the vector might be modified by another thread, you must synchronize the iteration:

synchronized(v) {
   for(int i = v.size() - 1; i >=0; --i) {
      o = v.elementAt(i);
      ...
   }
}

In Java 2 Platform, Standard Edition (J2SE), you would use an Iterator for this, but Iterators are not available in Java 2 Platform, Micro Edition (J2ME).

Returning null
If you are writing a public method that returns an object, it should never return null unless the following occurs:

  • a null is expected during normal program operation.
  • the javadoc @return parameter states that null is a possible return value.

If a null is not normally expected, then the method should throw an appropriate exception, which forces the caller to deal with the problem explicitly. The caller is not expected to check for a null return value, unless the documentation specifies otherwise.

Passing null into Methods
Do not pass null parameters into an API method unless the API Reference documentation explicitly states that the method supports them.

Passing null into a Constructor
To avoid ambiguity when passing a null into a constructor, you should use this form:

new someObject ((Object)null);

A class can have two or more constructors, such as SomeObject(String) and SomeObject(Object), where passing in a null does not identify which constructor to use. As a result, the compiler reports an error. Not all supported constructors necessarily appear in the API Reference documentation, because some constructors are for internal use only. By casting the null to the appropriate object, you indicate precisely which constructor the compiler should use. This practice also ensures forward compatibility if later releases of the API add new constructors.

Optimizing Division Operations
Division operations are slow on the BlackBerry Wireless Handheld because its processor does not have a hardware divide instruction. When you write code that divides a positive number by two, you should use “shift right by one” instead. The following example illustrates this:

midpoint = width / 2; //avoid this
int = width >> 1; //prefer this

This does not work for negative values. Only use “shift right” (>>) when you know you are dealing with a positive value. It does not work for negative values.

Managing Garbage Collection
Avoid calling System.gc() to perform garbage collection. On a full handheld, this could take two seconds. Let the virtual machine (VM) collect garbage automatically.


Casting Using instanceof
It is more efficient to use instanceof instead of classCastException to evaluate whether a cast succeeds. Here is an example of using a try/catch block to catch the classCastException:

try {
   (String)x.whatever();
} catch(ClassCastException e) {
   // something else
}

Alternatively, you can use instanceof operator:

if(x instanceof String) {
   (String)x.whatever();
} else {
   // something else
}

Using instanceof is faster. The only time you should use the try/catch block is when the failure of the cast is an exceptional circumstance. The BlackBerry Java Development Environment (JDE) compiler and the VM are optimized to perform only one class check in the first block of code. This is true of any code in which the cast is run immediately following a branch determined by an instanceof check. Always perform the cast immediately after the branch so that the optimization can be performed.

Using Longs for Unique Identifiers
You should use longs rather than strings for unique constants, such as globally unique identifiers (GUIDs), hash table keys, and state/context identifiers. So that unique identifiers remain unique across all third-party application developers, you should use randomly generated keys based on a hash of some string. In the input string, you should include enough information to make it unique.

Memory Management tip

Dealing with memory on the iPhone is one of the most difficult
challenges that you will face as a new iPhone developer. Today,
I am going to show you a very simple tip that will help you
debug the memory problems that you are like to face.

One thing that you have to worry about with memory management is
the "retain count" of an object. The retain count is how the
system keeps track of the memory used by an object. If an
object's retain count is zero and your attempt to access it
your app will crash; if you do not make sure the retain
count of your object is 0 when the object goes out of focus you
will have a memory leak.

Clearly, it is important to be able to find out what the current
retain count of an object is. Here is how you can do this:

NSLog([NSString stringWithFormat:@"Retain Count:%i", [someObject retainCount]]);
This writes out the current retain count to the log. The
important function is [someObject retainCount].

Friday, April 24, 2009

Strings in iPhone

The iPhone uses a special class called "NSString" to handle strings. Here is an example of a common use of NSString.
NSString *myString = @"This is my string";
You can use an NSString object in the alert that you learned about last week. Here is how you would use the NSString object "myString" in an alert:
NSString *myString = @"This is my string";

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"UIAlertView"
message:myString
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
Notice that the "message" argument of the alert you created above uses the NSString object as an argument. Another thing you will be doing with strings is combining strings to make new ones.
For instance, if I had two strings - a first and a last name - and I wanted to create a new string for a full name I could do something like this:
NSString *firstName = @"Matt";
NSString *lastName = @"Campbell";
NSString *fullName = [NSString stringWithFormat:@"My name is %@ %@",
firstName, lastName];

If you were to put fullName into an alert it would say "My name is Matt Campbell". How the stringWithFormat function works is that you give it a string with special symbols in it. The function will replace the symbols with the strings in give it as the next arguments to the function.
Note that when you are using the alert object you need to follow the "alloc, use, release" pattern while the NSString only requires you to use the function after which you may safely forget about it.
This has something to do with the memory management features of the iPhone. Essentially, when you use an object's "alloc" you need to "release" at some point in the future. NSString does not use an alloc in this instance so it does not need to be released while UIAlert does. More details about memory management will be discussed in this mailing list in the future.