Monday, January 17, 2011

Non-blocking Network I/O and Timeout in BlackBerry API

Currently I am working on porting a C++ project to BlackBerry JDE 5.0. In the C++ implementation of the project, I have noticed use of select() function to enforce timeout property in C++ socket programming. I had to find non-blocking network I/O API in BlackBerry JDE 5.0 documentation but to no avail. As klyubin pointed out, no non-blocking I/O API is present on BlackBerry. He suggested two solutions: (1) setting a read/write timeout on the connection (which is not supported on some old platforms) and (2) periodically checking some timeout value from another thread (e.g., daemon thread, Timer, event dispatcher) and disconnect once the timeout expires.

The first solution seemed faster to integrate. So I searched and found the following:

For UDP connection, use DatagramConnectionBase.

DatagramConnectionBase connection = (DatagramConnectionBase) Connector.open(connectionString, mode, true); // 3rd argument : timeout is enabled
connection.setTimeout(10000); // 10 seconds


For TCP connection, use SocketConnectionEnhanced as pointed out by Mark Sohm.

For TCP connection through BES (BlackBerry Enterprise Server), the following BlackBerry Knowledge Base article is useful:
How To - Control the connection timeout for TCP connections through the BlackBerry MDS Connection Service

Tuesday, August 31, 2010

Custom accessory view of table view cell : accessoryButtonTappedForRowWithIndexPath method is not called

In my attempt to implement a custom accessory view for table view cell, I faced a weird problem. While everything in my code looked okay, the accessoryButtonTappedForRowWithIndexPath method was not being invoked when I tapped the custom accessory button.

Sample code Accessory provided by Apple helped me sort out the problem. Here the clue is that the custom accessory view must have a custom button which will be wired to a predetermined target and action.

In the method cellForRowAtIndexPath:

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
// match the button's size with the image size
button.frame = frame;
[button setBackgroundImage:image forState:UIControlStateNormal];


// set the button's target to this table view controller so
// we can interpret touch events and map that to a NSIndexSet

[button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];

cell.accessoryView = button;



- (void)checkButtonTapped:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
if (indexPath != nil)
{
[self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}


Reference:
Sample code of custom accessory view from Apple

Monday, August 30, 2010

Warning : declaration of 'variableName' hides instance variable

The large number of warnings of the following kind seem to me really annoying, though I can realize the need of it.

declaration of 'variableName' hides instance variable

I googled for a nice work-around to avoid this warning but could not find any. Many have suggested to use underscore prefix for instance variables but some pointed out that underscore prefix notation has been reserved by Apple. The others suggested to use the convention of using the/a/an before the variable name but it seems to me quite distasteful!

Helpless, I opted for the latter solution :-(

References:
1. Objective-C convention to prevent “local declaration hides instance variable” warning
2. Suppressing variable hiding warning in Xcode
3. Parameters hide instance variables in Objective-C

Wednesday, December 16, 2009

Checking for NULL pointer before deleting or calling free()

Today after reading two posts (references given at the end) from Stack Overflow I have got a better understanding of how dynamically allocated memory should be freed and why in that way.

Earlier I knew only that pointer should be checked against NULL before freeing memory, otherwise catastrophic disaster may occur because it may happen that an already freed memory is being freed again. So I always put it like:

if (pointer == NULL) {
    free(pointer); // or "delete pointer;" in C++
}

Later while working with files in C, I came to realize that freeing memory in this fashion does not make the pointer NULL. So dangling pointer surfaces in this context. I added another line:

pointer = NULL;

However, freeing a NULL pointer is not a problem at all now because according to ANSI standard, free() function does nothing when the passed pointer is NULL.

For the sake of being cautious and avert non-standard compilers from causing havoc to your program, you may check for NULL pointer. Otherwise, it all boils down to only the following 2 lines:

delete pointer;
pointer = NULL;


References:

(1) checking for NULL before calling free
(2) Is there any reason to check for a NULL pointer before deleting?

Tuesday, December 15, 2009

BlackBerry application facing HTTP connection problem on simulator

Before testing an application that uses HTTP connection on BlackBerry simulator, I often forget to enable Mobile Data Service (MDS) with the simulator and I find my application not working as expected.

So if you encounter problem with your application failing to establish HTTP connection, check your intended simulator's MDS setting.

To enable MDS setting,

1. From JDE, go to Edit -> Preferences
2. Select Simulator tab
3. Select General tab under Simulator tab
4. Check "Launch Mobile Data Service (MDS) with Simulator"

Tuesday, December 08, 2009

How to clean or reset BlackBerry simulator

For a veteran BlackBerry developer, it is not unusual to get his BlackBerry simulator crammed with many icons of applications he developed over the years. At one point, when he needs to scroll deep down the screen to find his intended application icon, it becomes really annoying. He then wants to remove application icons from the simulator.

Another kind of need may arise in case of an application which requires the simulator reset its file system each time the simulator is launched.

I have two versions of the same application with same application icon installed on simulator. I wanted to clear everything up and to test one particular version. But I did not know how to do it. I then googled and found the following solutions.

Solution #1: In JDE, go to File -> Erase simulator file

Deletes the dmp files from the simulator directory but does not remove the application icons.

Solution #2: From command line, run clean.bat located at simulator sub-directory under JDE installation directory such as C:\Program Files\Research In Motion\BlackBerry JDE 4.3.0\simulator

Deletes your applications' files and dmp files from the simulator directory. So the icons are removed!

Solution #3: Delete the following files located at the simulator directory such as C:\Program Files\Research In Motion\BlackBerry Device Simulators 4.2.2\4.2.2.114 (8300-Vodafone):

* dmp files
* debug, cod, csl, cso, jar files of your applications

This works when the installed simulator does not have the solution #2 i.e. clean.bat is absent in the simulator's directory.

Solution #4: If you're using the JDE and wants your simulator reset each time you run it, go to Edit->Preferences; Simulator tab; Memory sub-tab, and check "Reset the filesystem on startup"