SlideShare une entreprise Scribd logo
1  sur  33
Télécharger pour lire hors ligne
Working With
AFNetworking
@waynehartman
Before AFNetworking
• NSURLConnection (meh)
• NSData (BARF!)
• CFNetwork (medic!)
NSURLConnection - (IBAction)didSelectRefreshButton:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://ip.jsontest.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
!
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
!
#pragma mark - NSURLConnection
!
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
_data = nil;
!
switch (response.statusCode) {
case 200: {
self.data = [NSMutableData dataWithCapacity:(NSUInteger)response.expectedContentLength];
}
break;
default: {
[connection cancel];
!
NSError *error = [NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork
code:response.statusCode
userInfo:@{(NSString *)kCFErrorDescriptionKey : (NSString *)kCFURLErrorFailingURLErrorKey}];
[self connection:connection didFailWithError:error];
}
break;
}
}
!
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.data appendData:data];
}
!
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:&error];
if (!jsonData) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"The data was corrupt. Sorry"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
} else {
NSString *ip = jsonData[@"ip"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!"
message:[NSString stringWithFormat:@"Your IP is: %@", ip]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
!
self.connection = nil;
}
!
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"There was an error getting the data. Please try again later."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
self.connection = nil;
}
• All this code, just to download
and display this:
{"ip": "72.191.49.142"}
NSData
• One line of code!
!
dataWithContentsOfURL:
!
NEVER USE THIS API!
CFNetwork NSURL *url = [NSURL URLWithString:DOWNLOAD_URL];
!
CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CFSTR("GET"), (__bridge CFURLRef)url, kCFHTTPVersion1_1);
!
CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, request);
CFReadStreamOpen(requestStream);
NSMutableData *responseBytes = [NSMutableData data];
CFIndex numBytesRead = 0 ;
NSUInteger totalBytesRead = 0;
!
do {
UInt8 buf[1024];
numBytesRead = CFReadStreamRead(requestStream, buf, sizeof(buf));
if(numBytesRead > 0) {
[responseBytes appendBytes:buf length:numBytesRead];
totalBytesRead += numBytesRead;
}
} while(numBytesRead > 0);
if (totalBytesRead > 0) {
CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader);
CFHTTPMessageSetBody(response, (__bridge CFDataRef)responseBytes);
CFReadStreamClose(requestStream);
CFDataRef responseBodyData = CFHTTPMessageCopyBody(response);
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:(__bridge NSData *)responseBodyData options:0 error:&error];
CFRelease(responseBodyData);
CFRelease(response);
if (!jsonData) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"The data was corrupt. Sorry"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
} else {
NSString *ip = jsonData[@"ip"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!"
message:[NSString stringWithFormat:@"Your IP is: %@", ip]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"There was an error getting the data. Please try again later."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
!
CFRelease(requestStream);
CFRelease(request);
• All this code, just to download
and display this:
{"ip": "72.191.49.142"}
• Plus we have to write gross C
with nasty CFRelease()
AFNetworking
“AFNetworking is a delightful networking library for iOS and Mac OS
X. It's built on top of the Foundation URL Loading System, extending
the powerful high-level networking abstractions built into Cocoa. It
has a modular architecture with well-designed, feature-rich APIs that
are a joy to use.”
AFNetworking
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:DOWNLOAD_URL]];
!
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setResponseSerializer:[AFJSONResponseSerializer serializer]];
[operation setCompletionBlockWithSuccess:successHandler failure:failureHandler];
!
[operation start];
AFNetworking
void(^failureHandler)(AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"There was an error getting the data. Please try again later."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
};
AFNetworking
void(^successHandler)(AFHTTPRequestOperation *, id) = ^(AFHTTPRequestOperation *operation, id responseObject) {
if (!responseObject) {
failureHandler(operation, [NSError errorWithDomain:AFNetworkingErrorDomain code:404 userInfo:nil]);
} else {
NSString *ip = responseObject[@"ip"];
!
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!"
message:[NSString stringWithFormat:@"Your IP is: %@", ip]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
};
void(^failureHandler)(AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"There was an error getting the data. Please try again later."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
};
void(^successHandler)(AFHTTPRequestOperation *, id) = ^(AFHTTPRequestOperation *operation, id responseObject) {
if (!responseObject) {
failureHandler(operation, [NSError errorWithDomain:AFNetworkingErrorDomain code:404 userInfo:nil]);
} else {
NSString *ip = responseObject[@"ip"];
!
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!"
message:[NSString stringWithFormat:@"Your IP is: %@", ip]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
};
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:DOWNLOAD_URL]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setResponseSerializer:[AFJSONResponseSerializer serializer]];
[operation setCompletionBlockWithSuccess:successHandler failure:failureHandler];
!
[operation start];
- (IBAction)didSelectRefreshButton:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://ip.jsontest.com/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
!
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
}
!
#pragma mark - NSURLConnection
!
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
_data = nil;
!
switch (response.statusCode) {
case 200: {
self.data = [NSMutableData dataWithCapacity:(NSUInteger)response.expectedContentLength];
}
break;
default: {
[connection cancel];
!
NSError *error = [NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork
code:response.statusCode
userInfo:@{(NSString *)kCFErrorDescriptionKey : (NSString *)kCFURLErrorFailingURLErrorKey}];
[self connection:connection didFailWithError:error];
}
break;
}
}
!
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.data appendData:data];
}
!
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:&error];
if (!jsonData) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"The data was corrupt. Sorry"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
} else {
NSString *ip = jsonData[@"ip"];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!"
message:[NSString stringWithFormat:@"Your IP is: %@", ip]
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
}
!
self.connection = nil;
}
!
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"There was an error getting the data. Please try again later."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
self.connection = nil;
}
Key Concepts
• AF*Operation are subclasses of NSOperation
• Networking operations can be started individually or placed in an
NSOperationQueue
• Custom serialization classes can be created for transforming and
validating data.
Demo: Using Queues
AFURLResponseSerializer
• If you don’t specify a request/response serializer, it will give back
NSData.
• Serializers can be created to handle data transformation and
validation.
AFURLResponseSerializer
AFJSONResponseSerializer
AFPropertyListResponseSerializer
AFImageResponseSerializer
AFCompoundResponseSerializer
AFXMLParserResponseSerializer
!
AFXMLDocumentResponseSerializer
Custom Serializer
• Subclass AFHTTPResponseSerializer
• Override
• responseObjectForResponse:data:error:
• acceptableContentTypes
Custom Serializer
• We’re going to create a serializer for decoding 1337593@k
Anyone know the Content-Type for
1337 encoded data?
@99l1c@710n/l337
D3m0: Cu570m R3590n53
53r1@l1z@710n
AFNetworking + UIKit
• AFNetworking adds a number of extensions to common UIKit
classes:
• UIImageView
• UIButton
• UIWebView
• UIProgressView
• UIRefreshControl
Demo: UIKit Extensions
Design Patterns for
Network & Data
“At its heart, programming is all
about abstraction.”
Justin Spahr-Summers
CocoaConf Austin 2014
Classes should have as few purposes as possible (say, one)
and do it very well.
!
Classes should know as little as possible about other classes.
Are your View Controllers like this?
Case Study:
Geekdom for iOS
Monster View Controller
• UITableView Datasource
• Configure Cells
• UITableView Delegate
• Showing Member Details
• NSFetchedResultsControllerDelegate
• Fetch All Member data
• Fetch Checked-In Members
• Fetch Profile Images
• Search Members By Name
• Search Members By Skills
• Data Persistance
• Check-In logic
• Checked-In vs All Members
Questions?
@waynehartman

