Tuesday, March 27, 2012

Handling Windows power state

- Rameshkumar Subramanian
While developing CloudStorage Drive [virtual drive] application I came across exploring windows power management to remount the CloudStorage Drive after getting up from hibernate state. Usually you can see our local drive / regular drive, like C:\, gets mounted when the system wakes up from sleep state.

We know that the operating system controls power management across the entire PC system. For example, suppose if you have paused a video and go to the hibernate state the process goes idle here. You can see the video remain on the same state when the system is on back.

The software developers can now make their application power-aware by handling the WM_POWERBROADCAST message provided by the windows operating system and scaling features accordingly. This article describes how to handle the WM_POWERBROADCAST message and also describes the sequence of messages for four typical cases. This is very helpful for whoever wants to re-launch the application after the system get back to power state.

Power States
To the user, the PC is either on or off, and other conditions are not visible. However, the ACPI (Advanced Configuration and Power Interface) specification defines a number of different power states that are supported by windows operating system.

State
Description
S0/Working
On. The CPU is fully up and running. power conversation is on a per-device basis.
S1 Sleep
Appears off. The CPU is stopped. RAM is refreshed, the system is running in a low power mode.
S2 Sleep
Appears off. The CPU has no power. RAM is refreshed. The system is in a lower mode than S1.
S3 Sleep
Appears off. The CPU has no power. RAM is in slow refresh. The power supply is in a reduced power mode.
S4 Hibernate
Appears off. The hardware is completely off. But system memory has been saved to disk.
S5/Off
Off. The hardware is completely off. The operating system has shut down, nothing has been saved. Requires a complete reboot to return to the working state.

The power management functions and messages retrieve the system power status and notify applications of power management events. The windows offer WM_POWERBROADCAST message which will be send to the application to indicate power changes. The documentation for each of these is provided as:

Event
Meaning
PBT_APMBATTERY LOW
Battery power is low.
PBT_APMOEMEVENT
OEM-defined event occurred.
PBT_APMPOWERSTATUSCHANGE
Power status has changed.
PBT_APMQUERYSUSPEND
Request for permission to suspend.
PBT_APMQUERYSUSPENDFAILED
Suspension request denied.
PBT_APMRESUMEAUTOMATIC
Operation resuming automatically after event.
PBT_APMRESUMECRITICAL
Operation resuming after critical suspension.
PBT_APMRESUMESUSPEND
Operation resuming after suspension.
PBT_APMSUSPEND
System is suspending operation.


The window proc receives the entire event which we can easily implement as shown below. In .Net you have to using interop service namespace for those things .

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg)
    {
    case WM_POWERBROADCAST:
    {
     switch (m.WParam.ToInt32())
      {
         case (int)PBT.PBT_APMQUERYSUSPEND:
          . . .
          . . .
      }
     }
    }
}
The above code can be made use to handle the power suspend states like when system goes sleep or to hibernate mode.

Wednesday, March 21, 2012

Handling multiple selection in iPhone TableView

- Rashid Khaleefa
Its a common practice to list down the data or items in any mobile phone. The display of contact list is a very common example in any mobile phone where you see a list of contacts saved. Even though the brand, the OS or the model differs, when it comes to bulk of data to display either a listview control or any tableview alternative controls are used.
In iPhone items can be displayed using the UITableview control. I came across using this control in my iPhone app. It was quiet easy to get started with displaying a list of data from an array. I just had to use the UITableview control along with its delegates to handle the display. It is much cool to use three functions as below to display the items. Here I have an array of dictionaries to list out in the tableview.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//Return the number of rows in the section.
return [tableList count];
}

And cellForRowAtIndexPath function gets called once for each row. This is where we define what content to display in a given row or cell. We assign the values to each cell labels. I have used a custom cell designed with three labels and an imageview separately and values are assigned to the corresponding controls in each cell.

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *CellID = @"CustomCell";
 CustomCellController *cell = (CustomCellController*)[tableView  
 dequeueReusableCellWithIdentifier:CellID];
 if (cell == nil)
 {
  NSArray *topLevelObjects = [[NSBundle mainBundle]   
  loadNibNamed:@"CustomCellController" owner:nil options:nil];
 for(id currentObject in topLevelObjects)
 {
  if([currentObject isKindOfClass:[CustomCellController class]])
  {
  cell = (CustomCellController *)currentObject;
  break;
  }
 }
}
//tableList is an array on dictionary elements.
NSDictionary *item = (NSDictionary *)[tableList objectAtIndex:indexPath.row];
[[[cell Name] setText:[UserUtils convertSize:[item objectForKey:@"ImageName"]]];
[[cell Size] setText:[item objectForKey:@"Size"]];
[[cell Date] setText:[item objectForKey:@"Date"]];
[[cell imageView] setImage:[UIImage imageNamed:@"image.png"]];
return cell;
}

