Transcript
Page 1: iOS Api Client: soluzioni a confronto

iOS Api ClientSoluzioni a confronto

Massimo Oliviero - Cappery S.r.l.Francesco Sinopoli - Tiltap S.r.l.

Monday, May 28, 12

Page 2: iOS Api Client: soluzioni a confronto

Chi siamo

Massimo Olivierohttp://www.massimooliviero.net - @maxoly

Co-founder & CEO di Cappery www.cappery.com

Co-founder di # pragma mark www.pragmamark.org

Monday, May 28, 12

Page 4: iOS Api Client: soluzioni a confronto

Disclaimer

• Non è una sessione su REST

• Non è una sessione su sulle API Server

• Non vuole essere una sessione esauriente

Monday, May 28, 12

Page 5: iOS Api Client: soluzioni a confronto

Agenda

• Architettura

• Framework custom

• Framework terze parti: REST Kit

Monday, May 28, 12

Page 6: iOS Api Client: soluzioni a confronto

Scenari

Monday, May 28, 12

Page 7: iOS Api Client: soluzioni a confronto

Scenari

• Scenario AServer Api non REST(ful)

Monday, May 28, 12

Page 8: iOS Api Client: soluzioni a confronto

Scenari

• Scenario AServer Api non REST(ful)

• Scenario BServer API REST(ful)

Monday, May 28, 12

Page 9: iOS Api Client: soluzioni a confronto

Soluzioni

Monday, May 28, 12

Page 10: iOS Api Client: soluzioni a confronto

Soluzioni

A. Easy (w lo spaghetti code!)

Monday, May 28, 12

Page 11: iOS Api Client: soluzioni a confronto

Soluzioni

A. Easy (w lo spaghetti code!)

B. Framework custom

Monday, May 28, 12

Page 12: iOS Api Client: soluzioni a confronto

Soluzioni

A. Easy (w lo spaghetti code!)

B. Framework custom

C. Framework di terze parti

Monday, May 28, 12

Page 13: iOS Api Client: soluzioni a confronto

Un nuovo progetto

Monday, May 28, 12

Page 14: iOS Api Client: soluzioni a confronto

Un nuovo progetto

Monday, May 28, 12

Page 15: iOS Api Client: soluzioni a confronto

Un nuovo progetto• App per la N.A.S.A.

Monday, May 28, 12

Page 16: iOS Api Client: soluzioni a confronto

Un nuovo progetto• App per la N.A.S.A.

• Con tre view (Lista pianeti + Lista rover sul pianeta + dettaglio rover)

Monday, May 28, 12

Page 17: iOS Api Client: soluzioni a confronto

Un nuovo progetto• App per la N.A.S.A.

• Con tre view (Lista pianeti + Lista rover sul pianeta + dettaglio rover)

• Il dettaglio deve mostrare alcuni parametri del rover (es. Opportunity su Marte)

Monday, May 28, 12

Page 18: iOS Api Client: soluzioni a confronto

Un nuovo progetto• App per la N.A.S.A.

• Con tre view (Lista pianeti + Lista rover sul pianeta + dettaglio rover)

• Il dettaglio deve mostrare alcuni parametri del rover (es. Opportunity su Marte)

• Lettura dei dati tramite server API della NASA

Monday, May 28, 12

Page 19: iOS Api Client: soluzioni a confronto

Un nuovo progetto• App per la N.A.S.A.

• Con tre view (Lista pianeti + Lista rover sul pianeta + dettaglio rover)

• Il dettaglio deve mostrare alcuni parametri del rover (es. Opportunity su Marte)

• Lettura dei dati tramite server API della NASA

• 10 gg/u

Monday, May 28, 12

Page 20: iOS Api Client: soluzioni a confronto

Dominio

Planet Rover Cam1 n 1 n

Geo

1

1

Monday, May 28, 12

Page 21: iOS Api Client: soluzioni a confronto

Server

• REQUESTGET /opportuniy_get_info.aspx?id=11A1&planet=mars

• RESPONSEcontent-type: text/html

Monday, May 28, 12

Page 22: iOS Api Client: soluzioni a confronto

Server

• REQUESTGET /opportuniy_get_info.aspx?id=11A1&planet=mars

• RESPONSEcontent-type: text/html

Monday, May 28, 12

Page 23: iOS Api Client: soluzioni a confronto

Non ci REST che piang!

Monday, May 28, 12

Page 24: iOS Api Client: soluzioni a confronto

Non ci REST che piang!

Monday, May 28, 12

Page 25: iOS Api Client: soluzioni a confronto

Non ci REST che piang!

Accettiamo la sfida!

Monday, May 28, 12

Page 26: iOS Api Client: soluzioni a confronto

Soluzione Bsviluppiamo un framework custom

Monday, May 28, 12

Page 27: iOS Api Client: soluzioni a confronto

Framework custom

Domande

• Cosa vuol dire sviluppare un framework custom?

• Quando sviluppare un framework custom?

• Quali sono i vantaggi?

• Quali sono gli svantaggi?

Monday, May 28, 12

Page 28: iOS Api Client: soluzioni a confronto

Architetturaun approccio graduale

Monday, May 28, 12

Page 29: iOS Api Client: soluzioni a confronto

Layers

Monday, May 28, 12

Page 30: iOS Api Client: soluzioni a confronto

LayersView

Monday, May 28, 12

Page 31: iOS Api Client: soluzioni a confronto

LayersView

Controller

Monday, May 28, 12

Page 32: iOS Api Client: soluzioni a confronto

Layers

Network Layer

View

Controller

Monday, May 28, 12

Page 33: iOS Api Client: soluzioni a confronto

Layers

Network Layer

View

Controller

Domain Model Layer

Monday, May 28, 12

Page 34: iOS Api Client: soluzioni a confronto

Layers

Network Layer

View

Controller

Domain Model Layer

Data Layer

Monday, May 28, 12

Page 35: iOS Api Client: soluzioni a confronto

Layers

Network Layer

View

Controller

Domain Model Layer

Data Layer

Business Layer

Monday, May 28, 12

Page 36: iOS Api Client: soluzioni a confronto

Layers

Network Layer

View

Controller

Domain Model Layer

Data Layer

Business Layer

Monday, May 28, 12

Page 37: iOS Api Client: soluzioni a confronto

Example Code

PMStarterKitPragma Mark Starter Kithttps://github.com/pragmamark/PMStarterKit

