mobile in the cloud with diamonds. improved.

33
MOBILE IN THE CLOUD WITH DIAMONDS 2013 2013

description

Software development evolution is here. We gotta open source. We making better blocks. In this presentation I show you some iOS related techniques for automatic data synchronisation. And overall - tools for rapid development and testing your software.

Transcript of mobile in the cloud with diamonds. improved.

Page 1: mobile in the cloud with diamonds. improved.

MOBILE IN THE CLOUD WITH DIAMONDS

20132013

Page 2: mobile in the cloud with diamonds. improved.
Page 3: mobile in the cloud with diamonds. improved.

Cont

ent

Mobile & Cloud

Bicycles we ride

Essential frameworks

Advanced frameworks

Wondertools

You don't test me

Backends

Imagination

Page 4: mobile in the cloud with diamonds. improved.

mobile and the internetsm

Page 5: mobile in the cloud with diamonds. improved.

VS

FRAMEWORKS

★ faster ★ know how ★ solves the problem

★ tested ★ independent ★ supported

Developer’s dilemma

Page 6: mobile in the cloud with diamonds. improved.

FRAMEWORKS

RESTawful services

That could be a pain

Page 7: mobile in the cloud with diamonds. improved.

Core Data

Data and Cloud

Page 8: mobile in the cloud with diamonds. improved.

Core Data

Data and Cloud

NSOperation

Page 9: mobile in the cloud with diamonds. improved.

Core Data

Data and Cloud

NSOperation

NSURLConnection

Page 10: mobile in the cloud with diamonds. improved.

Core Data

Data and Cloud

NSOperationNSURLConnection

AFNetworking

NSURL *url = [NSURL URLWithString:@"https://alpha-api.app.net/stream/0/posts/stream/global"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {! NSLog(@"App.net Global Stream: %@", JSON);!} failure:nil];![operation start];

Page 11: mobile in the cloud with diamonds. improved.

Core Data

Data and Cloud

NSOperationNSURLConnection

AFNetworking

KIT

REST

Page 12: mobile in the cloud with diamonds. improved.

NSOperationNSURLConnection Core Data

Data and Cloud

AFNetworking KIT

REST

Page 13: mobile in the cloud with diamonds. improved.

NSURLConnection

AFNetworking

NSOperation Core Data

KIT

REST Data Mapping

Data and Cloud - RestKit

Page 14: mobile in the cloud with diamonds. improved.

RestKit example@interface RKTweet : NSObject!@property (nonatomic, copy) NSNumber *userID;!@property (nonatomic, copy) NSString *username;!@property (nonatomic, copy) NSString *text;!@end!!RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];![mapping addAttributeMappingsFromDictionary:@{! @"user.name": @"username",! @"user.id": @"userID",! @"text": @"text"!}];!RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];!NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];! [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {! NSLog(@"The public timeline Tweets: %@", [result array]);!} failure:nil];![operation start];

@interface RKTweet : NSObject!@property (nonatomic, copy) NSNumber *userID;!@property (nonatomic, copy) NSString *username;!@property (nonatomic, copy) NSString *text;!@end!

Page 15: mobile in the cloud with diamonds. improved.

RestKit example@interface RKTweet : NSObject!@property (nonatomic, copy) NSNumber *userID;!@property (nonatomic, copy) NSString *username;!@property (nonatomic, copy) NSString *text;!@end!!RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];![mapping addAttributeMappingsFromDictionary:@{! @"user.name": @"username",! @"user.id": @"userID",! @"text": @"text"!}];!!RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];!!NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];! ![operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {! NSLog(@"The public timeline Tweets: %@", [result array]);!} failure:nil];![operation start];

RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];![mapping addAttributeMappingsFromDictionary:@{! @"user.name": @"username",! @"user.id": @"userID",! @"text": @"text"!}];

Page 16: mobile in the cloud with diamonds. improved.

RestKit example@interface RKTweet : NSObject!@property (nonatomic, copy) NSNumber *userID;!@property (nonatomic, copy) NSString *username;!@property (nonatomic, copy) NSString *text;!@end!RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];![mapping addAttributeMappingsFromDictionary:@{! @"user.name": @"username",! @"user.id": @"userID",! @"text": @"text"!}];!RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];!NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];! [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {! NSLog(@"The public timeline Tweets: %@", [result array]);!} failure:nil];![operation start];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];!NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];

Page 17: mobile in the cloud with diamonds. improved.

RestKit example@interface RKTweet : NSObject!@property (nonatomic, copy) NSNumber *userID;!@property (nonatomic, copy) NSString *username;!@property (nonatomic, copy) NSString *text;!@end!RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];![mapping addAttributeMappingsFromDictionary:@{! @"user.name": @"username",! @"user.id": @"userID",! @"text": @"text"!}];!RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];!NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];![operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {! NSLog(@"The public timeline Tweets: %@", [result array]);!} failure:nil];![operation start];

[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {! NSLog(@"The public timeline Tweets: %@", [result array]);!} failure:nil];![operation start];

Page 18: mobile in the cloud with diamonds. improved.