But I was stuck when it came to select multiple items from the table. I quiet easily managed to select a singe item from the list using the didSelectRowAtIndexPath function. But When it came to multiple selection I started breaking my head over. This made me google and got some solutions. But never stopped me googling more because most of the solution worked fine when there was only a page of data to display, where for me it was a list of twenty items.

The first thing I had to do was to select and deselect items in table which was identifiable by a check mark indication over the selected cell. Then I wanted to retrieve the corresponding dictionary of the selected items.
The issue I faced trying to select multiple items was that when I select fist item in the table of a particular page, the corresponding first item of all page was selected and so I was not able to differentiate the item list that was actually selected. And also to select and unselect multiple items from table took me some time to work it fine.

This is how I came up with the solution

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 NSMutableDictionary *rowDict = [tableList objectAtIndex:  
 [indexPath row]];
 NSString *SelectedState = (NSString*)[rowDict 
 objectForKey:@"objSelected"];
 if([SelectedState isEqualToString: @"YES"])
 {
  [rowDict setObject:@"NO" forKey:@"objSelected"];
  [tableView cellForRowAtIndexPath:indexPath].accessoryType
  UITableViewCellAccessoryNone;
 }
 else
 {
  [rowDict setObject:@"YES" forKey:@"objSelected"];
  [tableView cellForRowAtIndexPath:indexPath].accessoryType
  UITableViewCellAccessoryCheckmark;
 }
 [tableView reloadData];
 [tableView setNeedsDisplay];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:   
  (UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath
  *)indexPath
{
 NSDictionary *item = (NSDictionary *)[tableList  
 objectAtIndex:indexPath.row];
 NSString *SelectedState = (NSString*)[item 
 objectForKey:@"objSelected"];
 if([SelectedState isEqualToString: @"YES"])
 cell.accessoryType = UITableViewCellAccessoryCheckmark;
 else
 cell.accessoryType = UITableViewCellAccessoryNone;
}

Here, in didSelectRowAtIndexPath I have first retrieved the dictionary values at the particular index of selection and add one more value based on selection (YES when selected and NO when deselected) for key objectSelected and thereby placing a check mark by setting the cell accessoryType to UITableViewCellAccessoryCheckmark. This will obviously reflect the tablelist array as it is declared globally. So to make it simple the refreshed tablelist will have an additional key value pair which differentiates the selected items from the deselected one.

There will be n number of solutions for any issue of this kind. I would say this is also a way how I fixed the issue I faced. I hope this might be a useful post for any one working with UITableview in iPhone.


Tuesday, March 20, 2012

Write your first NSIS script

- Mohankumar Deivasigamani
Introduction
NSIS (Nullsoft Scriptable Install System) is a professional open source system to create Windows installers. It has a flexible design and is therefore very suitable for internet distribution. You can Google NSIS.


This article introduce how to write and compile your first NSIS script . I strongly recommend you to correctly install the NSIS on your computer.
As its been tradition to start of with the “Hello World” as first program , which does nothing more but show a simple "Hello World" message box . To create a program you'll need a text editor (like Notepad) or you install HM NIS EDIT it’s a free NSIS Editor. Ref: http://hmne.sourceforge.net/

Let’s Start 
Open notepad or NSIS editor, you can either type the program shown below into notepad or just copy-paste it from this article

/*
HelloWorld.nsi - First NSIS Script
Written by - Mohankumar Deivasigamani
*/
# Name of the installer
Name "CSS Corp Labs"
OutFile "CSSCorp.exe"
XPStyle on
  Function .onInit
      MessageBox MB_OK "Hello World …"
      Quit
  FunctionEnd
Section
SectionEnd

Once you finish typing your script you should Save the NSIS script file as HelloWorld.nsi. In fact after making any changes to your source code, you should always save the file. Once save script done close the notepad. Right click on the file, you will see two context menus (Compile NSIS Script & Compile NSIS Script [Choose Compressor]) to compile the NSIS script

  1. Compile NSIS Script will use default compressor that you defined in script.
  2. Compile NSIS Script [Choose Compressor] will allow you to choose compress type. (ZLIB, ZLIB (solid), BZIP2, BZIP2 (solid), LZMA, & LZMA (solid)).

Once you choose compressor type and say ok, the script is compiled and generate exe file in name that you specified in OutFile property.


After you compile, Make NSIS window will help you test your installer by clicking the “Test Installer” button. This creates Installer where your script is saved.

Double click to test the installer.



Notifications in iPhone application

-  Rashid khaleefa
       There should be always a way to provide alerts a informations for any IOS applications. Apple brings in this feature to IOS through APNs which is Apple Push Notification Service. Lets have a quick follow through over the process of activating this service in iPhone app.