PMTouchPragma Mark iOS General Purpose Libraryhttps://github.com/pragmamark/PMTouch

Monday, May 28, 12

Page 38: iOS Api Client: soluzioni a confronto

Network Layeril primo mattoncino della nostra architettura

Monday, May 28, 12

Page 39: iOS Api Client: soluzioni a confronto

Network Layer

Cosa deve fare

• Gestire URL e risorse

• Gestire request e response

• Gestire proxy & authentication

• Gestire la cache (Cache-Control & ETag)

Monday, May 28, 12

Page 40: iOS Api Client: soluzioni a confronto

Request

Monday, May 28, 12

Page 41: iOS Api Client: soluzioni a confronto

Request

Request

Network Layer

Monday, May 28, 12

Page 42: iOS Api Client: soluzioni a confronto

Request

Cosa deve fare

• Incapsulare una singola chiamata di rete ad una risorsa (URL) specifica

• Gestire i verbi HTTP (GET, POST, PUT, DELETE..)

• Gestire i parametri

Monday, May 28, 12

Page 43: iOS Api Client: soluzioni a confronto

NSURLConnection- (void)viewDidLoad{ [super viewDidLoad]; static NSString *url = @"http://..../?p1=v1&p2=v2"; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];}

.....

- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)data- (void)connection:(NSURLConnection *)theConnection didFailWithError:(NSError *)error- (void)connectionDidFinishLoading:(NSURLConnection *)theConnection- (void)connection:(NSURLConnection *)theConnection didReceiveResponse:(NSURLResponse *)response

Monday, May 28, 12

Page 44: iOS Api Client: soluzioni a confronto

Monday, May 28, 12

Page 45: iOS Api Client: soluzioni a confronto

NSURLConnection

Monday, May 28, 12

Page 46: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

Monday, May 28, 12

Page 47: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

Monday, May 28, 12

Page 48: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

Monday, May 28, 12

Page 49: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

• Flessibile

Monday, May 28, 12

Page 50: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

• Flessibile

Monday, May 28, 12

Page 51: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

• Flessibile

Monday, May 28, 12

Page 52: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

• Flessibile

Contro

Monday, May 28, 12

Page 53: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

• Flessibile

Contro

• Povero

Monday, May 28, 12

Page 54: iOS Api Client: soluzioni a confronto

NSURLConnectionPro

• Nativo

• Documentato

• Flessibile

Contro

• Povero

• Verboso

Monday, May 28, 12

Page 55: iOS Api Client: soluzioni a confronto

Alternative

• ASIHTTPRequesthttps://github.com/pokeb/asi-http-request/tree

• AFNetwork (by Gowalla)https://github.com/AFNetworking/AFNetworking

• MKNetworkKithttps://github.com/MugunthKumar/MKNetworkKit

Monday, May 28, 12

Page 57: iOS Api Client: soluzioni a confronto

ASIHTTPRequest- (void)viewDidLoad{ [super viewDidLoad]; NSURL *url = [NSURL URLWithString:@"http://www.apple.com"]; ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:url]; self.request = request; [request release]; [self.request setDelegate:self]; [self.request startAsynchronous];}

- (void)requestStarted:(ASIHTTPRequest *)request{}

- (void)requestFinished:(ASIHTTPRequest *)request{}

- (void)requestFailed:(ASIHTTPRequest *)request{}

Monday, May 28, 12

Page 58: iOS Api Client: soluzioni a confronto

AFNetworking

• HTTP Requests (cancelled, suspended / resumed)

• Authenticating requests with HTTP Basic credentials or an OAuth token

• Blocks

• feature-rich APIs

Monday, May 28, 12

Page 59: iOS Api Client: soluzioni a confronto

AFNetworkigNSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { NSLog(@"Public Timeline: %@", JSON);} failure:nil];[operation start];

Monday, May 28, 12

Page 60: iOS Api Client: soluzioni a confronto

Response

Network Layer

Monday, May 28, 12

Page 61: iOS Api Client: soluzioni a confronto

Response

Network Layer

Monday, May 28, 12

Page 62: iOS Api Client: soluzioni a confronto

Response

Request

Network Layer

Monday, May 28, 12

Page 63: iOS Api Client: soluzioni a confronto

Response

Request Response

Network Layer

Monday, May 28, 12

Page 64: iOS Api Client: soluzioni a confronto

Response

Request Response

Network Layer

Monday, May 28, 12

Page 65: iOS Api Client: soluzioni a confronto

Response

Request Response

Network Layer

Monday, May 28, 12

Page 66: iOS Api Client: soluzioni a confronto

Response

Request Response

Network Layer

Monday, May 28, 12

Page 67: iOS Api Client: soluzioni a confronto

Response

Cosa deve fare

• Incapsulare l’HTTP Response (Header, Status code etc.)

• Payload (HTTP Content body)

• Result (JSON > NSArray/NSDictionary etc.)

• Error

Monday, May 28, 12

Page 68: iOS Api Client: soluzioni a confronto

Response@interface PMTResponse : NSObject{ PMTRequest *_request; NSString *_contentBody; NSError *_error; NSObject *_result;}

@property (nonatomic, retain, readonly) PMTRequest *request;@property (nonatomic, retain, readonly) NSString *contentBody;@property (nonatomic, retain, readonly) NSError *error;@property (nonatomic, retain, readonly) NSObject *result;

- (id)initWithRequest:(PMTRequest *)request;- (id)initWithRequest:(PMTRequest *)request result:(NSObject *)result;- (id)initWithRequest:(PMTRequest *)request result:(NSObject *)result error:(NSError *)error;

@end

Monday, May 28, 12

Page 69: iOS Api Client: soluzioni a confronto

Parser

Cosa deve fare

• Trasformare stringhe o dati binari in strutture dati native (es. da JSon a NSArray).

Monday, May 28, 12

Page 70: iOS Api Client: soluzioni a confronto

JSON Parser

Alcune librerie

• NSJSONSerialization

• JSONKit

• SBJson

Benckmarkshttps://github.com/samsoffes/json-benchmarks

Monday, May 28, 12

Page 71: iOS Api Client: soluzioni a confronto

XML ParserAlcune librerie

• NSXMLParser (modalità SAX)

• libxml2 (C Library SAX e DOM)

• TBXML (DOM)

• TouchXML (NSXML DOM)

• KissXML (NSXML DOM)

• TinyXML (C Library DOM)

Monday, May 28, 12

Page 72: iOS Api Client: soluzioni a confronto

