The ESRI ArcGIS iPhone API was released to public beta today. Jeff Shaner blogged and tweeted about it this morning.
I downloaded the SDK this afternoon and took it for a spin. My first impressions are very favorable. Although the documentation is still a bit sparse in a few places, that’s to be expected for a first beta.
The SDK is another client API for consuming ArcGIS Server REST endpoints, and it works with versions 9.3.1 and 10.0. If you have worked with any of the other client APIs, you will already be familiar with the basic paradigm of interaction with the various REST services offered by ArcGIS Server.
The SDK Concepts Documentation provides a basic overview of the technology and includes a number of brief walkthroughs as well as short code samples illustrating how to perform common programming tasks with the API.
The installation also includes six sample applications which are installed into your ~/Library/SDKs/Samples folder. Studying these sample apps is a good way to jumpstart your familiarity with the API.
But enough talk already, let’s see some code! [more]
After following the My First iPhone Application tutorial, I decided to jump in and modify the application to improve it in a some specific ways:
- Add a button bar to toggle three base map types: Streets, Aerial Imagery, and Shaded Relief Map
- Zoom to a predefined initial extent on application startup
- Support any device rotation
I won’t spend a lot of time describing everything here. I’ll just show a few screen snapshots with the source code and make everything available for download.
Here are some screen snapshots of the app running in the simulator:
Here is the MyFirstMapAppViewController.h header file:
#import <UIKit/UIKit.h>
#import "AGSiPhone.h"
#define kTiledStreetMapServiceURL @"http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"
#define kTiledImageryMapServiceURL @"http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer"
#define kTiledReliefMapServiceURL @"http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer"
@interface MyFirstMapAppViewController : UIViewController<AGSMapViewDelegate> {
AGSMapView *_mapView;
UIView *_streetView;
AGSTiledMapServiceLayer *_streetLayer;
UIView *_imageryView;
AGSTiledMapServiceLayer *_imageryLayer;
UIView *_reliefView;
AGSTiledMapServiceLayer *_reliefLayer;
}
@property (nonatomic, retain) IBOutlet AGSMapView *mapView;
@property (nonatomic, retain) UIView *streetView;
@property (nonatomic, retain) AGSTiledMapServiceLayer *streetLayer;
@property (nonatomic, retain) UIView *imageryView;
@property (nonatomic, retain) AGSTiledMapServiceLayer *imageryLayer;
@property (nonatomic, retain) UIView *reliefView;
@property (nonatomic, retain) AGSTiledMapServiceLayer *reliefLayer;
- (IBAction)toggleLayer:(id)sender;
@end
(Sorry, this is my first post about iPhone programming and I haven’t figured out how to highlight the syntax for Objective-C yet!)
And here is the MyFirstMapAppViewController.m implementation file:
#import "MyFirstMapAppViewController.h"
@implementation MyFirstMapAppViewController
@synthesize mapView = _mapView;
@synthesize streetView = _streetView;
@synthesize streetLayer = _streetLayer;
@synthesize imageryView = _imageryView;
@synthesize imageryLayer = _imageryLayer;
@synthesize reliefView = _reliefView;
@synthesize reliefLayer = _reliefLayer;
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.mapView.mapViewDelegate = self;
self.streetLayer = [AGSTiledMapServiceLayer tiledMapServiceLayerWithURL:[NSURL URLWithString:kTiledStreetMapServiceURL]];
self.streetView = [self.mapView addMapLayer:self.streetLayer withName:@"Street"];
self.streetView.hidden = NO;
self.imageryLayer = [AGSTiledMapServiceLayer tiledMapServiceLayerWithURL:[NSURL URLWithString:kTiledImageryMapServiceURL]];
self.imageryView = [self.mapView addMapLayer:self.imageryLayer withName:@"Imagery"];
self.imageryView.hidden = YES;
self.reliefLayer = [AGSTiledMapServiceLayer tiledMapServiceLayerWithURL:[NSURL URLWithString:kTiledReliefMapServiceURL]];
self.reliefView = [self.mapView addMapLayer:self.reliefLayer withName:@"Relief"];
self.reliefView.hidden = YES;
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
self.mapView = nil;
self.streetView = nil;
self.streetLayer = nil;
self.imageryView = nil;
self.imageryLayer = nil;
self.reliefView = nil;
self.reliefLayer = nil;
[super dealloc];
}
- (IBAction)toggleLayer:(id)sender {
self.streetView.hidden = (((UISegmentedControl *)sender).selectedSegmentIndex != 0);
self.imageryView.hidden = (((UISegmentedControl *)sender).selectedSegmentIndex != 1);
self.reliefView.hidden = (((UISegmentedControl *)sender).selectedSegmentIndex != 2);
}
#pragma mark AGSMapViewDelegate
//called when the map view is loaded (after the view is loaded)
- (void)mapViewDidLoad:(AGSMapView *)mapView {
//create extent to be used as default
AGSEnvelope *envelope = [AGSEnvelope envelopeWithXmin:-124.83145667
ymin:30.49849464
xmax:-113.91375495
ymax:44.69150688
spatialReference:mapView.spatialReference];
//call method to set extent, pass in envelope
[self.mapView performSelector:@selector(zoomToEnvelope:animated:)
withObject:envelope
afterDelay:0.5];
}
@end
There are a couple of points to note about how things are wired up in Interface Builder.
The UISegmentedControl’s Value Changed event is hooked up to the File’s Owner’s toggleLayer function.
And the UISegmentedControl’s Autosizing is set to bottom center. By configuring the control this way in Interface Builder, we do not need to write any code to handle placement of the UISegmentedControl when the view rotates.
Summary
Well, that about covers everything for my first experience with the ESRI iPhone SDK. All in all, I’d say it looks like another great client API for use with ArcGIS Server. For those of us who have been wanting to create native iPhone apps on the ESRI stack, the wait is over!
I hope you enjoyed this brief tour of ESRI’s latest offering.
Click here to download the source code from this article.
Additional Resources