SlideShare a Scribd company logo
iOS for ERREST
Paul Lynch
@pauldlynch
paul@plsys.co.uk
• We know WebObjects & ERREST
• The client problem
• Example ERREST/iOS architecture
• Some code specifics
• Some iOS client-server tips
• NOT how to write an iOS app - NO UITableView, etc
iOS for ERREST
App Store
• Huddle
• b-london
• iWycombe
• SOE Status
• Comet
• Mobile Adventure Walks
Enterprise
• DeLaRue
• Oetker
• Dorchester
• LifeFitness
• BidPresentation x 5
WebObjects
• Powerful system for server based development
• ERREST for RESTful servers
• Historically has used browsers for clients
Problem?
The Client
• HTML
• BUT <table>, Browser Wars, CSS
• Java Client
• BUT - Java - in the client
• Javascript/Single Page Applications
• BUT Javascript?, what framework?
The Client
• iOS
• iPhone for mass distribution
• iPad for Enterprise
• Objective C
• Xcode
• Foundation, UIKit
iOS Statistics (WWDC 2013)
• 600 million units sold
• iPad has 82% tablet market share
• iOS 6 is on 93% of all iOS devices
Objective C
• ARC
• properties
• blocks
• Grand Central Dispatch
• Xcode
• git
• OSS
• Huddle
• SaaS,Windows/IE oriented
• Comet *
• High street large enterprise, high volume shopping, ERREST
• Walks *
• “exergaming”, ERREST,Amazon EC2
• SOE Status
• game server updates
Examples
Comet Architecture
Marketing
db
Reviews
WO db
XML
Linux, mySQL
Change
Report
Mobile
clients
Comet Database
Features: skunum, runId; xml/json held as strings
Category
SKU
Review WC7SKU
Client
REST API
• category - parent, children
• sku
• skudetail - contains full review and XML text
• brand - attribute of sku
Code Approaches
• CometAPI subclasses PLRestful
• per entity subclass (Sku, Category, etc)
• NSURLConnection
• ASIHTTPRequest (not maintained)
• AFNetworking (github)
• RESTKit - RestKit.org
PLRestful.h
@class PLRestful;
typedef void (^PLRestfulAPICompletionBlock)(PLRestful *api, id object, int status, NSError *error);
@interface PLRestful : NSObject
@property (nonatomic, copy) NSString *endpoint;
@property (nonatomic, copy) PLRestfulAPICompletionBlock completionBlock;
@property (nonatomic, copy) NSString *username;
@property (nonatomic, copy) NSString *password;
+ (NSString *)messageForStatus:(int)status;
+ (BOOL)checkReachability:(NSURL *)url;
+ (void)get:(NSString *)requestPath parameters:(NSDictionary *)parameters completionBlock:(PLRestfulAPICompletionBlock)completion;
+ (void)post:(NSString *)requestPath content:(NSDictionary *)content completionBlock:(PLRestfulAPICompletionBlock)completion;
- (void)get:(NSString *)requestPath parameters:(NSDictionary *)parameters completionBlock:(PLRestfulAPICompletionBlock)completion;
- (void)post:(NSString *)requestPath content:(NSDictionary *)content completionBlock:(PLRestfulAPICompletionBlock)completion;
@end
[skudetail viewDidLoad];
NSString *query = [NSString stringWithFormat:@"skudetail/%@.json", [sku valueForKey:@"skuNum"]];
[CometAPI get:query parameters:nil completionBlock:^(CometAPI *api, id object, int status, NSError *error) {
if (error) {
[PRPAlertView showWithTitle:@"Error" message:@"Unable to fetch product details" buttonTitle:@"Continue"];
} else {
self.sku = object;
[self.tableView reloadData];
}
}];
CometAPI get
- (void)get:(NSString *)requestString parameters:(NSDictionary *)parameters completionBlock:(CometAPICompletionBlock)completion {
NSURL *requestURL = [[NSURL URLWithString:endpoint] urlByAddingPath:requestString andParameters:parameters];
NSLog(@"get: '%@'", [requestURL absoluteString]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL];
if (userName && password && useBasicAuthentication) {
NSString *authString = [[NSString stringWithFormat:@"%@:%@", userName, password] base64];
NSString *authHeader = [NSString stringWithFormat:@"Basic %@", authString];
[request setValue:authHeader forHTTPHeaderField:@"Authorization"];! !
}
//[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
! [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
...
CometAPI get
...
self.completionBlock = completion;
[[UIApplication sharedApplication] prp_pushNetworkActivity];
self.restQueue = [[NSOperationQueue alloc] init];
self.restQueue.name = @"Comet REST Queue";
[NSURLConnection sendAsynchronousRequest:request queue:self.restQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if (error) {
NSLog(@"%s %@", __PRETTY_FUNCTION__, error);
[self callCompletionBlockWithObject:nil error:error];
} else {
if ([data length] == 0) {
NSLog(@"no data");
[self callCompletionBlockWithObject:nil error:[NSError errorWithDomain:@"com.plsys.semaphore.CometAPI" code:1001 userInfo:nil]];
} else {
NSError *error;
id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if (object) {
[self callCompletionBlockWithObject:object error:nil];
} else {
NSLog(@"received bad json: (%d) '%@'", [data length], [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
[self callCompletionBlockWithObject:nil error:[NSError errorWithDomain:@"com.plsys.semaphore.CometAPI" code:1002 userInfo:nil]];
}
}
}
}];
}
CometAPI Methods
- (void)callCompletionBlockWithObject:(id)object error:(NSError *)error {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] prp_popNetworkActivity];
self.completionBlock(self, object, error);
});
}
CometAPI Methods
- (NSURL *)urlByAddingPath:(NSString *)path andParameters:(NSDictionary *)parameters; {
NSString *requestString = [[self absoluteString] stringByAppendingPathComponent:path];
if (parameters) {
requestString = [requestString stringByAppendingString:@"?"];
BOOL first = YES;
for (NSString *key in [parameters allKeys]) {
if (!first) {
requestString = [requestString stringByAppendingString:@"&"];
}
requestString = [requestString stringByAppendingString:[NSString stringWithFormat:@"%@=%@", key, [[[parameters
objectForKey:key] description] stringByAddingPercentEscapesUsingEncoding:kCFStringEncodingUTF8]]];
first = NO;
}
}
return [NSURL URLWithString:requestString];
}
Traps
• Connection reliability
• isn’t really “always on”
• Data cacheing
• performance?
• capacity?
• Update cacheing
• Reachability
Write more apps!
Q&A
Paul Lynch
paul@plsys.co.uk
@pauldlynch