Cache

Network Layer

Monday, May 28, 12

Page 73: iOS Api Client: soluzioni a confronto

Cache

Network Layer

Monday, May 28, 12

Page 74: iOS Api Client: soluzioni a confronto

Cache

Request

Network Layer

Monday, May 28, 12

Page 75: iOS Api Client: soluzioni a confronto

Cache

Request Response

Network Layer

Monday, May 28, 12

Page 76: iOS Api Client: soluzioni a confronto

Cache

Request Response Cache

Network Layer

Monday, May 28, 12

Page 77: iOS Api Client: soluzioni a confronto

Cache

Request Response Cache

Network Layer

Monday, May 28, 12

Page 78: iOS Api Client: soluzioni a confronto

Cache

Request Response Cache

Network Layer

Monday, May 28, 12

Page 79: iOS Api Client: soluzioni a confronto

Cache

Cosa deve fare

• Gestire la direttiva cache-control

• Gestire la direttiva ETag

• Storage policy: per session o permanent

Monday, May 28, 12

Page 80: iOS Api Client: soluzioni a confronto

Cache

• A cosa serveA gestire la cache

• Quando utilizzarlaQuando il server lo prevede e lo gestisce in modo efficente ed efficace con le direttive HTTP.

• Perché utilizzarlaPerché diminuisce il traffico di rete e di conseguenza aumenta la responsività dell’app.

Monday, May 28, 12

Page 81: iOS Api Client: soluzioni a confronto

Client

Network Layer

Monday, May 28, 12

Page 82: iOS Api Client: soluzioni a confronto

Client

Network Layer

Monday, May 28, 12

Page 83: iOS Api Client: soluzioni a confronto

Client

Request

Network Layer

Monday, May 28, 12

Page 84: iOS Api Client: soluzioni a confronto

Client

Request Response

Network Layer

Monday, May 28, 12

Page 85: iOS Api Client: soluzioni a confronto

Client

Request Response Cache

Network Layer

Monday, May 28, 12

Page 86: iOS Api Client: soluzioni a confronto

Client

Request Response Cache Client

Network Layer

Monday, May 28, 12

Page 87: iOS Api Client: soluzioni a confronto

Client

Request Response Cache Client

Network Layer

Monday, May 28, 12

Page 88: iOS Api Client: soluzioni a confronto

Client

Cosa deve fare

• Gestire ambienti diversi (produzione, sviluppo, stage, etc.)

• Aprire e chiudere tunnel ssh o vpn

• Gestire l’autenticazione

Monday, May 28, 12

Page 89: iOS Api Client: soluzioni a confronto

Client

• A cosa serveAd incapsulare le request in ambienti specifici.

• Quando utilizzarloQuando si gestiscono ambienti diversi (stage, prod. etc.) o quando si utilizzano tunnel SSH o VPN.

• Perché utilizzarloPer isolare la gestione di queste specifiche funzionalità.

Monday, May 28, 12

Page 90: iOS Api Client: soluzioni a confronto

Client@interface PMTClient : NSObject{ NSURL *_baseUrl; NSString *_username; NSString *_password;}

@property (nonatomic, retain, readonly) NSURL *baseUrl;@property (nonatomic, copy) NSString *username;@property (nonatomic, copy) NSString *password;

- (id)initWithBaseURL:(NSURL *)baseUrl;- (id)initWithBaseURL:(NSURL *)baseUrl username:(NSString *)username password:(NSString *)password;

- (PMTRequest *)createRequest:(NSString *)stringUrl delegate:(id<PMTRequestDelegate>)delegate;

Monday, May 28, 12

Page 91: iOS Api Client: soluzioni a confronto

Network Manager

Network Layer

Monday, May 28, 12

Page 92: iOS Api Client: soluzioni a confronto

Network Manager

Request

Network Layer

Monday, May 28, 12

Page 93: iOS Api Client: soluzioni a confronto

Network Manager

Request Response

Network Layer

Monday, May 28, 12

Page 94: iOS Api Client: soluzioni a confronto

Network Manager

Request Response Cache

Network Layer

Monday, May 28, 12

Page 95: iOS Api Client: soluzioni a confronto

Network Manager

Request Response Cache Client

Network Layer

Monday, May 28, 12

Page 96: iOS Api Client: soluzioni a confronto

Network Manager

Request Response Cache Client

Network Manager

Network Layer

Monday, May 28, 12

Page 97: iOS Api Client: soluzioni a confronto

Network Manager

Cosa deve fare

• Creare ed eseguire le request tramite il client

• Gestire le code di request

• Gestire il suspend e il resume

Monday, May 28, 12

Page 98: iOS Api Client: soluzioni a confronto

Network Manager• A cosa serve

A governare il network layer.

• Quando utilizzarloQuando si vuole disaccopiare e gestire attività complesse come le code, etc.

• Perché utilizzarloDisaccoppia il view controller dall’implementazione di rete e di conseguenza aumenta la manutenibilità del codice.

Monday, May 28, 12

Page 99: iOS Api Client: soluzioni a confronto

Network Manager@interface PMTNetworkManager : NSObject{ SPKRequestQueue *_requestQueue;}

@property (nonatomic, retain, readonly) PMTRequestQueue *requestQueue;@property (nonatomic, assing) BOOL enableSuspendResume;

- (PMTRequest *)requestAdd:(NSString *)request params:(NSDictionary *)params- (PMTRequest *)requestAdd:(NSString *)request params:(NSDictionary *)params queue:(NSString *)queueName;

- (void)addQueue:(NSString *)queueName;

- (void)requestsStart;- (void)requestsStop;

@end

Monday, May 28, 12

Page 100: iOS Api Client: soluzioni a confronto

Network Layer

Quando utilizzare un networking framework?

• SEMPRE, quando possibile evitare di utilizzare direttamente NSURLConnection. Non ha senso.

• Framework come ASIHTTPRequest o AFNetworking semplicano troppo la vita per non essere utilizzati. (Twitter e Facebook docet)

Monday, May 28, 12

Page 101: iOS Api Client: soluzioni a confronto

Network Layer

Monday, May 28, 12

Page 102: iOS Api Client: soluzioni a confronto

Network LayerIn conclusione

• HTTP Request & Response

• Tunneling SSH/VPN

• Ambienti (stage, produzione etc.)

• Cache (HTTP)

• Network Manager

Monday, May 28, 12

Page 103: iOS Api Client: soluzioni a confronto

Network LayerIn conclusione

