concurrent networking - made easy

Post on 06-May-2015

2.238 Views

Category:

Technology

3 Downloads

Preview:

Click to see full reader

DESCRIPTION

A short presentation we held at the Stockholm CocoaHeads meeting March 5th 2012 on concurrent networking in iOS.

TRANSCRIPT

CONCURRENT NETWORKING – MADE EASY!

CocoaHeads Stockholm, March 5 2012MARTHIN FREIJ / AMAZING APPLICATIONS

A two-man army of digital production veterans, on a crusade to delight people with pixel perfect design, delicate code and stunning user experiences.

We work hard to ensure that everything from concept and user interaction design to animations and technical implementation is as sleek as possible.

AMAZING APPLICATIONS / IN SHORT

A tech savvy pixel pusher and design geek with over 15 years of experience working with global brands in digital channels. Also a confused father and a avid gamer.

CLIENT SHORT LIST: Vin & Sprit (Absolut Vodka & Malibu Rum), IKEA, Scania, Electrolux, Nokia, SCA (Libresse)

JIMMY POOPUU / ART DIRECTOR

Has written million lines of code as a software developer and held countless lectures as technical trainer during the past 10 years for clients in the bank, finance and media sector.

CLIENT SHORT LIST: ICA Banken, Handelsbanken, Bonnier, Dagens Nyheter, Dagens Industri

MARTHIN FREIJ / SENIOR DEVELOPER

CONCURRENT NETWORKING – MADE EASY!

CocoaHeads Stockholm, March 5 2012MARTHIN FREIJ / AMAZING APPLICATIONS

MADE EASY?IS IT HARD IN THE FIRST PLACE?

APPLE PROVIDE SIMPLE API’S FOR NETWORKING

NSURLConnectionNSURLRequestNSURLResponse

FEW DEVELOPERS USE THEM

;(

BECAUSE THEY REQUIRE A LOT OF BOILERPLATE CODE

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;

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

AND MAYBE YOU WANT TO DO MORE THAN ONE REQUEST

AT THE TIME?

THEN YOU NEED TO KEEP TRACK

OF YOUR REQUESTS AND CONNECTIONS

WE TEND TO USE BOILERPLATE CODE WRITTEN BY SOMEONE ELSE

LIKE NETWORK LIBRARIES

ASIHTTPREQUEST

DOH! DISCONTINUED!

AFNETWORKING

BUGS!RACE CONDITIONS!MEMORY LEAKS!

!

IT TURNS OUT TO BE KIND OF HARD

NEW STUFF IN iOS 5

+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*)) handler;

NSURLRequestNSOperationQueueCompletion Handler

☞☞☞

// Create the requestNSURL *url = [NSURL URLWithString:@"https://the.api.com/method/"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

// Create the queueNSOperationQueue *queue = [[NSOperationQueue alloc] init];queue.name = @"com.your.unique.queue.name";

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // If there was an error getting the data if (error) { dispatch_async(dispatch_get_main_queue(), ^(void) { // Display error message in UI }); return; } // Do stuff with the data dispatch_async(dispatch_get_main_queue(), ^(void) { // Update UI });}];

ONE MORE THING...

CORE DATA AND CONCURRENCY HAVEN’T ALWAYS BEEN BEST BUDDIES

UNTIL NOW IN iOS 5

- (id)initWithConcurrencyType:(NSManagedObjectContextConcurrencyType)ct;- (void)setParentContext:(NSManagedObjectContext*)parent;- (void)performBlock:(void (^)())block;

NSManagedObjectContext

Set your main context to execute on Main Queue(NSMainQueueConcurrencyType)

☞IMPORT DATA EXAMPLE (1 / 2)

Create an import context and tell Core Data to create a new queue for it (NSPrivateQueueConcurrencyType)

☞Set the main context as the import contexts parentContext☞

On the import context, call performBlock and do the import (i.e. download data, validate it, import it, purge old data etc)

☞IMPORT DATA EXAMPLE (2 / 2)

Save changes on the import context. This will stage it up one level (to the main context)

☞Save changes on the main context. This will persist it on the associated persistent store (and update NSFetchedResultControllers etc)

// Setup the main context (probably in the AppDelegate)[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

NSManagedObjectContext *importContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

importContext.parentContext = self.managedObjectContext;

[importContext performBlock:^{

// Download data, import etc..

NSError *importError = nil; [importContext save:&importError];

[importContext.parentContext performBlock:^{ NSError *parentError = nil; [importContext.parentContext save:&parentError]; }];}];

THATS IT, THANKS FOR YOUR TIME!

www.amazing-apps.se

top related