More Related Content

PDF
Getting Started with Riak - NoSQL Live 2010 - Boston
PDF
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
PPTX
Jekyll, static websites generator
PDF
Jekyll Presentation Slides
ODP
Introduction to blogging with Jekyll
PDF
State of search | drupal dinner
PDF
Omeka: Open Archives and Exhibits for Anyone
PDF
State of search | drupalcamp ghent
Getting Started with Riak - NoSQL Live 2010 - Boston
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
Jekyll, static websites generator
Jekyll Presentation Slides
Introduction to blogging with Jekyll
State of search | drupal dinner
Omeka: Open Archives and Exhibits for Anyone
State of search | drupalcamp ghent

What's hot (20)

PDF
Riding rails for 10 years
PPTX
In-browser storage and me
KEY
Rails with mongodb
PPTX
SharePoint 2013 APIs
PPTX
2011 NetUG HH: ASP.NET MVC & HTML 5
PDF
Build Reusable Web Components using HTML5 Web cComponents
PDF
0323社内LT大会
PDF
How and When to Use FalcorJS
PDF
State of search | drupalcon dublin
PDF
.NET Core Foundations - Dependency Injection, Logging & Configuration - BASTA...
PDF
A Persistence Service for the OSGi Framework - Carl Rosenberger, Chief Softwa...
KEY
Impression of Rails 3
PPTX
Web Ninja
PDF
Web components
PDF
PHP Indonesia Meetup - What's New in Yii2 and PHP5.5
PPTX
Panada: An Introduction by Iskandar Soesman
KEY
HTML5 History & Features
PPTX
Neos CMS and SEO
PPTX
Service stack all the things
PPTX
PowerShell Basics for Office Apps and Servers
Riding rails for 10 years
In-browser storage and me
Rails with mongodb
SharePoint 2013 APIs
2011 NetUG HH: ASP.NET MVC & HTML 5
Build Reusable Web Components using HTML5 Web cComponents
0323社内LT大会
How and When to Use FalcorJS
State of search | drupalcon dublin
.NET Core Foundations - Dependency Injection, Logging & Configuration - BASTA...
A Persistence Service for the OSGi Framework - Carl Rosenberger, Chief Softwa...
Impression of Rails 3
Web Ninja
Web components
PHP Indonesia Meetup - What's New in Yii2 and PHP5.5
Panada: An Introduction by Iskandar Soesman
HTML5 History & Features
Neos CMS and SEO
Service stack all the things
PowerShell Basics for Office Apps and Servers
Ad