• HTTP Request & Response

• Tunneling SSH/VPN

• Ambienti (stage, produzione etc.)

• Cache (HTTP)

• Network Manager

Monday, May 28, 12

Page 104: iOS Api Client: soluzioni a confronto

One more thing...

Monday, May 28, 12

Page 105: iOS Api Client: soluzioni a confronto

One more thing...

Monday, May 28, 12

Page 106: iOS Api Client: soluzioni a confronto

One more thing...

“Oltre che leggere l’app deve poter anche inviare dei comandi al rover!”

Monday, May 28, 12

Page 107: iOS Api Client: soluzioni a confronto

Domain Model Layermodelliamo il nostro business

Monday, May 28, 12

Page 108: iOS Api Client: soluzioni a confronto

Domain Model Layer

Cosa deve fare

• Gestire il dato (entità e relazioni)

• Gestire il comportamento

• Convertire il dato da una forma ad un’altra

Monday, May 28, 12

Page 109: iOS Api Client: soluzioni a confronto

Model

Domain Model Layer

Monday, May 28, 12

Page 110: iOS Api Client: soluzioni a confronto

Model

Domain Model Layer

Monday, May 28, 12

Page 111: iOS Api Client: soluzioni a confronto

Model

Model

Domain Model Layer

Monday, May 28, 12

Page 112: iOS Api Client: soluzioni a confronto

Model

Model

Domain Model Layer

Monday, May 28, 12

Page 113: iOS Api Client: soluzioni a confronto

Model

Cosa deve fare

• Rappresentare l’informazione attraverso l’ausilio di una struttura dati nativa o custom

• Possibilmente oltre al dato dovrebbe incorporare anche il comportamento

Monday, May 28, 12

Page 114: iOS Api Client: soluzioni a confronto

NSDictionary & NSArray

NSDictionary *element = [self.elements objectAtIndex:indexPath.row]; cell.textLabel.text = [element objectForKey:@"name"]; cell.detailTextLabel.text = [element objectForKey:@"description"];

Monday, May 28, 12

Page 115: iOS Api Client: soluzioni a confronto

NSObject@interface PMSKPlanet : NSObject

@property (nonatomic, copy, readonly) NSString *name;@property (nonatomic, retain, readonly) PMSKGalaxy *galaxy;

- (id)initWithName:(NSString *)name galaxy:(PMSKGalaxy *)galaxy;

@end

@interface PMSKGalaxy : NSObject

@property (nonatomic, copy, readonly) NSString *name;@property (nonatomic, retain, readonly) NSArray *planets;

- (id)initWithName:(NSString *)name;

@end

Monday, May 28, 12

Page 116: iOS Api Client: soluzioni a confronto

Mapper

Domain Model Layer

Monday, May 28, 12

Page 117: iOS Api Client: soluzioni a confronto

Mapper

Domain Model Layer

Monday, May 28, 12

Page 118: iOS Api Client: soluzioni a confronto

Mapper

Domain Model Layer

Model

Monday, May 28, 12

Page 119: iOS Api Client: soluzioni a confronto

Mapper

Domain Model Layer

Model Mapper

Monday, May 28, 12

Page 120: iOS Api Client: soluzioni a confronto

Mapper

Cosa deve fare

• Definire le regole di traformazione da una struttura dati ad un’altra (es. NSArray to NSObject)

• Gestire le regole e fornirle su richiesta attraverso un sistema centralizzato

Monday, May 28, 12

Page 121: iOS Api Client: soluzioni a confronto

Object Mapper@interface PMTObjectMapper : NSObject

- (void)mapKey:(NSString *)mapKey toProperty:(NSString *)property;

+ (PMTObjectMapper *)mapperForClass:(Class)class;

@end

PMTObjectMapper *mapper = [PMTObjectMapper mapperForClass:[PMSKGalaxy class]];[mapper mapKey:@"planet_name" toProperty:@"name"];[mapper mapKey:@"solar_distance" toProperty:@"solarDistance"];

Monday, May 28, 12

Page 122: iOS Api Client: soluzioni a confronto

Domain Model

Monday, May 28, 12

Page 123: iOS Api Client: soluzioni a confronto

Domain Model

In conclusione

• Entità e relazioni

• Mappatura

Monday, May 28, 12

Page 124: iOS Api Client: soluzioni a confronto

Domain Model

In conclusione

• Entità e relazioni

• Mappatura

Monday, May 28, 12

Page 125: iOS Api Client: soluzioni a confronto

One more “little” thing

Monday, May 28, 12

Page 126: iOS Api Client: soluzioni a confronto

One more “little” thing

Monday, May 28, 12

Page 127: iOS Api Client: soluzioni a confronto

One more “little” thing

“L’applicazione deve funzionare anche OFFLINE”

Monday, May 28, 12

Page 128: iOS Api Client: soluzioni a confronto

Data Layerpersistiamo i nostri dati

Monday, May 28, 12

Page 129: iOS Api Client: soluzioni a confronto

Data Layer

Cosa deve fare

• Persistere le informazioni

• Recuperare le informazioni

Monday, May 28, 12

Page 130: iOS Api Client: soluzioni a confronto

Store

Data Layer

Monday, May 28, 12

Page 131: iOS Api Client: soluzioni a confronto

Store

Data Layer

Monday, May 28, 12

Page 132: iOS Api Client: soluzioni a confronto

Store

Store

Data Layer

Monday, May 28, 12

Page 133: iOS Api Client: soluzioni a confronto

Store

Store

Data Layer

Monday, May 28, 12

Page 134: iOS Api Client: soluzioni a confronto

File system

• File systemNSCoding, NSKeyedArchiver, NSKeyedUnarchiver

• PlistNSDictionary, NSArray, NSFileManager

Monday, May 28, 12

Page 135: iOS Api Client: soluzioni a confronto

Relational

• FMDB (Objective-C wrapper around SQLite)https://github.com/ccgus/fmdb

• CoreData (object graph & persistence framework)http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coredata/cdprogrammingguide.html

Monday, May 28, 12

Page 136: iOS Api Client: soluzioni a confronto

Manager

Data Layer

Monday, May 28, 12

Page 137: iOS Api Client: soluzioni a confronto

Manager

Data Layer

Monday, May 28, 12

Page 138: iOS Api Client: soluzioni a confronto

Manager

Store

Data Layer

Monday, May 28, 12

Page 139: iOS Api Client: soluzioni a confronto

Manager

Store

