Upload
wo-community
View
432
Download
0
Embed Size (px)
Citation preview
• 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 dbXML
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!