Viewers also liked (18)

PDF
Life outside WO
PDF
PDF
Apache Cayenne for WO Devs
PDF
Migrating existing Projects to Wonder
PDF
Advanced Apache Cayenne
PDF
Using Nagios to monitor your WO systems
PDF
iOS for ERREST - alternative version
PDF
Build and deployment
PDF
D2W Stateful Controllers
PDF
Filtering data with D2W
PDF
Reenabling SOAP using ERJaxWS
PDF
Unit Testing with WOUnit
PDF
Chaining the Beast - Testing Wonder Applications in the Real World
PDF
KAAccessControl
PDF
High availability
PDF
Deploying WO on Windows
PDF
"Framework Principal" pattern
PDF
In memory OLAP engine
Life outside WO
Apache Cayenne for WO Devs
Migrating existing Projects to Wonder
Advanced Apache Cayenne
Using Nagios to monitor your WO systems
iOS for ERREST - alternative version
Build and deployment
D2W Stateful Controllers
Filtering data with D2W
Reenabling SOAP using ERJaxWS
Unit Testing with WOUnit
Chaining the Beast - Testing Wonder Applications in the Real World
KAAccessControl
High availability
Deploying WO on Windows
"Framework Principal" pattern
In memory OLAP engine
Ad

Similar to iOS for ERREST (20)

PDF
Developing iOS REST Applications
PDF
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
KEY
RESTfull with RestKit
KEY
Introduction to Restkit
PDF
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
PDF
- Webexpo 2010
PDF
Rails and iOS with RestKit
PDF
mobile in the cloud with diamonds. improved.
PDF
A Deep Dive into REST API Framework Survey
PPTX
Rest APIs Training
PPTX
REST API Design
PDF
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
PPTX
API Design Tour: Digital River
PPTX
API Design Tour with Digital River and Apigee - June 26th, 2012
PPTX
Iphone client-server app with Rails backend (v3)
PDF
IRJET- Rest API for E-Commerce Site
PPT
ReST-ful Resource Management
PDF
Web Clients for Ruby and What they should be in the future
PDF
Web Services, for DevDays Belfast
PDF
Designing beautiful REST APIs
Developing iOS REST Applications
MPD2011 | Сергей Клюев "RESTfull iOS with RestKit"
RESTfull with RestKit
Introduction to Restkit
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
- Webexpo 2010
Rails and iOS with RestKit
mobile in the cloud with diamonds. improved.
A Deep Dive into REST API Framework Survey
Rest APIs Training
REST API Design
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
API Design Tour: Digital River
API Design Tour with Digital River and Apigee - June 26th, 2012
Iphone client-server app with Rails backend (v3)
IRJET- Rest API for E-Commerce Site
ReST-ful Resource Management
Web Clients for Ruby and What they should be in the future
Web Services, for DevDays Belfast
Designing beautiful REST APIs

More from WO Community (12)