Data Layer

Manager

Monday, May 28, 12

Page 140: iOS Api Client: soluzioni a confronto

Manager

Cosa deve fare

• Fornire un’interfaccia di accesso ai dati persistiti

• Fornire strumenti di interrogazione

Monday, May 28, 12

Page 141: iOS Api Client: soluzioni a confronto

Conclusionie quindi?

Monday, May 28, 12

Page 142: iOS Api Client: soluzioni a confronto

Framework custom

Layer Quando

Network Layer SEMPRE

Domain Model Leggere e scrivere

Data Layer Offline

Monday, May 28, 12

Page 143: iOS Api Client: soluzioni a confronto

Framework custom

Monday, May 28, 12

Page 144: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

Monday, May 28, 12

Page 145: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

Monday, May 28, 12

Page 146: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

• Modulare

Monday, May 28, 12

Page 147: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

• Modulare

• Flessibile (Business)

Monday, May 28, 12

Page 148: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

• Modulare

• Flessibile (Business)

Svantaggi

Monday, May 28, 12

Page 149: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

• Modulare

• Flessibile (Business)

Svantaggi

• Tempo (Costi)

Monday, May 28, 12

Page 150: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

• Modulare

• Flessibile (Business)

Svantaggi

• Tempo (Costi)

• Skill

Monday, May 28, 12

Page 151: iOS Api Client: soluzioni a confronto

Framework custom

Vantaggi

• Know-how

• Modulare

• Flessibile (Business)

Svantaggi

• Tempo (Costi)

• Skill

• Declinato

Monday, May 28, 12

Page 152: iOS Api Client: soluzioni a confronto

Soluzione C

API +

Dominio di Business =

Monday, May 28, 12

Page 153: iOS Api Client: soluzioni a confronto

RestKit

Che cosa è ?Restkit è un framework Objective-C per iOS che ha lo scopo di facilitare l'interazione con i web-service.

Monday, May 28, 12

Page 154: iOS Api Client: soluzioni a confronto

Che cosa fa ?

HTTP PROTOCOLREST SOAP XMLENCODE PARSER

CODE ACTIVE RECORDPATTERN MAPPING

CACHE STRATEGY SQL

RestKit

Monday, May 28, 12

Page 155: iOS Api Client: soluzioni a confronto

Network Layer

“Ha la funzione di costruire e consegnare le richieste HTTP e processare le risposte che arrivano dal server remoto”

Obiettivo

Come raggiunge l’obiettivo?

RKClient RKRequest RKResponse

Attraverso tre attori principali

Monday, May 28, 12

Page 156: iOS Api Client: soluzioni a confronto

Network Layer

RKClientHttp headers - Type Authentication

Base URL

RKClient

App

Monday, May 28, 12

Page 157: iOS Api Client: soluzioni a confronto

Network Layer

RKClientHttp headers - Type Authentication

Base URL

RKClient Http headers - Type Authentication

Base URL

RKClient

App

Monday, May 28, 12

Page 158: iOS Api Client: soluzioni a confronto

Network LayerRKClientRKRequestRKResponse

#import "AppDelegate.h"#import <RestKit/RestKit.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ RKClient *client = [RKClient clientWithBaseURL:@"https://api.pragma-mark.org/sampleQuiz"];...

[RKClient sharedClient]

Da qui in poi avremo disponibile

Monday, May 28, 12

Page 159: iOS Api Client: soluzioni a confronto

Network Layer

@implementation MyViewController...

#pragma mark - View lifecycle

- (void)viewDidLoad{ [super viewDidLoad];

[[RKClient sharedClient] get:@"/collections/questions" delegate:self];}

#pragma mark - Restkit delegate

- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response { NSLog(@"Loaded payload: %@ with code %i", [response bodyAsString], [response statusCode]); }

-(void)request:(RKRequest*)request didFailLoadWithError:(NSError*)error{ NSLog(@"Error %@",[error localizedDescription]);}

#import <UIKit/UIKit.h>#import <RestKit/RestKit.h>

@interface MyViewController : UIViewController<RKRequestDelegate>{...

Una volta configurato un client possiamo inviare e processare richieste HTTP attraverso esso.

Esempio: invio richiesta e visualizzazione risposta

resource path

Monday, May 28, 12

Page 160: iOS Api Client: soluzioni a confronto

Network Layer

?payload

Siamo in grado di comunicare con un

web service remoto, inviare

richieste e processare risposte,

Web Service

Monday, May 28, 12

Page 161: iOS Api Client: soluzioni a confronto

Object Mapping

Quando ne abbiamo bisogno e che cosa è?

Punto di forza di RestKit

E’ un sistema che ci permette di trasformare le risposte JSON/XML in oggetti di dominio locali.

Salendo di astrazione: è un sistema che si occupa di trasformare i dati da un formato ad un altro.

Quando si ha necessità, non solo di scambiare dati, ma di rappresentare oggetti.

Monday, May 28, 12

Page 162: iOS Api Client: soluzioni a confronto

Object Mapping

RKObjectManager RKObjectMapping

RKObjectMapper RKObjectMappingProvider

•Quando carichiamo un risorsa remota tramite un’istanza di RKObjectManager•Quando un oggetto locale è inviato al backend per essere processato

Le operazioni di mapping sono eseguite:

Monday, May 28, 12

Page 163: iOS Api Client: soluzioni a confronto

Il protagonista principale di questo layer è RKObjectManager

“RKObjectManager è la classe che si occupa della trasformazione dei dati contenuti nel payload in oggetti”

Object Mapping

RKObjectManager

App RK

Clie

nt

Monday, May 28, 12

Page 164: iOS Api Client: soluzioni a confronto

Object MappingEsempio: caricare oggetti remoti in oggetti locali

Obiettivo: vogliamo recuperare una collection di question dal web service

Monday, May 28, 12

Page 165: iOS Api Client: soluzioni a confronto

Object MappingEsempio: caricare oggetti remoti in oggetti locali

Il web service ritorna qualcosa di simile a...{ “questions”: [{ "body" : "Che cosa si intende per scope creep?", "correctIdAnswer" : 1, "identifier" : 1},{ "body" : "Che differenza c’è tra lead e lag?", "correctIdAnswer" : 2, "identifier" : 2}]}

Monday, May 28, 12

Page 166: iOS Api Client: soluzioni a confronto

Object MappingEsempio: caricare oggetti remoti in oggetti locali

@interface Question : NSObject

@property (nonatomic, copy) NSNumber* identifier;@property (nonatomic, copy) NSString* body;@property (nonatomic, copy) NSNumber* correctIdAnswer;

@end

...lato client, questi dati sono rappresentati da una classe

Monday, May 28, 12

Page 167: iOS Api Client: soluzioni a confronto

Object Mapping

RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@"https://api.pragmamark.org/quiz"]; RKObjectMapping* questionMapping = [RKObjectMapping mappingForClass:[Question class]];[questionMapping mapKeyPath:@"identifier" toAttribute:@"identifier"];[questionMapping mapKeyPath:@"body" toAttribute:@"body"];[questionMapping mapKeyPath:@"correctIdAnswer" toAttribute:@"correctIdAnswer"]; [objectManager.mappingProvider setMapping:questionMapping forKeyPath:@"questions"];

