Slide 1

Slide 1 text

iAsync Functional Programming in Objective-C Alexander Dodatko 2013

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Over 900,000 apps (as of June 2013)

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

NSData* jsonData = nil; jsonData = [ NSData dataWithContentsOfURL: RESOURSE ];

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Asynchronous Programming

Slide 11

Slide 11 text

@protocol NSURLConnectionDataDelegate @optional - (void)connection: didReceiveResponse: - (void)connection: didReceiveData: - (void)connectionDidFinishLoading: - (void)connection: didFailWithError: @end

Slide 12

Slide 12 text

Too Much Code

Slide 13

Slide 13 text

Objectice-C Blocks

Slide 14

Slide 14 text

NS_AVAILABLE(10_7, 5_0); + (void)sendAsynchronousRequest: queue: completionHandler:

Slide 15

Slide 15 text

void (^HANDLER_BLOCK)( NSURLResponse* response, NSData* data, NSError* connectionError)

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Progress Cancel

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

NSURL *url = [NSURL URLWithString:@"https://...."]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; id onSuccess = ^(NSURLRequest *, NSHTTPURLResponse *, id JSON) { NSLog( @"App.net Global Stream: %@", JSON ); }; AFJSONRequestOperation *operation = [ AFJSONRequestOperation JSONRequestOperationWithRequest: request success: onSuccess failure: nil ]; [ operation start ];

Slide 20

Slide 20 text

Dependencies

Slide 21

Slide 21 text

When using methods which return blocks they can be very convenient. However, when you have to string a few of them together it gets messy really quickly

Slide 22

Slide 22 text

[remoteAPIWithURL:url1 success:^(int status){ [remoteAPIWithURL:url2 success:^(int status){ [remoteAPIWithURL:url3 success:^(int status){ [remoteAPIWithURL:url2 success:^(int status){ //success!!! }]; }]; }]; }];

Slide 23

Slide 23 text

It was not uncommon when using AFNetworking in Gowalla to have calls chained together in success blocks. My advice would be to factor the network requests and serializations as best you can into class methods in your model. Then, for requests that need to make sub-requets, you can call those methods in the success block.

Slide 24

Slide 24 text

Callback Hell

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

AFURLConnectionOperation

Slide 27

Slide 27 text

Working with independent data sets in parallel and then combining them into a final result is non-trivial in Cocoa, and often involves a lot of synchronization

Slide 28

Slide 28 text

__block NSArray *databaseObjects, fileContents; NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init]; NSBlockOperation *databaseOperation = [NSBlockOperation blockOperationWithBlock:^{ databaseObjects = [databaseClient fetchObjectsMatchingPredicate:predicate]; }]; NSBlockOperation *filesOperation = [NSBlockOperation blockOperationWithBlock:^{ NSMutableArray *filesInProgress = [NSMutableArray array]; for (NSString *path in files) { [filesInProgress addObject:[NSData dataWithContentsOfFile:path]]; } fileContents = [filesInProgress copy]; }]; NSBlockOperation *finishOperation = [NSBlockOperation blockOperationWithBlock:^{ [self finishProcessingDatabaseObjects:databaseObjects fileContents:fileContents]; NSLog(@"Done processing"); }]; [finishOperation addDependency:databaseOperation]; [finishOperation addDependency:filesOperation]; [backgroundQueue addOperation:databaseOperation]; [backgroundQueue addOperation:filesOperation]; [backgroundQueue addOperation:finishOperation];

Slide 29

Slide 29 text

Rather than using mutable variables which are replaced and modified in-place, RAC provides signals (represented by RACSignal) that capture present and future values.

Slide 30

Slide 30 text

When Design Patterns are NOT enough

Slide 31

Slide 31 text

Meet the Async Operation CancelBlock (^AsyncOperation) ( ProgressCallback, CancelCallback, CompletionCallback ) {...};

Slide 32

Slide 32 text

Sequence JFFAsyncOperation sequence = sequenceOfAsyncOperations( @[ op1, op2, opN ] );

Slide 33

Slide 33 text

Sequence of Attempts JFFAsyncOperation sequence = trySequenceOfAsyncOperations( @[ op1, op2, opN ] );

Slide 34

Slide 34 text

Parallel execution JFFAsyncOperation sequence = groupOfAsyncOperations( @[ op1, op2, opN ] ); CompletionCallback

Slide 35

Slide 35 text

Waterfall JFFAsyncOperation sequence = bindSequenceOfAsyncOperations( op1, @[ b1, b2, bN ] );

Slide 36

Slide 36 text

Function = Command + Composite

Slide 37

Slide 37 text

Any Complexity Tasks

Slide 38

Slide 38 text

loadFromNet = sequenceOfAsyncOperations( @[ login, loadFromNet ] ); loadRawData = trySequenceOfAsyncOperations( @[ loadFromFSCache, loadFromNet ] ); JFFAsyncOperation getData = bindSequenceOfAsyncOperations( loadRawData, @[ parseBinder, filterBinder ] );

Slide 39

Slide 39 text

iAsync bit.ly/1bLdN59

Slide 40

Slide 40 text

Does anyone use it?

Slide 41

Slide 41 text

Wishdates

Slide 42

Slide 42 text

Sitecore

Slide 43

Slide 43 text

Pitfalls Large codebase No PodSpec No Documentation No Community No Versioning policy

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

Vladimir Gorbenko [email protected] Vova.Gorbenko.mac github.com/volodg iAsync Author

Slide 46

Slide 46 text

Oleksandr Dodatko [email protected] alexander.dodatko.work @dodikk88 github.com/dodikk

Slide 47

Slide 47 text

No content