PDF
Localizing your apps for multibyte languages
PDF
PDF
ERGroupware
PDF
D2W Branding Using jQuery ThemeRoller
PDF
CMS / BLOG and SnoWOman
PDF
Using GIT
PDF
Persistent Session Storage
PDF
Back2 future
PDF
WebObjects Optimization
PDF
Dynamic Elements
PDF
Practical ERSync
PDF
ERRest: the Basics
Localizing your apps for multibyte languages
ERGroupware
D2W Branding Using jQuery ThemeRoller
CMS / BLOG and SnoWOman
Using GIT
Persistent Session Storage
Back2 future
WebObjects Optimization
Dynamic Elements
Practical ERSync
ERRest: the Basics

Recently uploaded (20)

PDF
Empathic Computing: Creating Shared Understanding
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Advanced Soft Computing BINUS July 2025.pdf
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
NewMind AI Monthly Chronicles - July 2025
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
[발표본] 너의 과제는 클라우드에 있어_KTDS_김동현_20250524.pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
KodekX | Application Modernization Development
Empathic Computing: Creating Shared Understanding
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Mobile App Security Testing_ A Comprehensive Guide.pdf
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Advanced Soft Computing BINUS July 2025.pdf
Per capita expenditure prediction using model stacking based on satellite ima...
Reach Out and Touch Someone: Haptics and Empathic Computing
NewMind AI Monthly Chronicles - July 2025
The AUB Centre for AI in Media Proposal.docx
[발표본] 너의 과제는 클라우드에 있어_KTDS_김동현_20250524.pdf
Understanding_Digital_Forensics_Presentation.pptx
Big Data Technologies - Introduction.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
20250228 LYD VKU AI Blended-Learning.pptx
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
KodekX | Application Modernization Development