Configuriamo RestKit Definiamo un mapping per

la classe Question

Istruiamo il mapping provider ad usare questionMapping se incontra un

@”questions” key path

Un esempio: caricare oggetti remoti in oggetti locali

Monday, May 28, 12

Page 168: iOS Api Client: soluzioni a confronto

Object MappingUn esempio: caricare oggetti remoti in oggetti locali

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@”/questions" delegate:self];

Carichiamo gli oggetti

...i dati vengono recuperati, parserizzati e assegnati agli oggetti locali- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {! NSLog(@"Loaded statuses: %@", objects); }

La classe deve implementare RKObjectLoaderDelegate

Monday, May 28, 12

Page 169: iOS Api Client: soluzioni a confronto

Object Mapping

Siamo in grado di comunicare con un

web service remoto, inviare

richieste e processare risposte

Caricare rappresentazioni di

oggetti remotinella nostra App e mapparli in oggeti

locali

Monday, May 28, 12

Page 170: iOS Api Client: soluzioni a confronto

Object Mapping

JSONXML...

payloadServer

Inviare oggetti al server

(Serialization)

Monday, May 28, 12

Page 171: iOS Api Client: soluzioni a confronto

Object Mapping

RKObjectSerializer

Local Domain Objects

IntermediateDictionary

(NSMutableDictionary)

