2011年5月28日土曜日

iOS 4 in Action - Using Location Monitoring Service

When an application needs to continue running in the background, these
multitasking features are available on iOS 4:

Audio—The application can continue running and play audio to the user while
in the background. The user can use the multitasking UI or the lock screen
UI to remote control the audio play, pause, fast-forward, and so on.
Location—The application can receive location updates to support a
location-related task or navigation in the background, such as significant
location change service and turn-by-turn directions.
VoIP—Allows the application to receive voice calls through the Internet
while other applications are in the foreground.
In this article, we will build a demo application that tracks the location
updates in the background.

Updating the UI when the Application Relaunches

The first step is to create an application to display the collected location
data. First, open Xcode and create a project using a navigation-based
application template in the iOS application projects. Name it Locations. In
this application, we will use a table view to display all the new location
updates from the location service running in the background.

The application's view controller needs to update the user interface when
the location is restarted from the background state.

Inside the RootViewConroller.h file, define an array locationData and use it
as table view's data source, as shown in the following listing. Then, in
the RootViewController.m file, display the location data on the table view.
Keep in mind that the table view needs to reload the data when the
application is restarted from the background.

Listing 1 RootViewController's header file and implementation file

Collapse
#import <UIKit/UIKit.h>
@interface RootViewController : UITableViewController {
NSArray *locationData;
}
@property (nonatomic, retain) NSArray *locationData;
@end

#import "RootViewController.h"
@implementation RootViewController
@synthesize locationData;

- (void)updateUI {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.locationData = [defaults objectForKey:@"kLocationData"];
[self.tableView reloadData];
}

- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Locations";
[self updateUI];
NSNotificationCenter *notifcenter = [NSNotificationCenter
defaultCenter];
[notifcenter addObserver:self selector:@selector(updateUI)
name:UIApplicationWillEnterForegroundNotification object:nil];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [locationData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
autorelease];
}
cell.textLabel.text = [locationData objectAtIndex:indexPath.row];
return cell;
}
- (void)dealloc {
[locationData release];
[super dealloc];
}
@end
When the table view controller gets loaded, the locationData array will
fetch the data stored with NSUserDefaults, then update the table view based
on the locationData array. The notification center will observe the event
when the application resumes from the background state and reload the table
view's data.

Now we have the table view ready to display the location data. Next, let's
look at how to get the location updates from the Core Location framework
with the significant location update service.

Enabling Significant Location Change Service

In this part, we will add the significant location change service to our
application locations. First, we add the Core Location framework to the
project and include the core location header in the app delegate file. Then,
let's add the Core Location Manager to the app delegate as an instance
variable: CLLocationManager *locationManager. Now, we will add changes from
the following listing to the app delegate implementation file to enable the
location monitoring service when the app launches.

Listing 2 Implementing Location Updates in the Background

Collapse
#import "LocationsAppDelegate.h"
#import "RootViewController.h"

@implementation LocationsAppDelegate
@synthesize window;
@synthesize navigationController;

-(void)initLocationManager { #1
if (locationManager == nil) {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
}
- (void)saveCurrentData:(NSString *)newData { #2
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *savedData = [[NSMutableArray alloc]
initWithArray:[defaults objectForKey:@"kLocationData"]];
[savedData addObject:newData];
[defaults setObject:savedData forKey:@"kLocationData"];
[savedData release];
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (![CLLocationManager significantLocationChangeMonitoringAvailable]) #3
{UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Sorry"
message:@"Your device won't support the significant location change."
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return YES; #3
} #3
[self initLocationManager];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}

- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation
*)oldLocation { #4
NSString *locationData = [NSString stringWithFormat:@"%.6f,
%.6f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
[self saveCurrentData:locationData];
} #4

- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error { #5
NSString *errorData = [NSString stringWithFormat:@"%@",[error
localizedDescription]];
NSLog(@"%@", errorData); #5
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[locationManager release];
[navigationControllerrelease];
[window release];
[super dealloc];
}

@end
#1 Starts location service
#2 Stores data
#3 Tests if location service is available
#4 Updates location data
#5 Error handling

Inside the application delegate, we use the Core Location Manager to monitor
the significant location change. When the application first launches, we
call method initLocationManager (#1) to initialize the location manager and
start the significant location update service. In order to make sure the
location service is actually available on this device, we use method
significantLocationChangeMonitoringAvailable (#3) to test the availability
and, if not possible, to use the location update service on this device, we
give user an alert.

Once the new location is available, the location manager delegate method is
called (#4). We need to store the new location data using NSDefaults in
method saveCurrentData (#2). That's how the table view can get all the new
location updates from the application delegate.

In case an error occurs during location updating, the location manager calls
the delegate method (#5). We can read out the error message inside the
Console Window under Xcode.

You need to test this application on your iPhone or iPad with 3G since the
simulator won't support the location change service. Build and run this
application on the device. Quit the application to let the location service
run in the background.

The locations application will continue receiving updates in the background
and, once it's relaunched, you can track all the places you've been to.
Notice that, even if the application is suspended in the background or the
application is not running at all, the location service is running. You can
tell by the indicator on the status bar of your iPhone or iPad 3G, as shown
in figure 1.

Figure 1 Significant location updates application running in the background
You can combine this significant location updates service and notify user
with local notifications. The region-based location monitoring service works
exactly like the significant location updates service. You can define which
region to monitor; when the user enters that specific region, the
application will receive the location update through core location delegate
methods. The system will wake up the application even if the application is
not running or is suspended.

Summary

In this article, we dug into the multitasking topic and built the location
tracking application with background significant location updates.

2011年5月26日木曜日

iPad、BlackBerry、iPhoneのモバイル戦略

自分の端末の利用を促す「Bring Your Own Device」(BYOD)戦略に加え、組織は新たなモバイル労働力管理戦略を立案し、モバイル端末を脅かす新たなセキュリティ問題とサポートモデルについても考慮しなければならなくなった。

 携帯型、常時接続型のタブレット端末は定着する。疑わしいと思うのなら、iPadの大成功と、しのぎを削っている競合各社のことを考えてみるといい。信じようと信じまいと、これはBYODフレンドリーなビジネスに恩恵をもたらし得る。多くの企業が近いうちにノートPCの支給をやめてしまうとは思えないが、一部ではタブレットが補完的な端末として使われている。ウェストミンスター大学では、学長がiPad熱に取りつかれた。ノートPCもまだ持っていて会議に持って来ることもあるが、大抵はiPadのみを持って出張し、以前よりも生産的になっている。iPadは適切な管理が行き届いているので、電子メールのやりとり、ちょっとした文書やプレゼン資料の編集、市況チェック、寄付してくれそうな相手への情報提供など、「外出中」のニーズを満たすことができる。

 それでも、学長のニーズはiPadでできることのほんの表面をなぞっているにすぎない。ベンダーのアプリケーションストアからは、何千というビジネスアプリを入手できる。さらに、適切なインフラがあれば、アプリケーションは簡単にデスクトップPCから切り離せる。ノートPCによって切り離しは何年も前から可能になっていたが、新世代のモバイル端末、特に3Gネットワークに常時接続できる端末により、まったく新しいレベルに到達した。

 新しいモバイルで実現できるメリットを全てリストアップするのは不可能だ。「いつでも、どこでも、どんな端末でも」使えるコンピューティングが定着し、可能性は無限にあるといえば十分だろう。大きな夢を持ち、それを実現させたい。