iOS for ERREST

  • 1. iOS for ERREST Paul Lynch @pauldlynch paul@plsys.co.uk
  • 2. • We know WebObjects & ERREST • The client problem • Example ERREST/iOS architecture • Some code specifics • Some iOS client-server tips • NOT how to write an iOS app - NO UITableView, etc iOS for ERREST
  • 3. App Store • Huddle • b-london • iWycombe • SOE Status • Comet • Mobile Adventure Walks
  • 4. Enterprise • DeLaRue • Oetker • Dorchester • LifeFitness • BidPresentation x 5
  • 5. WebObjects • Powerful system for server based development • ERREST for RESTful servers • Historically has used browsers for clients
  • 7. The Client • HTML • BUT <table>, Browser Wars, CSS • Java Client • BUT - Java - in the client • Javascript/Single Page Applications • BUT Javascript?, what framework?
  • 8. The Client • iOS • iPhone for mass distribution • iPad for Enterprise • Objective C • Xcode • Foundation, UIKit
  • 9. iOS Statistics (WWDC 2013) • 600 million units sold • iPad has 82% tablet market share • iOS 6 is on 93% of all iOS devices
  • 10. Objective C • ARC • properties • blocks • Grand Central Dispatch • Xcode • git • OSS
  • 11. • Huddle • SaaS,Windows/IE oriented • Comet * • High street large enterprise, high volume shopping, ERREST • Walks * • “exergaming”, ERREST,Amazon EC2 • SOE Status • game server updates Examples
  • 12. Comet Architecture Marketing db Reviews WO db XML Linux, mySQL Change Report Mobile clients
  • 13. Comet Database Features: skunum, runId; xml/json held as strings Category SKU Review WC7SKU Client
  • 14. REST API • category - parent, children • sku • skudetail - contains full review and XML text • brand - attribute of sku
  • 15. Code Approaches • CometAPI subclasses PLRestful • per entity subclass (Sku, Category, etc) • NSURLConnection • ASIHTTPRequest (not maintained) • AFNetworking (github) • RESTKit - RestKit.org
  • 16. PLRestful.h @class PLRestful; typedef void (^PLRestfulAPICompletionBlock)(PLRestful *api, id object, int status, NSError *error); @interface PLRestful : NSObject @property (nonatomic, copy) NSString *endpoint; @property (nonatomic, copy) PLRestfulAPICompletionBlock completionBlock; @property (nonatomic, copy) NSString *username; @property (nonatomic, copy) NSString *password; + (NSString *)messageForStatus:(int)status; + (BOOL)checkReachability:(NSURL *)url; + (void)get:(NSString *)requestPath parameters:(NSDictionary *)parameters completionBlock:(PLRestfulAPICompletionBlock)completion; + (void)post:(NSString *)requestPath content:(NSDictionary *)content completionBlock:(PLRestfulAPICompletionBlock)completion; - (void)get:(NSString *)requestPath parameters:(NSDictionary *)parameters completionBlock:(PLRestfulAPICompletionBlock)completion; - (void)post:(NSString *)requestPath content:(NSDictionary *)content completionBlock:(PLRestfulAPICompletionBlock)completion; @end
  • 17. [skudetail viewDidLoad]; NSString *query = [NSString stringWithFormat:@"skudetail/%@.json", [sku valueForKey:@"skuNum"]]; [CometAPI get:query parameters:nil completionBlock:^(CometAPI *api, id object, int status, NSError *error) { if (error) { [PRPAlertView showWithTitle:@"Error" message:@"Unable to fetch product details" buttonTitle:@"Continue"]; } else { self.sku = object; [self.tableView reloadData]; } }];
  • 18. CometAPI get - (void)get:(NSString *)requestString parameters:(NSDictionary *)parameters completionBlock:(CometAPICompletionBlock)completion { NSURL *requestURL = [[NSURL URLWithString:endpoint] urlByAddingPath:requestString andParameters:parameters]; NSLog(@"get: '%@'", [requestURL absoluteString]); NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:requestURL]; if (userName && password && useBasicAuthentication) { NSString *authString = [[NSString stringWithFormat:@"%@:%@", userName, password] base64]; NSString *authHeader = [NSString stringWithFormat:@"Basic %@", authString]; [request setValue:authHeader forHTTPHeaderField:@"Authorization"];! ! } //[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; ! [request setValue:@"application/json" forHTTPHeaderField:@"Accept"]; ...
  • 19. CometAPI get ... self.completionBlock = completion; [[UIApplication sharedApplication] prp_pushNetworkActivity]; self.restQueue = [[NSOperationQueue alloc] init]; self.restQueue.name = @"Comet REST Queue"; [NSURLConnection sendAsynchronousRequest:request queue:self.restQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ if (error) { NSLog(@"%s %@", __PRETTY_FUNCTION__, error); [self callCompletionBlockWithObject:nil error:error]; } else { if ([data length] == 0) { NSLog(@"no data"); [self callCompletionBlockWithObject:nil error:[NSError errorWithDomain:@"com.plsys.semaphore.CometAPI" code:1001 userInfo:nil]]; } else { NSError *error; id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; if (object) { [self callCompletionBlockWithObject:object error:nil]; } else { NSLog(@"received bad json: (%d) '%@'", [data length], [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); [self callCompletionBlockWithObject:nil error:[NSError errorWithDomain:@"com.plsys.semaphore.CometAPI" code:1002 userInfo:nil]]; } } } }]; }
  • 20. CometAPI Methods - (void)callCompletionBlockWithObject:(id)object error:(NSError *)error { dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] prp_popNetworkActivity]; self.completionBlock(self, object, error); }); }
  • 21. CometAPI Methods - (NSURL *)urlByAddingPath:(NSString *)path andParameters:(NSDictionary *)parameters; { NSString *requestString = [[self absoluteString] stringByAppendingPathComponent:path]; if (parameters) { requestString = [requestString stringByAppendingString:@"?"]; BOOL first = YES; for (NSString *key in [parameters allKeys]) { if (!first) { requestString = [requestString stringByAppendingString:@"&"]; } requestString = [requestString stringByAppendingString:[NSString stringWithFormat:@"%@=%@", key, [[[parameters objectForKey:key] description] stringByAddingPercentEscapesUsingEncoding:kCFStringEncodingUTF8]]]; first = NO; } } return [NSURL URLWithString:requestString]; }
  • 22. Traps • Connection reliability • isn’t really “always on” • Data cacheing • performance? • capacity? • Update cacheing • Reachability