Mapping Encoder[{ "body" : "Che cosa si intende per scope creep?",

"correctIdAnswer" : 1,

"identifier" : 1

},

{ "body" : "Che differenza c’è tra lead e lag?",

"correctIdAnswer" : 2,

"identifier" : 2

JSON(XML, URL Form Encode...)

BackendSystem

RKParser

attributi e relazioni

Serialization? Un’altra operazione di mapping.

Requ

est

Monday, May 28, 12

Page 172: iOS Api Client: soluzioni a confronto

Object Mapping Un esempio: inviare oggetti locale al server remoto

[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions" forMethod:RKRequestMethodPOST];

[[RKObjectManager sharedManager] setSerializationMIMEType:RKMIMETypeJSON];RKObjectMapping* questionSerializationMapping = [questionMapping inverseMapping];[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:questionSerializationMapping forClass:[Question class]];

Configuriamo RestKit

Lo stesso mapping definito prima è

utilizzo per serializzare la classe

Istruiamo il mapping provider ad usare

questionSerializationMapping

Monday, May 28, 12

Page 173: iOS Api Client: soluzioni a confronto

Object Mapping

// Create a new Question and POST it to the serverQuestion* question = [Question new];question.body = @"Cosa si intende per approccio agile ad un progetto?";question.identifier = [NSNumber numberWithInt: 3];

Creiamo l’oggetto

[[RKObjectManager sharedManager] postObject:question delegate:self];Inviamo la richiesta...

...recuperiamo la risposta dal server- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {! NSLog(@"Loaded statuses: %@", objects); }

RestKit sa che deve serializzare quando

esegue un POST o un PUT

Un esempio: inviare oggetti locale al server remoto

Monday, May 28, 12

Page 174: iOS Api Client: soluzioni a confronto

RoutingOvvero, dove vivono gli oggetti?

RKObjectRouter

RestKit offre un sistema di routing capace di generare resource path per un oggetto.

RKObjectRouter registra un mapping tra una classe del dominio e un resource path per uno specifico metodo HTTP.

Per interagire con un web service è necessario sapere dove gli oggetti risiedono.

RoutingSystem

/questions/123

/questions/654/questions/789

Monday, May 28, 12

Page 175: iOS Api Client: soluzioni a confronto

RoutingOvvero, dove vivono gli oggetti?

[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions" forMethod:RKRequestMethodPOST];

POST

[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions/(idpk)" forMethod:RKRequestMethodPUT];

PUT

[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions/(idpk)" forMethod:RKRequestMethodDELETE];

DELETE

GET[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions/(idpk)" forMethod:RKRequestMethodGET];

Monday, May 28, 12

Page 176: iOS Api Client: soluzioni a confronto

Routing

[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions" forMethod:RKRequestMethodPOST];

[[RKObjectManager sharedManager].router routeClass:[Question class] toResourcePath:@"/questions/(identifier)"];

Inizializziamo il nostro route...

Definiamo default route che

sarà usato per tutti gli HTTP

verbs (GET, POST, PUT e DELETE)

registriamo uno specifico

route per il verbo POST

Un esempio: inviare un oggetto al server

Monday, May 28, 12

Page 177: iOS Api Client: soluzioni a confronto

Routing

// Nel setup dell’App abbiamo già definito i mapping per questa classe Question* question = [Question new]; question.body = @"Cosa si intende per approccio agile ad un progetto?";

[[RKObjectManager sharedManager] postObject:question delegate:self];

POST

Un esempio: inviare oggetti locale al server remoto

RKObjectRouter è quindi utilizzato per generare resource path quando utilizziamo getObject, deleteObject, postObject e putObject.

“/questions”

Monday, May 28, 12

Page 178: iOS Api Client: soluzioni a confronto

Routing

Question *question = [Question new]; question.body = @"Che cosa si intende per scope creep?"; question.identifier = [NSNumber numberWithInt: 3];

[[RKObjectManager sharedManager] putObject:question delegate:self];

PUT

Un esempio: inviare oggetti locale al server remoto

RKObjectRouter è quindi utilizzato per generare resource path quando utilizziamo getObject, deleteObject, postObject e putObject.

“/questions/3”

Monday, May 28, 12

Page 179: iOS Api Client: soluzioni a confronto

Routing

Question *question = [Question new];question.identifier = [NSNumber numberWithInt: 3];

[[RKObjectManager sharedManager] deleteObject:question delegate:self];

DELETE

Un esempio: inviare oggetti locale al server remoto

RKObjectRouter è quindi utilizzato per generare resource path quando utilizziamo getObject, deleteObject, postObject e putObject.

“/questions/3”

Monday, May 28, 12

Page 180: iOS Api Client: soluzioni a confronto

Offline :|Core Data Integration

A questo punto, cosa siamo in grado di fare?

Interagire con il web service remoto

Rappresentare le risorse remote in

locale

Modificare e inviare oggetti

locali al backend

Monday, May 28, 12

Page 181: iOS Api Client: soluzioni a confronto

Offline :|Core Data Integration

Assenza di connettività?

Monday, May 28, 12

Page 182: iOS Api Client: soluzioni a confronto

Offline :)Core Data Integration

Assenza di connettività?Persistiamo i dati in locale con Core Data

Monday, May 28, 12

Page 183: iOS Api Client: soluzioni a confronto

OfflineCore Data Integration

RKManagedObjectStore RKManagedObjectMapping

RKObjectManager* objectManager = [RKObjectManager objectManagerWithBaseURL:@”http://pragmamark.org]; objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:@”Quiz.sqlite];

Setup RestKit

Vediamo come fare passo dopo passo.

Indicare lo store1

Monday, May 28, 12

Page 184: iOS Api Client: soluzioni a confronto

Mapping

Vediamo come fare passo dopo passo.

Utilizzare RKManagedObjectMapping2

Questo permette al Mapper di discriminare tra oggetti nuovi, aggiornati o

eliminati

3

OfflineCore Data Integration

RKManagedObjectMapping* questionMapping = [RKManagedObjectMapping mappingForClass:[Question class]]; questionMapping.primaryKeyAttribute = @"identifier"; [questionMapping mapKeyPath:@"identifier" toAttribute:@"identifier"];[questionMapping mapKeyPath:@"body" toAttribute:@"body"];[questionMapping mapKeyPath:@"correctIdAnswer" toAttribute:@"correctIdAnswer"]; [objectManager.mappingProvider setMapping:questionMapping forKeyPath:@"questions"];

Monday, May 28, 12

Page 185: iOS Api Client: soluzioni a confronto

OfflineCore Data Integration

Il modello persistente deve

ereditare da NSManagedObject

4

@interface Question : NSManagedObject

@property (nonatomic, copy) NSNumber* identifier;@property (nonatomic, copy) NSString* body;@property (nonatomic, copy) NSNumber* correctIdAnswer;

@end

Monday, May 28, 12

Page 186: iOS Api Client: soluzioni a confronto

@implementation Question

@synthesize identifier;@synthesize body;@synthesize correctIdAnswer;

@end

@implementation Question

@dynamic identifier;@dynamic body;@dynamic correctIdAnswer;

@end @dynamic vs @synthesize

5

OfflineCore Data Integration

Monday, May 28, 12

Page 187: iOS Api Client: soluzioni a confronto

2012-05-20 12:03:20.921 WhyMCA[1060:fb03] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot initialize an RKManagedObjectMapping without an entity. Maybe you want RKObjectMapping instead?'

Data Model Data Model resource6

OfflineCore Data Integration

Monday, May 28, 12

Page 188: iOS Api Client: soluzioni a confronto

Ora che succede?

Local Domains Objectsmapping

{questions: [

{ "body" : "Che cosa si intende per scope creep?",

"correctIdAnswer" : 1,

"identifier" : 1

},

{ "body" : "Che differenza c’è tra lead e lag?",

"correctIdAnswer" : 2,

"identifier" : 2

}]

}

JSON(XML, Form URL Encode...)

Transientobjects

Persistentobjects

OfflineCore Data Integration

Monday, May 28, 12

Page 189: iOS Api Client: soluzioni a confronto

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@”/questions" delegate:self];

Dopo aver fatto richieste al server...

...i dati sono recuperati, parserizzati e assegnati agli oggetti locali- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {! NSLog(@"Loaded questions: %@", objects); }

OfflineCore Data Integration

Un esempio: chiedere i dati al server

Monday, May 28, 12

Page 190: iOS Api Client: soluzioni a confronto

2012-05-20 12:29:00.757 WhyMCA [1499:fb03] Loaded questions: ( "<Question: 0x6b921b0> (entity: Question; id: 0x6e704e0 <x-coredata://62C52FE3-86E9-4FD0-9BA8-FAE16839477E/Question/p1> ; data: <fault>)", "<Question: 0x6b8f090> (entity: Question; id: 0x6e707a0 <x-coredata://62C52FE3-86E9-4FD0-9BA8-FAE16839477E/Question/p5> ; data: <fault>)", }

2012-05-13 16:01:03.478 WhyMCA[9935:fb03] Loaded questions: ( "<Question: 0x83a1bd0>", "<Question: 0x83a57d0>")

OfflineCore Data Integration

Un esempio: chiedere i dati al server

Monday, May 28, 12

Page 191: iOS Api Client: soluzioni a confronto

if ([[RKObjectManager sharedManager] isOnline]) { [[RKObjectManager sharedManager] loadObjectsAtResourcePath:@"/questions" delegate:self];}else { NSArray *questions = [Question allObjects];}

Impostiamo la nostra tecnica

Alternative?

•Implementare di RKManagedObjectCache protocol•Utilizzare RKRequestCache •Database seeding

Un esempio: chiedere i dati al server

OfflineCore Data Integration

Monday, May 28, 12

Page 192: iOS Api Client: soluzioni a confronto

In practiceRestKit Mapping & CoreData

“Non sempre le risposte del web service sono come ce le aspettiamo”(Anonimo)

Team Mobile Team Server-side

Monday, May 28, 12

Page 193: iOS Api Client: soluzioni a confronto

•Aggiungiamo l’entità Answer

•Question e Answer sono in relazione molti a molti

•L’identificativo di Question è in un oggetto nidificato

•Nell’elenco delle question manca la key Path @”questions”

Elaboriamo un pò il nostro model

In practiceRestKit Mapping & CoreData

Monday, May 28, 12

Page 194: iOS Api Client: soluzioni a confronto

RestKit Mapping & CoreDataIn practice

{ “questions”: [ { "identifier" : 1 "body" : "Che cosa si intende per scope creep?", "correctIdAnswer" : 1, }, { "identifier" : 2 "body" : "Che differenza c’è tra lead e lag?", "correctIdAnswer" : 2, }]}

{ [ {"_id": {        "$identifier": "4faf69fee4b0895a3ed9b1ff"    },    "correctIdAnswer": 1,    "body": "Quale è il significato del termine lead?",    "answers": [        {            "identifier": "3",            "body": "risposta B"        },        {            "identifier": "1",            "body": "risposta A"        }    ] }, {...

Dove è la key @“questions” ?Come identifichiamo il contenuto?

Monday, May 28, 12

Page 195: iOS Api Client: soluzioni a confronto

@interface Answer : NSManagedObject

@property (nonatomic, copy) NSString* identifier;@property (nonatomic, copy) NSString* body;@property (nonatomic, retain) NSSet* questions;

@end

In practiceRestKit Mapping & CoreData

@interface Question : NSManagedObject

@property (nonatomic, copy) NSString* identifier;@property (nonatomic, copy) NSString* body;@property (nonatomic, copy) NSNumber* correctIdAnswer;@property (nonatomic, retain) NSSet* answers;

@end

Monday, May 28, 12

Page 196: iOS Api Client: soluzioni a confronto

In practiceRestKit Mapping & CoreData

//MappingRKManagedObjectMapping* questionMapping = [RKManagedObjectMapping mappingForClass:[Question class]];questionMapping.primaryKeyAttribute = @"identifier";[questionMapping mapKeyPath:@"_id.$identifier" toAttribute:@"identifier"];[questionMapping mapKeyPath:@"body" toAttribute:@"body"];[questionMapping mapKeyPath:@"correctIdAnswer" toAttribute:@"correctIdAnswer"];

RKManagedObjectMapping* answerMapping = [RKManagedObjectMapping mappingForClass:[Answer class]]; [answerMapping setPrimaryKeyAttribute:@"identifier"];[answerMapping mapKeyPath:@"identifier" toAttribute:@"identifier"];[answerMapping mapKeyPath:@"body" toAttribute:@"body"];

[questionMapping mapKeyPath:@"answers" toRelationship:@"answers" withMapping:answerMapping];[objectManager.mappingProvider addObjectMapping:questionMapping];

Monday, May 28, 12

Page 197: iOS Api Client: soluzioni a confronto

In practiceRestKit Mapping & CoreData

Effettuiamo la richiesta al server...RKObjectMapping *questionMapping = [[RKObjectManager sharedManager].mappingProvider objectMappingForClass:[Question class]];

[[RKObjectManager sharedManager] loadObjectsAtResourcePath:@”/questions" objectMapping:questionMapping delegate:self];

Monday, May 28, 12

Page 198: iOS Api Client: soluzioni a confronto

[[RKObjectManager sharedManager] postObject:question delegate:self block:^(RKObjectLoader* loader) { loader.objectMapping = [RKObjectMapping mappingForClass:[Question class] block:^(RKObjectMapping* mapping) { [mapping mapAttributes:@"identifier", @"body", nil]; }]; }];

In practiceRestKit Mapping & CoreData

Possiamo costruire un mapping dinamicamente...

Monday, May 28, 12

Page 199: iOS Api Client: soluzioni a confronto

Le codeInviare richieste e processare risposte: i retroscena.

RKResponse

RKClient

RKRequest

Payload

Monday, May 28, 12

Page 200: iOS Api Client: soluzioni a confronto

Le codeInviare richieste e processare risposte: i retroscena.

RKResponse

RKClient

RKRequest

Payload

RKRequestQueue

Monday, May 28, 12

Page 201: iOS Api Client: soluzioni a confronto

//[[RKClient sharedClient].requestQueue addRequest:loader];

Cosa succede quando inviamo una richiesta con RKRequest?[RKClient sharedClient].requestQueue

[[RKClient sharedClient].requestQueue cancelRequestsWithDelegate:delegate];

•rilevare connettività•limitare le richieste concorrenti•eliminare richieste per un determinato delegato

RKRequestQueue è utilizzato anche per:

Le codeInviare richieste e processare risposte: i retroscena.

Monday, May 28, 12

Page 202: iOS Api Client: soluzioni a confronto

Possiamo usarle per:

•Effettuare il download di un’entità “complessa”. Ad esempio: ipotizziamo una Guida, entità del dominio, rappresentata da un grafo di oggetti contenente le sue proprietà e le sue relazioni ma che fa riferimento a diversi asset (audio, fotografie, tiles per le mappa offline) attraverso percorsi esterni.

•Raggruppare le chiamate per la paginazione, per la ricerca, per il workflow di acquisto, etc.. e utilizzare la sharedQueue per soddisfare la user action.

Le codeInviare richieste e processare risposte: i retroscena.

Monday, May 28, 12

Page 203: iOS Api Client: soluzioni a confronto

Le codeInviare richieste e processare risposte: i retroscena.

RKRequestQueue *queue = [RKRequestQueue requestQueueWithName:nameQueue];

queue.concurrentRequestsLimit = 5;

Creare una coda...

Monday, May 28, 12

Page 204: iOS Api Client: soluzioni a confronto

Le codeInviare richieste e processare risposte: i retroscena.

NSString *resourcePath = [NSString stringWithFormat:@"%@%@/%i",kAPIAddress,kAPI_AUDIO_GET,[identifier intValue]]; RKRequest *request = [RKRequest requestWithURL:[NSURL URLWithString:resourcePath] delegate:self];request.authenticationType = RKRequestAuthenticationTypeHTTPBasic;request.username = [RKClient sharedClient].username;request.password = [RKClient sharedClient].password; [queue addRequest:request][queue start];

Aggiungere richieste...

Monday, May 28, 12

Page 205: iOS Api Client: soluzioni a confronto

Le codeInviare richieste e processare risposte: i retroscena.

//verifica prima se esiste la queueBOOL existsQueue = [RKRequestQueue requestQueueExistsWithName:nameQueue]; if (existsQueue) { RKRequestQueue *queue = [RKRequestQueue requestQueueWithName:nameQueue]; NSLog(@"Elimino richieste in coda %i",[queue count]); [queue cancelAllRequests]; NSLog(@"Richieste in coda %i",[queue count]);}

Svuotare la coda...

Monday, May 28, 12

Page 206: iOS Api Client: soluzioni a confronto

Conclusionie quindi?

Monday, May 28, 12

Page 207: iOS Api Client: soluzioni a confronto

“Buon senso”

Monday, May 28, 12


Top Related