RestKit example@interface RKTweet : NSObject!@property (nonatomic, copy) NSNumber *userID;!@property (nonatomic, copy) NSString *username;!@property (nonatomic, copy) NSString *text;!@end!RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[RKTweet class]];![mapping addAttributeMappingsFromDictionary:@{! @"user.name": @"username",! @"user.id": @"userID",! @"text": @"text"!}];!RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping pathPattern:nil keyPath:nil statusCodes:nil];!NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/public_timeline.json"];!NSURLRequest *request = [NSURLRequest requestWithURL:url];!RKObjectRequestOperation *operation = [[RKObjectRequestOperation alloc] initWithRequest:request responseDescriptors:@[responseDescriptor]];![operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {! NSLog(@"The public timeline Tweets: %@", [result array]);!} failure:nil];![operation start];

Page 19: mobile in the cloud with diamonds. improved.

Next Step

NSURLConnection NSOperation Core Data

NSIncrementalStore

Page 20: mobile in the cloud with diamonds. improved.

Next Step

NSURLConnection NSOperation Core Data

NSIncrementalStore

AFNetworking

Page 21: mobile in the cloud with diamonds. improved.

Next Step

NSURLConnection NSOperation Core Data

NSIncrementalStoreAFNetworking

Page 22: mobile in the cloud with diamonds. improved.

NSURLConnection

AFNetworking

NSOperation

NSIncrementalStore

Core Data

AFIncrementalStore

Next Step - Data Sync

Page 23: mobile in the cloud with diamonds. improved.

a snap into AFIncrementalStore

YOUR CODE

CoreData framework

YOUR CODE

CoreData framework

+ AF

Incremental Store

AFNetworking

RESTful server

unusualusual

CoreData framework

Page 24: mobile in the cloud with diamonds. improved.

working with AFIncrementalStore is the same as with CoreData

@interface TasksViewController()<NSFetchedResultsControllerDelegate>!@property NSFetchedResultsController *fetchedResultsController;!@end!!- (UITableViewCell *)tableView:(UITableView *)tableView! cellForRowAtIndexPath:(NSIndexPath *)indexPath !{!

...! [self configureCell:cell forRowAtIndexPath:indexPath];! return cell;!}!!- (void)configureCell:(UITableViewCell *)cell ! forRowAtIndexPath:(NSIndexPath *)indexPath !{! NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];! cell.textLabel.text = [managedObject valueForKey:@"text"];!

Page 25: mobile in the cloud with diamonds. improved.

AFIncrementalStore

?

Business Logic

?

?

Page 26: mobile in the cloud with diamonds. improved.

⦿Push Notifications ⦿InAppPurchase

⦿ Analytics ⦿ Passbook ⦿ Newsstand

Sync.

#  helios  server

with just one command...*

Page 27: mobile in the cloud with diamonds. improved.

Helios-ready iOS frameworks

AFIncrementalStore Core Data Persistence with AFNetworking, Done Right

AFNetworking A Delightful iOS & OS X Networking Framework

Antenna Extensible Remote Logging

SkyLab Multivariate & A/B Testing

Orbiter Push Notification Registration

Cargo Bay The Essential StoreKit Companion

Ground Control Remote Configuration

Page 28: mobile in the cloud with diamonds. improved.

Cocoa Pods$ [sudo] gem install cocoapods $ pod setup myproject$ pod install

http://cocoapods.org

Podfile example: platform :ios, '7.0' pod 'AFNetworking', '~> 2.0.3’ pod 'ICViewPager', '~> 1.5’ RestKit

AFNetworking AFIncrementalStore

AFAmazonS3Client ...

https://github.com/CocoaPods/Specs

Page 29: mobile in the cloud with diamonds. improved.

Testing★ many frameworks comes with tests, bros

KIF

https://github.com/kif-framework/KIF

FRANK

https://github.com/moredip/Frank

Page 30: mobile in the cloud with diamonds. improved.

KIF★ leveraging the accessibility attributes ★ conducted synchronously in the main thread ★ uses undocumented Apple APIs

- (void)testSuccessfulLogin!{! [tester enterText:@"[email protected]" intoViewWithAccessibilityLabel:@"Login User Name"];! [tester enterText:@"thisismypassword" intoViewWithAccessibilityLabel:@"Login Password"];! [tester tapViewWithAccessibilityLabel:@"Log In"];!! // Verify that the login succeeded! [tester waitForTappableViewWithAccessibilityLabel:@"Welcome"];!}

Page 31: mobile in the cloud with diamonds. improved.

FRANK★ from outer ruby space ‘cucumber’ ★ 'Selenium for native iOS apps'. ★ uses undocumented Apple APIs ★ totally different approach to testing in iOS

Feature: Various scenarios that exercise different parts of Frank!!Background:! Given I launch the app !!Scenario: Counting number of rows in a table section! Then I should see 3 rows in section 0!!Scenario: Scrolling to the bottom of the table ! When I touch "Larry Stooge"! And I touch "User Roles"! Then I should not see "Returns"! When I scroll to the bottom of the table! Then I should see "Returns"

Page 32: mobile in the cloud with diamonds. improved.

READY TO USE CLOUDS★Deployd.com

- free to use - javascript based

★★Parse.com -all essential platforms supported -“out of the box” basic data entities -free to test

★★★APIgee.com (books & webcasts) - developer console to popular services - intermediate data processing (eg.

convert xml to json, mapping, etc) - free to test

Page 33: mobile in the cloud with diamonds. improved.

[email protected]@gelosi - http://obrij.com

AFNetworking, AFIncrementalStore, AF*** https://github.com/helios-framework/helios

RESTKit - https://github.com/RestKit/RestKit

Follow: @mattt, @soffes, @gruber, @edog1203

CocoaPods - http://cocoapods.org