Contenu connexe

Tendances

Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
Mauro Rocco
 

Tendances (20)

Django Celery - A distributed task queue
Django Celery - A distributed task queueDjango Celery - A distributed task queue
Django Celery - A distributed task queue
 
An Introduction to Celery
An Introduction to CeleryAn Introduction to Celery
An Introduction to Celery
 
Effective iOS Network Programming Techniques
Effective iOS Network Programming TechniquesEffective iOS Network Programming Techniques
Effective iOS Network Programming Techniques
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
 
Europython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & CeleryEuropython 2011 - Playing tasks with Django & Celery
Europython 2011 - Playing tasks with Django & Celery
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
MySQL in Go - Golang NE July 2015
MySQL in Go - Golang NE July 2015MySQL in Go - Golang NE July 2015
MySQL in Go - Golang NE July 2015
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
 
Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Webエンジニアから見たiOS5
Webエンジニアから見たiOS5
 
Practical JavaScript Promises
Practical JavaScript PromisesPractical JavaScript Promises
Practical JavaScript Promises
 
Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet Protractor Training in Pune by QuickITDotnet
Protractor Training in Pune by QuickITDotnet
 
HTML5 JavaScript APIs
HTML5 JavaScript APIsHTML5 JavaScript APIs
HTML5 JavaScript APIs
 
Practical Celery
Practical CeleryPractical Celery
Practical Celery
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
 
Tools for Solving Performance Issues
Tools for Solving Performance IssuesTools for Solving Performance Issues
Tools for Solving Performance Issues
 
Nevermore Unit Testing
Nevermore Unit TestingNevermore Unit Testing
Nevermore Unit Testing
 
Real time server
Real time serverReal time server
Real time server
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScript
 

Similaire à Working with AFNetworking

Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
Whymca
 
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Sarp Erdag
 
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docxWeb CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
celenarouzie
 

Similaire à Working with AFNetworking (20)

Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applications
 
Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
 