Before to go through the steps, listed below are the types of notifications that iOS apps provide
  • Sounds: Plays an audible alert
  • Alerts/Banners: Displays an alert or banner on the screen
  • Badges: Displays an image or number on the application icon
The Notification view has made pretty cool from iOS5 onwards that one can just swipe down for notifications from the top of the screen.

What APNS does ?

Apple Push Notification service transports and routes a notification from a given provider to a given device. APNS actually uses the Push technology by which the notification from the servers of third party applications are forwarded to Apple devices.

How to Enable APNS in our app?
To sum up the steps in order
  • Request for certificate Authority
  • Create app id
  • Configuring AppId for Push Notifications
  • Create provisioning profile
  • Provisioning a device
  • Enabling the profile in Xcode
  • Creating push notification provider.
Going into each steps further

Request for certificate Authority
  1. Open keyChain Access.
  2. Select Certificate Assistant > request a certificate from certified authority.
  3. Fill up the Email , common name fields.
  4. Click on save to disc which will save the certificate to your computer.
Creating AppId
  1. Login to apple member sender and navigate to iOS Provisioning Portal page.
  2. Click on the Apple Ids tab and select New App ID.
  3. Enter Description, Bundle Seed Id (select Generate new) and Bundle Identifier (reverse domain style is recommended)
  4. Click on the submit button.
You can know see the AppId created 

Configuring AppId for Push Notifications
  1. Click on the configure option to the right of the AppId listed.
  1. Enable the checkbox for push notifications.
  2. Click on the configure button which is to the right of Development Push SSL Certificate.
  3. Click continue.
  4. Upload the CSR file that is been saved before by clicking choose File button from Submit Certificate Signing Request screen and click Generate.
  5. Click continue opens next screen where you can download the APNs SSL Certificate.
  6. Double click the downloaded file to install it in the Keychain Access application.
Create Provisioning Profile
  1. Click on the provisioning tab.
  2. Enter profile name and select certificate, AppId , devices that you need to provision.
  3. Click on Submit.
  4. Now you can see a download button to the right of the provisioning profile created. Click on it to download the profile.
  5. Drag this file to the Xcode on the Dock.
  6. To provision a device connect the device and drag the profile to the xcode in doc. Open the organizer from window menu from xcode and you can see the profile installed on the device.
Enabling the profile in xcode
  1. Create a project in xcode
  2. Right click the file found below Targets. Choose GetInfo opens the target info window.
  3. Click on the build tab and select Code Signing Identity.
  4. Select the provision profile that was created before.
This is all you have to do. And its now time to code for bringing out the notification to our application. Its easy that you can add some delegates to the AppDelegate.m file 

- (void)applicationDidFinishLaunching:(UIApplication*)application
{
 // Add registration for remote notifications
 [[UIApplication sharedApplication]
 registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert |              UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
// Clear application badge when app launches
 application.applicationIconBadgeNumber = 0;
}
//Fetch and Format Device Token and Register Important Information to Remote Server

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
 // code to register the device token to the provider
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
 NSLog(@"Error in registration. Error: %@", error);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
 NSLog(@"remote notification: %@",[userInfo description]);
 NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];
 NSString *alert = [apsInfo objectForKey:@"alert"];
 NSLog(@"Received Push Alert: %@", alert);
}

And now creating a push notification provider
      The push notification provider sends notifications to application through APNs. For this you must first communicate with the APNs using SSL certificate that was created earlier. And then you can sent push notification containing the payload to the APNs. The pay load have to be constructed as below.
     {
          "aps": {
               "badge": 2,
               "alert": "This is Labs Team from CSSCorp."},
               "device_tokens":["8DCDDC0CC1E110228DC9C1926B301BA3C3ED7403D6A39D571A1CD81906D7C944"]
      }
To avoid the burden of creating a provider you can even use some third party service to make your work easy. I have tried with UrbanAirShip service. Below are the steps that I followed.

Step 1:  The first is to create an account with UrbanAirShip.

Step 2:  Create an a new application by clicking on create app option on Select an application tab. Enter the application name, Add application icon. Now select on push notification support which will expand the options. Now add the Apple push certificate file which we have already downloaded incase of an iPhone application.

Step 3:  This will display the full details of the app created where you can get the app key, app secret, device tokens etc:

Step 4:  Click on push tab. This opens a window where you can specify the device token, badge, alert, sound for the notification to be sent. Note that once entering all these fields the payload will be automatically created.

Step 5:  Click on the sent this will send the notification to the device.

To make this work on our application you have to add the library to the xcode project created and do a bit modification to your the Appdelegate.m file.

Further you can download a sample app using urbanAirShip notification here to know how to integrate the library into your xcode project.