정오의 데이트 for iOS 코드 정리
정오의 데이트 for iOS 코드 정리정오의 데이트 for iOS 코드 정리
정오의 데이트 for iOS 코드 정리
 
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
Hızlı Cocoa Geliştirme (Develop your next cocoa app faster!)
 
Formacion en movilidad: Conceptos de desarrollo en iOS (III)
Formacion en movilidad: Conceptos de desarrollo en iOS (III) Formacion en movilidad: Conceptos de desarrollo en iOS (III)
Formacion en movilidad: Conceptos de desarrollo en iOS (III)
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
 
CakePHP in iPhone App
CakePHP in iPhone AppCakePHP in iPhone App
CakePHP in iPhone App
 
Parse: 5 tricks that won YC Hacks
Parse: 5 tricks that won YC HacksParse: 5 tricks that won YC Hacks
Parse: 5 tricks that won YC Hacks
 
UIWebView Tips
UIWebView TipsUIWebView Tips
UIWebView Tips
 
Unit Testing: Special Cases
Unit Testing: Special CasesUnit Testing: Special Cases
Unit Testing: Special Cases
 
iPhone project - Wireless networks seminar
iPhone project - Wireless networks seminariPhone project - Wireless networks seminar
iPhone project - Wireless networks seminar
 
jQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journeyjQuery Data Manipulate API - A source code dissecting journey
jQuery Data Manipulate API - A source code dissecting journey
 
Moar tools for asynchrony!
Moar tools for asynchrony!Moar tools for asynchrony!
Moar tools for asynchrony!
 
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docxWeb CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
Web CrawlersrcedusmulylecrawlerController.javaWeb Crawler.docx
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
 
Taking a Test Drive
Taking a Test DriveTaking a Test Drive
Taking a Test Drive
 
Beacons, Raspberry Pi & Node.js
Beacons, Raspberry Pi & Node.jsBeacons, Raspberry Pi & Node.js
Beacons, Raspberry Pi & Node.js
 
Introduction to Parse
Introduction to ParseIntroduction to Parse
Introduction to Parse
 
Your Second iPhone App - Code Listings
Your Second iPhone App - Code ListingsYour Second iPhone App - Code Listings
Your Second iPhone App - Code Listings
 
mobile in the cloud with diamonds. improved.
mobile in the cloud with diamonds. improved.mobile in the cloud with diamonds. improved.
mobile in the cloud with diamonds. improved.
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Dernier (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 

Working with AFNetworking

  • 2. Before AFNetworking • NSURLConnection (meh) • NSData (BARF!) • CFNetwork (medic!)
  • 3. NSURLConnection - (IBAction)didSelectRefreshButton:(id)sender { NSURL *url = [NSURL URLWithString:@"http://ip.jsontest.com/"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; ! self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; } ! #pragma mark - NSURLConnection ! - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { _data = nil; ! switch (response.statusCode) { case 200: { self.data = [NSMutableData dataWithCapacity:(NSUInteger)response.expectedContentLength]; } break; default: { [connection cancel]; ! NSError *error = [NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork code:response.statusCode userInfo:@{(NSString *)kCFErrorDescriptionKey : (NSString *)kCFURLErrorFailingURLErrorKey}]; [self connection:connection didFailWithError:error]; } break; } } ! - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.data appendData:data]; } ! - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSError *error = nil; NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:&error]; if (!jsonData) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The data was corrupt. Sorry" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } else { NSString *ip = jsonData[@"ip"]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:[NSString stringWithFormat:@"Your IP is: %@", ip] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } ! self.connection = nil; } ! - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"There was an error getting the data. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; self.connection = nil; } • All this code, just to download and display this: {"ip": "72.191.49.142"}
  • 4. NSData • One line of code! ! dataWithContentsOfURL: ! NEVER USE THIS API!
  • 5. CFNetwork NSURL *url = [NSURL URLWithString:DOWNLOAD_URL]; ! CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CFSTR("GET"), (__bridge CFURLRef)url, kCFHTTPVersion1_1); ! CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, request); CFReadStreamOpen(requestStream); NSMutableData *responseBytes = [NSMutableData data]; CFIndex numBytesRead = 0 ; NSUInteger totalBytesRead = 0; ! do { UInt8 buf[1024]; numBytesRead = CFReadStreamRead(requestStream, buf, sizeof(buf)); if(numBytesRead > 0) { [responseBytes appendBytes:buf length:numBytesRead]; totalBytesRead += numBytesRead; } } while(numBytesRead > 0); if (totalBytesRead > 0) { CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader); CFHTTPMessageSetBody(response, (__bridge CFDataRef)responseBytes); CFReadStreamClose(requestStream); CFDataRef responseBodyData = CFHTTPMessageCopyBody(response); NSError *error = nil; NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:(__bridge NSData *)responseBodyData options:0 error:&error]; CFRelease(responseBodyData); CFRelease(response); if (!jsonData) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The data was corrupt. Sorry" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } else { NSString *ip = jsonData[@"ip"]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:[NSString stringWithFormat:@"Your IP is: %@", ip] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } } else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"There was an error getting the data. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } ! CFRelease(requestStream); CFRelease(request); • All this code, just to download and display this: {"ip": "72.191.49.142"} • Plus we have to write gross C with nasty CFRelease()
  • 6. AFNetworking “AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the Foundation URL Loading System, extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use.”
  • 7. AFNetworking NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:DOWNLOAD_URL]]; ! AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [operation setResponseSerializer:[AFJSONResponseSerializer serializer]]; [operation setCompletionBlockWithSuccess:successHandler failure:failureHandler]; ! [operation start];
  • 8. AFNetworking void(^failureHandler)(AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, NSError *error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"There was an error getting the data. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; };
  • 9. AFNetworking void(^successHandler)(AFHTTPRequestOperation *, id) = ^(AFHTTPRequestOperation *operation, id responseObject) { if (!responseObject) { failureHandler(operation, [NSError errorWithDomain:AFNetworkingErrorDomain code:404 userInfo:nil]); } else { NSString *ip = responseObject[@"ip"]; ! UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:[NSString stringWithFormat:@"Your IP is: %@", ip] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } };
  • 10. void(^failureHandler)(AFHTTPRequestOperation *, NSError *) = ^(AFHTTPRequestOperation *operation, NSError *error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"There was an error getting the data. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; }; void(^successHandler)(AFHTTPRequestOperation *, id) = ^(AFHTTPRequestOperation *operation, id responseObject) { if (!responseObject) { failureHandler(operation, [NSError errorWithDomain:AFNetworkingErrorDomain code:404 userInfo:nil]); } else { NSString *ip = responseObject[@"ip"]; ! UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:[NSString stringWithFormat:@"Your IP is: %@", ip] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } }; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:DOWNLOAD_URL]]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [operation setResponseSerializer:[AFJSONResponseSerializer serializer]]; [operation setCompletionBlockWithSuccess:successHandler failure:failureHandler]; ! [operation start]; - (IBAction)didSelectRefreshButton:(id)sender { NSURL *url = [NSURL URLWithString:@"http://ip.jsontest.com/"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; ! self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; } ! #pragma mark - NSURLConnection ! - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { _data = nil; ! switch (response.statusCode) { case 200: { self.data = [NSMutableData dataWithCapacity:(NSUInteger)response.expectedContentLength]; } break; default: { [connection cancel]; ! NSError *error = [NSError errorWithDomain:(NSString *)kCFErrorDomainCFNetwork code:response.statusCode userInfo:@{(NSString *)kCFErrorDescriptionKey : (NSString *)kCFURLErrorFailingURLErrorKey}]; [self connection:connection didFailWithError:error]; } break; } } ! - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [self.data appendData:data]; } ! - (void)connectionDidFinishLoading:(NSURLConnection *)connection { NSError *error = nil; NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:&error]; if (!jsonData) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The data was corrupt. Sorry" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } else { NSString *ip = jsonData[@"ip"]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:[NSString stringWithFormat:@"Your IP is: %@", ip] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } ! self.connection = nil; } ! - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"There was an error getting the data. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; self.connection = nil; }
  • 11.
  • 12. Key Concepts • AF*Operation are subclasses of NSOperation • Networking operations can be started individually or placed in an NSOperationQueue • Custom serialization classes can be created for transforming and validating data.
  • 14. AFURLResponseSerializer • If you don’t specify a request/response serializer, it will give back NSData. • Serializers can be created to handle data transformation and validation.
  • 16. Custom Serializer • Subclass AFHTTPResponseSerializer • Override • responseObjectForResponse:data:error: • acceptableContentTypes
  • 17. Custom Serializer • We’re going to create a serializer for decoding 1337593@k
  • 18. Anyone know the Content-Type for 1337 encoded data?
  • 21. AFNetworking + UIKit • AFNetworking adds a number of extensions to common UIKit classes: • UIImageView • UIButton • UIWebView • UIProgressView • UIRefreshControl
  • 24. “At its heart, programming is all about abstraction.” Justin Spahr-Summers CocoaConf Austin 2014
  • 25. Classes should have as few purposes as possible (say, one) and do it very well. ! Classes should know as little as possible about other classes.
  • 26. Are your View Controllers like this?
  • 28.
  • 29. Monster View Controller • UITableView Datasource • Configure Cells • UITableView Delegate • Showing Member Details • NSFetchedResultsControllerDelegate • Fetch All Member data • Fetch Checked-In Members • Fetch Profile Images • Search Members By Name • Search Members By Skills • Data Persistance • Check-In logic • Checked-In vs All Members
  • 30.
  • 31.