mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-23 20:31:13 +08:00
Merge branch 'reachability-queue-three20'
Conflicts: Code/Network/RKResponse.m
This commit is contained in:
@@ -10,3 +10,5 @@
|
||||
#import "RKRequest.h"
|
||||
#import "RKResponse.h"
|
||||
#import "RKRequestSerializable.h"
|
||||
#import "RKReachabilityObserver.h"
|
||||
#import "RKRequestQueue.h"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import "RKParams.h"
|
||||
#import "RKResponse.h"
|
||||
#import "NSDictionary+RKRequestSerialization.h"
|
||||
#import "RKReachabilityObserver.h"
|
||||
|
||||
/**
|
||||
* RKClient exposes the low level client interface for working
|
||||
@@ -21,6 +22,7 @@
|
||||
NSString* _username;
|
||||
NSString* _password;
|
||||
NSMutableDictionary* _HTTPHeaders;
|
||||
RKReachabilityObserver* _baseURLReachabilityObserver;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,12 @@
|
||||
*/
|
||||
@property(nonatomic, readonly) NSDictionary* HTTPHeaders;
|
||||
|
||||
/**
|
||||
* The RKReachabilityObserver used to monitor whether or not the client has a connection
|
||||
* path to the baseURL
|
||||
*/
|
||||
@property(nonatomic, readonly) RKReachabilityObserver* baseURLReachabilityObserver;
|
||||
|
||||
/**
|
||||
* Return the configured singleton instance of the Rest client
|
||||
*/
|
||||
@@ -95,11 +103,13 @@
|
||||
*/
|
||||
- (NSURL*)URLForResourcePath:(NSString *)resourcePath queryParams:(NSDictionary*)queryParams;
|
||||
|
||||
- (void)setupRequest:(RKRequest*)request;
|
||||
|
||||
/**
|
||||
* Return a request object targetted at a resource path relative to the base URL. By default the method is set to GET
|
||||
* All headers set on the client will automatically be applied to the request as well.
|
||||
*/
|
||||
- (RKRequest*)requestWithResourcePath:(NSString*)resourcePath delegate:(id)delegate callback:(SEL)callback;
|
||||
- (RKRequest*)requestWithResourcePath:(NSString*)resourcePath delegate:(id)delegate;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Asynchronous Helper Methods
|
||||
@@ -112,31 +122,31 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetch a resource via an HTTP GET and invoke a callback with the result
|
||||
* Fetch a resource via an HTTP GET
|
||||
*/
|
||||
- (RKRequest*)get:(NSString*)resourcePath delegate:(id)delegate callback:(SEL)callback;
|
||||
- (RKRequest*)get:(NSString*)resourcePath delegate:(id)delegate;
|
||||
|
||||
/**
|
||||
* Fetch a resource via an HTTP GET with a dictionary of params and invoke a callback with the resulting payload
|
||||
* Fetch a resource via an HTTP GET with a dictionary of params
|
||||
*
|
||||
* Note that this request _only_ allows NSDictionary objects as the params. The dictionary will be coerced into a URL encoded
|
||||
* string and then appended to the resourcePath as the query string of the request.
|
||||
*/
|
||||
- (RKRequest*)get:(NSString*)resourcePath queryParams:(NSDictionary*)queryParams delegate:(id)delegate callback:(SEL)callback;
|
||||
- (RKRequest*)get:(NSString*)resourcePath queryParams:(NSDictionary*)queryParams delegate:(id)delegate;
|
||||
|
||||
/**
|
||||
* Create a resource via an HTTP POST with a set of form parameters and invoke a callback with the resulting payload
|
||||
* Create a resource via an HTTP POST with a set of form parameters
|
||||
*/
|
||||
- (RKRequest*)post:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate callback:(SEL)callback;
|
||||
- (RKRequest*)post:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate;
|
||||
|
||||
/**
|
||||
* Update a resource via an HTTP PUT and invoke a callback with the resulting payload
|
||||
* Update a resource via an HTTP PUT
|
||||
*/
|
||||
- (RKRequest*)put:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate callback:(SEL)callback;
|
||||
- (RKRequest*)put:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate;
|
||||
|
||||
/**
|
||||
* Destroy a resource via an HTTP DELETE and invoke a callback with the resulting payload
|
||||
* Destroy a resource via an HTTP DELETE
|
||||
*/
|
||||
- (RKRequest*)delete:(NSString*)resourcePath delegate:(id)delegate callback:(SEL)callback;
|
||||
- (RKRequest*)delete:(NSString*)resourcePath delegate:(id)delegate;
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,6 +24,7 @@ static RKClient* sharedClient = nil;
|
||||
@synthesize username = _username;
|
||||
@synthesize password = _password;
|
||||
@synthesize HTTPHeaders = _HTTPHeaders;
|
||||
@synthesize baseURLReachabilityObserver = _baseURLReachabilityObserver;
|
||||
|
||||
+ (RKClient*)sharedClient {
|
||||
return sharedClient;
|
||||
@@ -80,20 +81,13 @@ static RKClient* sharedClient = nil;
|
||||
}
|
||||
|
||||
- (BOOL)isNetworkAvailable {
|
||||
Boolean success;
|
||||
|
||||
const char *host_name = "google.com"; // your data source host name
|
||||
|
||||
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host_name);
|
||||
#ifdef TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
|
||||
SCNetworkReachabilityFlags flags;
|
||||
#else
|
||||
SCNetworkConnectionFlags flags;
|
||||
#endif
|
||||
success = SCNetworkReachabilityGetFlags(reachability, &flags);
|
||||
BOOL isNetworkAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
|
||||
CFRelease(reachability);
|
||||
|
||||
BOOL isNetworkAvailable = NO;
|
||||
if (self.baseURLReachabilityObserver) {
|
||||
isNetworkAvailable = [self.baseURLReachabilityObserver isNetworkReachable];
|
||||
} else {
|
||||
RKReachabilityObserver* googleObserver = [RKReachabilityObserver reachabilityObserverWithHostName:@"google.com"];
|
||||
isNetworkAvailable = [googleObserver isNetworkReachable];
|
||||
}
|
||||
return isNetworkAvailable;
|
||||
}
|
||||
|
||||
@@ -119,8 +113,18 @@ static RKClient* sharedClient = nil;
|
||||
[_HTTPHeaders setValue:value forKey:header];
|
||||
}
|
||||
|
||||
- (RKRequest*)requestWithResourcePath:(NSString*)resourcePath delegate:(id)delegate callback:(SEL)callback {
|
||||
RKRequest* request = [[RKRequest alloc] initWithURL:[self URLForResourcePath:resourcePath] delegate:delegate callback:callback];
|
||||
- (void)setBaseURL:(NSString*)baseURL {
|
||||
[_baseURL release];
|
||||
_baseURL = nil;
|
||||
_baseURL = [baseURL retain];
|
||||
|
||||
[_baseURLReachabilityObserver release];
|
||||
_baseURLReachabilityObserver = nil;
|
||||
_baseURLReachabilityObserver = [[RKReachabilityObserver reachabilityObserverWithHostName:baseURL] retain];
|
||||
}
|
||||
|
||||
- (RKRequest*)requestWithResourcePath:(NSString*)resourcePath delegate:(id)delegate {
|
||||
RKRequest* request = [[RKRequest alloc] initWithURL:[self URLForResourcePath:resourcePath] delegate:delegate];
|
||||
[self setupRequest:request];
|
||||
[request autorelease];
|
||||
|
||||
@@ -131,8 +135,8 @@ static RKClient* sharedClient = nil;
|
||||
// Asynchronous Requests
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
- (RKRequest*)load:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate callback:(SEL)callback {
|
||||
RKRequest* request = [[RKRequest alloc] initWithURL:[self URLForResourcePath:resourcePath] delegate:delegate callback:callback];
|
||||
- (RKRequest*)load:(NSString*)resourcePath method:(RKRequestMethod)method params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate {
|
||||
RKRequest* request = [[RKRequest alloc] initWithURL:[self URLForResourcePath:resourcePath] delegate:delegate];
|
||||
[self setupRequest:request];
|
||||
[request autorelease];
|
||||
request.params = params;
|
||||
@@ -142,25 +146,25 @@ static RKClient* sharedClient = nil;
|
||||
return request;
|
||||
}
|
||||
|
||||
- (RKRequest*)get:(NSString*)resourcePath delegate:(id)delegate callback:(SEL)callback {
|
||||
return [self load:resourcePath method:RKRequestMethodGET params:nil delegate:delegate callback:callback];
|
||||
- (RKRequest*)get:(NSString*)resourcePath delegate:(id)delegate {
|
||||
return [self load:resourcePath method:RKRequestMethodGET params:nil delegate:delegate];
|
||||
}
|
||||
|
||||
- (RKRequest*)get:(NSString*)resourcePath queryParams:(NSDictionary*)queryParams delegate:(id)delegate callback:(SEL)callback {
|
||||
- (RKRequest*)get:(NSString*)resourcePath queryParams:(NSDictionary*)queryParams delegate:(id)delegate {
|
||||
NSString* resourcePathWithQueryString = [NSString stringWithFormat:@"%@?%@", resourcePath, [queryParams URLEncodedString]];
|
||||
return [self load:resourcePathWithQueryString method:RKRequestMethodGET params:nil delegate:delegate callback:callback];
|
||||
return [self load:resourcePathWithQueryString method:RKRequestMethodGET params:nil delegate:delegate];
|
||||
}
|
||||
|
||||
- (RKRequest*)post:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate callback:(SEL)callback {
|
||||
return [self load:resourcePath method:RKRequestMethodPOST params:params delegate:delegate callback:callback];
|
||||
- (RKRequest*)post:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate {
|
||||
return [self load:resourcePath method:RKRequestMethodPOST params:params delegate:delegate];
|
||||
}
|
||||
|
||||
- (RKRequest*)put:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate callback:(SEL)callback {
|
||||
return [self load:resourcePath method:RKRequestMethodPUT params:params delegate:delegate callback:callback];
|
||||
- (RKRequest*)put:(NSString*)resourcePath params:(NSObject<RKRequestSerializable>*)params delegate:(id)delegate {
|
||||
return [self load:resourcePath method:RKRequestMethodPUT params:params delegate:delegate];
|
||||
}
|
||||
|
||||
- (RKRequest*)delete:(NSString*)resourcePath delegate:(id)delegate callback:(SEL)callback {
|
||||
return [self load:resourcePath method:RKRequestMethodDELETE params:nil delegate:delegate callback:callback];
|
||||
- (RKRequest*)delete:(NSString*)resourcePath delegate:(id)delegate {
|
||||
return [self load:resourcePath method:RKRequestMethodDELETE params:nil delegate:delegate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -18,3 +18,4 @@
|
||||
*/
|
||||
extern NSString* const kRKRequestSentNotification;
|
||||
extern NSString* const kRKResponseReceivedNotification;
|
||||
extern NSString* const kRKRequestFailedWithErrorNotification;
|
||||
@@ -10,3 +10,4 @@
|
||||
|
||||
NSString* const kRKRequestSentNotification = @"kRKRequestSentNotification";
|
||||
NSString* const kRKResponseReceivedNotification = @"kRKRespongReceivedNotification";
|
||||
NSString* const kRKRequestFailedWithErrorNotification = @"kRKRequestFailedWithErrorNotification";
|
||||
|
||||
55
Code/Network/RKReachabilityObserver.h
Executable file
55
Code/Network/RKReachabilityObserver.h
Executable file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// RKReachabilityObserver.h
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 9/14/10.
|
||||
// Copyright 2010 RestKit. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <SystemConfiguration/SystemConfiguration.h>
|
||||
|
||||
/**
|
||||
* Posted when the network state has changed
|
||||
*/
|
||||
extern NSString* const RKReachabilityStateChangedNotification;
|
||||
|
||||
typedef enum {
|
||||
RKReachabilityNotReachable,
|
||||
RKReachabilityReachableViaWiFi,
|
||||
RKReachabilityReachableViaWWAN
|
||||
} RKReachabilityNetworkStatus;
|
||||
|
||||
/**
|
||||
* Provides a notification based interface for monitoring changes
|
||||
* to network status
|
||||
*/
|
||||
@interface RKReachabilityObserver : NSObject {
|
||||
SCNetworkReachabilityRef _reachabilityRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new reachability observer against a given hostname. The observer
|
||||
* will monitor the ability to reach the specified hostname and emit notifications
|
||||
* when its reachability status changes.
|
||||
*
|
||||
* Note that the observer will be scheduled in the current run loop.
|
||||
*/
|
||||
+ (RKReachabilityObserver*)reachabilityObserverWithHostName:(NSString*)hostName;
|
||||
|
||||
/**
|
||||
* Returns the current network status
|
||||
*/
|
||||
- (RKReachabilityNetworkStatus)networkStatus;
|
||||
|
||||
/**
|
||||
* Returns YES when the Internet is reachable (via WiFi or WWAN)
|
||||
*/
|
||||
- (BOOL)isNetworkReachable;
|
||||
|
||||
/**
|
||||
* Returns YES when WWAN may be available, but not active until a connection has been established.
|
||||
*/
|
||||
- (BOOL)isConnectionRequired;
|
||||
|
||||
@end
|
||||
145
Code/Network/RKReachabilityObserver.m
Executable file
145
Code/Network/RKReachabilityObserver.m
Executable file
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// RKReachabilityObserver.m
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 9/14/10.
|
||||
// Copyright 2010 RestKit. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RKReachabilityObserver.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
// Constants
|
||||
NSString* const RKReachabilityStateChangedNotification = @"RKReachabilityStateChangedNotification";
|
||||
|
||||
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
|
||||
#pragma unused (target, flags)
|
||||
// We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
|
||||
// in case someone uses the Reachablity object in a different thread.
|
||||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
RKReachabilityObserver* observer = (RKReachabilityObserver*) info;
|
||||
// Post a notification to notify the client that the network reachability changed.
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RKReachabilityStateChangedNotification object:observer];
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface RKReachabilityObserver (Private)
|
||||
|
||||
// Internal initializer
|
||||
- (id)initWithReachabilityRef:(SCNetworkReachabilityRef)reachabilityRef;
|
||||
- (void)scheduleObserver;
|
||||
- (void)unscheduleObserver;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RKReachabilityObserver
|
||||
|
||||
+ (RKReachabilityObserver*)reachabilityObserverWithHostName:(NSString*)hostName {
|
||||
RKReachabilityObserver* observer = nil;
|
||||
SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
|
||||
|
||||
if (nil != reachabilityRef) {
|
||||
observer = [[[self alloc] initWithReachabilityRef:reachabilityRef] autorelease];
|
||||
}
|
||||
return observer;
|
||||
}
|
||||
|
||||
- (id)initWithReachabilityRef:(SCNetworkReachabilityRef)reachabilityRef {
|
||||
if (self = [self init]) {
|
||||
_reachabilityRef = reachabilityRef;
|
||||
[self scheduleObserver];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(scheduleObserver)
|
||||
name:UIApplicationDidBecomeActiveNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(unscheduleObserver)
|
||||
name:UIApplicationWillResignActiveNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[self unscheduleObserver];
|
||||
if (_reachabilityRef) {
|
||||
CFRelease(_reachabilityRef);
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (RKReachabilityNetworkStatus)networkStatus {
|
||||
NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
|
||||
RKReachabilityNetworkStatus status = RKReachabilityNotReachable;
|
||||
SCNetworkReachabilityFlags flags;
|
||||
|
||||
if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)) {
|
||||
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) {
|
||||
// if target host is not reachable
|
||||
return RKReachabilityNotReachable;
|
||||
}
|
||||
|
||||
if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) {
|
||||
// if target host is reachable and no connection is required
|
||||
// then we'll assume (for now) that your on Wi-Fi
|
||||
status = RKReachabilityReachableViaWiFi;
|
||||
}
|
||||
|
||||
|
||||
if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
|
||||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) {
|
||||
// ... and the connection is on-demand (or on-traffic) if the
|
||||
// calling application is using the CFSocketStream or higher APIs
|
||||
|
||||
if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) {
|
||||
// ... and no [user] intervention is needed
|
||||
status = RKReachabilityReachableViaWiFi;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) {
|
||||
// ... but WWAN connections are OK if the calling application
|
||||
// is using the CFNetwork (CFSocketStream?) APIs.
|
||||
status = RKReachabilityReachableViaWWAN;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
- (BOOL)isNetworkReachable {
|
||||
return (RKReachabilityNotReachable != [self networkStatus]);
|
||||
}
|
||||
|
||||
- (BOOL)isConnectionRequired {
|
||||
NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
|
||||
SCNetworkReachabilityFlags flags;
|
||||
if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)) {
|
||||
return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark Observer scheduling
|
||||
|
||||
- (void)scheduleObserver {
|
||||
SCNetworkReachabilityContext context = {0, self, NULL, NULL, NULL};
|
||||
if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context)) {
|
||||
if (NO == SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
|
||||
NSLog(@"Warning -- Unable to schedule reachability observer in current run loop.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unscheduleObserver {
|
||||
if (nil != _reachabilityRef) {
|
||||
SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -22,6 +22,7 @@ typedef enum RKRequestMethod {
|
||||
} RKRequestMethod;
|
||||
|
||||
@class RKResponse;
|
||||
@protocol RKRequestDelegate;
|
||||
|
||||
@interface RKRequest : NSObject {
|
||||
NSURL* _URL;
|
||||
@@ -29,12 +30,13 @@ typedef enum RKRequestMethod {
|
||||
NSURLConnection* _connection;
|
||||
NSDictionary* _additionalHTTPHeaders;
|
||||
NSObject<RKRequestSerializable>* _params;
|
||||
id _delegate;
|
||||
SEL _callback;
|
||||
NSObject<RKRequestDelegate>* _delegate;
|
||||
id _userData;
|
||||
NSString* _username;
|
||||
NSString* _password;
|
||||
RKRequestMethod _method;
|
||||
BOOL _isLoading;
|
||||
BOOL _isLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,6 +44,11 @@ typedef enum RKRequestMethod {
|
||||
*/
|
||||
@property(nonatomic, readonly) NSURL* URL;
|
||||
|
||||
/**
|
||||
* The resourcePath portion of this loader's URL
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString* resourcePath;
|
||||
|
||||
/**
|
||||
* The HTTP verb the request is sent via
|
||||
*
|
||||
@@ -61,12 +68,7 @@ typedef enum RKRequestMethod {
|
||||
* If the object implements the RKRequestDelegate protocol,
|
||||
* it will receive request lifecycle event messages.
|
||||
*/
|
||||
@property(nonatomic, assign) id delegate;
|
||||
|
||||
/**
|
||||
* The selector to invoke when the request is completed
|
||||
*/
|
||||
@property(nonatomic, assign) SEL callback;
|
||||
@property(nonatomic, assign) NSObject<RKRequestDelegate>* delegate;
|
||||
|
||||
/**
|
||||
* A Dictionary of additional HTTP Headers to send with the request
|
||||
@@ -100,7 +102,7 @@ typedef enum RKRequestMethod {
|
||||
/**
|
||||
* Return a REST request that is ready for dispatching
|
||||
*/
|
||||
+ (RKRequest*)requestWithURL:(NSURL*)URL delegate:(id)delegate callback:(SEL)callback;
|
||||
+ (RKRequest*)requestWithURL:(NSURL*)URL delegate:(id)delegate;
|
||||
|
||||
/**
|
||||
* Initialize a synchronous request
|
||||
@@ -110,10 +112,11 @@ typedef enum RKRequestMethod {
|
||||
/**
|
||||
* Initialize a REST request and prepare it for dispatching
|
||||
*/
|
||||
- (id)initWithURL:(NSURL*)URL delegate:(id)delegate callback:(SEL)callback;
|
||||
- (id)initWithURL:(NSURL*)URL delegate:(id)delegate;
|
||||
|
||||
/**
|
||||
* Send the request asynchronously
|
||||
* Send the request asynchronously. It will be added to the queue and
|
||||
* dispatched as soon as possible.
|
||||
*/
|
||||
- (void)send;
|
||||
|
||||
@@ -122,6 +125,18 @@ typedef enum RKRequestMethod {
|
||||
*/
|
||||
- (RKResponse*)sendSynchronously;
|
||||
|
||||
/**
|
||||
* Callback performed to notify the request that the underlying NSURLConnection
|
||||
* has failed with an error.
|
||||
*/
|
||||
- (void)didFailLoadWithError:(NSError*)error;
|
||||
|
||||
/**
|
||||
* Callback performed to notify the request that the underlying NSURLConnection
|
||||
* has completed with a response.
|
||||
*/
|
||||
- (void)didFinishLoad:(RKResponse*)response;
|
||||
|
||||
/**
|
||||
* Cancels the underlying URL connection
|
||||
*/
|
||||
@@ -147,6 +162,16 @@ typedef enum RKRequestMethod {
|
||||
*/
|
||||
- (BOOL)isDELETE;
|
||||
|
||||
/**
|
||||
* Returns YES when this request is in-progress
|
||||
*/
|
||||
- (BOOL)isLoading;
|
||||
|
||||
/**
|
||||
* Returns YES when this request has been completed
|
||||
*/
|
||||
- (BOOL)isLoaded;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
@@ -154,18 +179,13 @@ typedef enum RKRequestMethod {
|
||||
*
|
||||
* Modeled off of TTURLRequest
|
||||
*/
|
||||
@protocol RKRequestDelegate
|
||||
@protocol RKRequestDelegate
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Sent when a request has started loading
|
||||
*/
|
||||
- (void)requestDidStartLoad:(RKRequest*)request;
|
||||
|
||||
/**
|
||||
* Sent when a request has finished loading
|
||||
*/
|
||||
- (void)requestDidFinishLoad:(RKRequest*)request;
|
||||
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response;
|
||||
|
||||
/**
|
||||
* Sent when a request has failed due to an error
|
||||
@@ -173,9 +193,9 @@ typedef enum RKRequestMethod {
|
||||
- (void)request:(RKRequest*)request didFailLoadWithError:(NSError*)error;
|
||||
|
||||
/**
|
||||
* Sent when a request has been canceled
|
||||
* Sent when a request has started loading
|
||||
*/
|
||||
- (void)requestDidCancelLoad:(RKRequest*)request;
|
||||
- (void)requestDidStartLoad:(RKRequest*)request;
|
||||
|
||||
/**
|
||||
* Sent when a request has uploaded data to the remote site
|
||||
|
||||
@@ -7,20 +7,21 @@
|
||||
//
|
||||
|
||||
#import "RKRequest.h"
|
||||
#import "RKRequestQueue.h"
|
||||
#import "RKResponse.h"
|
||||
#import "NSDictionary+RKRequestSerialization.h"
|
||||
#import "RKNotifications.h"
|
||||
#import "RKClient.h"
|
||||
#import "../Support/Support.h"
|
||||
#import "RKURL.h"
|
||||
|
||||
@implementation RKRequest
|
||||
|
||||
@synthesize URL = _URL, URLRequest = _URLRequest, delegate = _delegate, callback = _callback, additionalHTTPHeaders = _additionalHTTPHeaders,
|
||||
@synthesize URL = _URL, URLRequest = _URLRequest, delegate = _delegate, additionalHTTPHeaders = _additionalHTTPHeaders,
|
||||
params = _params, userData = _userData, username = _username, password = _password, method = _method;
|
||||
|
||||
+ (RKRequest*)requestWithURL:(NSURL*)URL delegate:(id)delegate callback:(SEL)callback {
|
||||
RKRequest* request = [[RKRequest alloc] initWithURL:URL delegate:delegate callback:callback];
|
||||
[request autorelease];
|
||||
|
||||
return request;
|
||||
+ (RKRequest*)requestWithURL:(NSURL*)URL delegate:(id)delegate {
|
||||
return [[[RKRequest alloc] initWithURL:URL delegate:delegate] autorelease];
|
||||
}
|
||||
|
||||
- (id)initWithURL:(NSURL*)URL {
|
||||
@@ -28,30 +29,38 @@
|
||||
_URL = [URL retain];
|
||||
_URLRequest = [[NSMutableURLRequest alloc] initWithURL:_URL];
|
||||
_connection = nil;
|
||||
_isLoading = NO;
|
||||
_isLoaded = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initWithURL:(NSURL*)URL delegate:(id)delegate callback:(SEL)callback {
|
||||
- (id)initWithURL:(NSURL*)URL delegate:(id)delegate {
|
||||
if (self = [self initWithURL:URL]) {
|
||||
_delegate = delegate;
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
self.delegate = nil;
|
||||
[_connection cancel];
|
||||
[_connection release];
|
||||
_connection = nil;
|
||||
[_userData release];
|
||||
_userData = nil;
|
||||
[_URL release];
|
||||
_URL = nil;
|
||||
[_URLRequest release];
|
||||
_URLRequest = nil;
|
||||
[_params release];
|
||||
_params = nil;
|
||||
[_additionalHTTPHeaders release];
|
||||
_additionalHTTPHeaders = nil;
|
||||
[_username release];
|
||||
_username = nil;
|
||||
[_password release];
|
||||
_password = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -126,38 +135,96 @@
|
||||
}
|
||||
|
||||
- (void)send {
|
||||
[self addHeadersToRequest];
|
||||
NSString* body = [[NSString alloc] initWithData:[_URLRequest HTTPBody] encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"Sending %@ request to URL %@. HTTP Body: %@", [self HTTPMethod], [[self URL] absoluteString], body);
|
||||
[body release];
|
||||
NSDate* sentAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", sentAt, @"sentAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestSentNotification object:self userInfo:userInfo];
|
||||
RKResponse* response = [[[RKResponse alloc] initWithRequest:self] autorelease];
|
||||
_connection = [[NSURLConnection connectionWithRequest:_URLRequest delegate:response] retain];
|
||||
[[RKRequestQueue sharedQueue] sendRequest:self];
|
||||
}
|
||||
|
||||
- (void)fireAsynchronousRequest {
|
||||
if ([[RKClient sharedClient] isNetworkAvailable]) {
|
||||
[self addHeadersToRequest];
|
||||
NSString* body = [[NSString alloc] initWithData:[_URLRequest HTTPBody] encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"Sending %@ request to URL %@. HTTP Body: %@", [self HTTPMethod], [[self URL] absoluteString], body);
|
||||
[body release];
|
||||
NSDate* sentAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", sentAt, @"sentAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestSentNotification object:self userInfo:userInfo];
|
||||
|
||||
_isLoading = YES;
|
||||
RKResponse* response = [[[RKResponse alloc] initWithRequest:self] autorelease];
|
||||
_connection = [[NSURLConnection connectionWithRequest:_URLRequest delegate:response] retain];
|
||||
} else {
|
||||
NSString* errorMessage = [NSString stringWithFormat:@"The client is unable to contact the resource at %@", [[self URL] absoluteString]];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
errorMessage, NSLocalizedDescriptionKey,
|
||||
nil];
|
||||
NSError* error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
|
||||
[self didFailLoadWithError:error];
|
||||
}
|
||||
}
|
||||
|
||||
- (RKResponse*)sendSynchronously {
|
||||
[self addHeadersToRequest];
|
||||
NSString* body = [[NSString alloc] initWithData:[_URLRequest HTTPBody] encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"Sending synchronous %@ request to URL %@. HTTP Body: %@", [self HTTPMethod], [[self URL] absoluteString], body);
|
||||
[body release];
|
||||
NSDate* sentAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", sentAt, @"sentAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestSentNotification object:self userInfo:userInfo];
|
||||
NSURLResponse* URLResponse = nil;
|
||||
NSError* error = nil;
|
||||
NSData* payload = [NSURLConnection sendSynchronousRequest:_URLRequest returningResponse:&URLResponse error:&error];
|
||||
return [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
|
||||
NSData* payload = nil;
|
||||
RKResponse* response = nil;
|
||||
|
||||
if ([[RKClient sharedClient] isNetworkAvailable]) {
|
||||
[self addHeadersToRequest];
|
||||
NSString* body = [[NSString alloc] initWithData:[_URLRequest HTTPBody] encoding:NSUTF8StringEncoding];
|
||||
NSLog(@"Sending synchronous %@ request to URL %@. HTTP Body: %@", [self HTTPMethod], [[self URL] absoluteString], body);
|
||||
[body release];
|
||||
NSDate* sentAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", sentAt, @"sentAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestSentNotification object:self userInfo:userInfo];
|
||||
|
||||
_isLoading = YES;
|
||||
payload = [NSURLConnection sendSynchronousRequest:_URLRequest returningResponse:&URLResponse error:&error];
|
||||
response = [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
|
||||
} else {
|
||||
NSString* errorMessage = [NSString stringWithFormat:@"The client is unable to contact the resource at %@", [[self URL] absoluteString]];
|
||||
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
errorMessage, NSLocalizedDescriptionKey,
|
||||
nil];
|
||||
error = [NSError errorWithDomain:RKRestKitErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
|
||||
[self didFailLoadWithError:error];
|
||||
|
||||
// TODO: Is this needed here? Or can we just return a nil response and everyone will be happy??
|
||||
response = [[[RKResponse alloc] initWithSynchronousRequest:self URLResponse:URLResponse body:payload error:error] autorelease];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (void)cancel {
|
||||
[_connection cancel];
|
||||
[_connection release];
|
||||
_connection = nil;
|
||||
if ([_delegate respondsToSelector:@selector(requestDidCancelLoad:)]) {
|
||||
[_delegate requestDidCancelLoad:self];
|
||||
_isLoading = NO;
|
||||
}
|
||||
|
||||
- (void)didFailLoadWithError:(NSError*)error {
|
||||
_isLoading = NO;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[_delegate request:self didFailLoadWithError:error];
|
||||
}
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod",
|
||||
[self URL], @"URL", receivedAt, @"receivedAt", error, @"error", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKRequestFailedWithErrorNotification object:self userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (void)didFinishLoad:(RKResponse*)response {
|
||||
_isLoading = NO;
|
||||
_isLoaded = YES;
|
||||
|
||||
if ([_delegate respondsToSelector:@selector(request:didLoadResponse:)]) {
|
||||
[_delegate request:self didLoadResponse:response];
|
||||
}
|
||||
|
||||
NSDate* receivedAt = [NSDate date];
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[self HTTPMethod], @"HTTPMethod", [self URL], @"URL", receivedAt, @"receivedAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:response userInfo:userInfo];
|
||||
}
|
||||
|
||||
- (BOOL)isGET {
|
||||
@@ -176,4 +243,21 @@
|
||||
return _method == RKRequestMethodDELETE;
|
||||
}
|
||||
|
||||
- (BOOL)isLoading {
|
||||
return _isLoading;
|
||||
}
|
||||
|
||||
- (BOOL)isLoaded {
|
||||
return _isLoaded;
|
||||
}
|
||||
|
||||
- (NSString*)resourcePath {
|
||||
NSString* resourcePath = nil;
|
||||
if ([self.URL isKindOfClass:[RKURL class]]) {
|
||||
RKURL* url = (RKURL*)self.URL;
|
||||
resourcePath = url.resourcePath;
|
||||
}
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
63
Code/Network/RKRequestQueue.h
Normal file
63
Code/Network/RKRequestQueue.h
Normal file
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// RKRequestQueue.h
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 12/1/10.
|
||||
// Copyright 2010 Two Toasters. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RKRequest.h"
|
||||
|
||||
/**
|
||||
* A lightweight queue implementation responsible
|
||||
* for dispatching and managing RKRequest objects
|
||||
*/
|
||||
@interface RKRequestQueue : NSObject {
|
||||
NSMutableArray* _requests;
|
||||
NSInteger _totalLoading;
|
||||
NSTimer* _queueTimer;
|
||||
BOOL _suspended;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flag that determines if new load requests are allowed to reach the network.
|
||||
*
|
||||
* Because network requests tend to slow down performance, this property can be used to
|
||||
* temporarily delay them. All requests made while suspended are queued, and when
|
||||
* suspended becomes false again they are executed.
|
||||
*/
|
||||
@property (nonatomic) BOOL suspended;
|
||||
|
||||
/**
|
||||
* Return the global queue
|
||||
*/
|
||||
+ (RKRequestQueue*)sharedQueue;
|
||||
|
||||
/**
|
||||
* Set the global queue
|
||||
*/
|
||||
+ (void)setSharedQueue:(RKRequestQueue*)requestQueue;
|
||||
|
||||
/**
|
||||
* Add an asynchronous request to the queue and send it as
|
||||
* as soon as possible
|
||||
*/
|
||||
- (void)sendRequest:(RKRequest*)request;
|
||||
|
||||
/**
|
||||
* Cancel a request that is in progress
|
||||
*/
|
||||
- (void)cancelRequest:(RKRequest*)request;
|
||||
|
||||
/**
|
||||
* Cancel all requests with a given delegate
|
||||
*/
|
||||
- (void)cancelRequestsWithDelegate:(NSObject<RKRequestDelegate>*)delegate;
|
||||
|
||||
/**
|
||||
* Cancel all active or pending requests.
|
||||
*/
|
||||
- (void)cancelAllRequests;
|
||||
|
||||
@end
|
||||
163
Code/Network/RKRequestQueue.m
Normal file
163
Code/Network/RKRequestQueue.m
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// RKRequestQueue.m
|
||||
// RestKit
|
||||
//
|
||||
// Created by Blake Watters on 12/1/10.
|
||||
// Copyright 2010 Two Toasters. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RKRequestQueue.h"
|
||||
#import "RKResponse.h"
|
||||
#import "RKNotifications.h"
|
||||
|
||||
static RKRequestQueue* gSharedQueue = nil;
|
||||
|
||||
static const NSTimeInterval kFlushDelay = 0.3;
|
||||
static const NSTimeInterval kTimeout = 300.0;
|
||||
static const NSInteger kMaxConcurrentLoads = 5;
|
||||
|
||||
@implementation RKRequestQueue
|
||||
|
||||
@synthesize suspended = _suspended;
|
||||
|
||||
+ (RKRequestQueue*)sharedQueue {
|
||||
if (!gSharedQueue) {
|
||||
gSharedQueue = [[RKRequestQueue alloc] init];
|
||||
}
|
||||
return gSharedQueue;
|
||||
}
|
||||
|
||||
+ (void)setSharedQueue:(RKRequestQueue*)requestQueue {
|
||||
if (gSharedQueue != requestQueue) {
|
||||
[gSharedQueue release];
|
||||
gSharedQueue = [requestQueue retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
if (self = [super init]) {
|
||||
_requests = [[NSMutableArray alloc] init];
|
||||
_suspended = NO;
|
||||
_totalLoading = 0;
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(responseDidLoad:)
|
||||
name:kRKResponseReceivedNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(responseDidLoad:)
|
||||
name:kRKRequestFailedWithErrorNotification
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[_queueTimer invalidate];
|
||||
[_requests release];
|
||||
_requests = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)loadNextInQueueDelayed {
|
||||
if (!_queueTimer) {
|
||||
_queueTimer = [NSTimer scheduledTimerWithTimeInterval:kFlushDelay
|
||||
target:self
|
||||
selector:@selector(loadNextInQueue)
|
||||
userInfo:nil
|
||||
repeats:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dispatchRequest:(RKRequest*)request {
|
||||
[request performSelector:@selector(fireAsynchronousRequest)];
|
||||
}
|
||||
|
||||
- (void)loadNextInQueue {
|
||||
_queueTimer = nil;
|
||||
|
||||
for (RKRequest* request in _requests) {
|
||||
if (![request isLoading] && ![request isLoaded] && _totalLoading < kMaxConcurrentLoads) {
|
||||
++_totalLoading;
|
||||
[self dispatchRequest:request];
|
||||
}
|
||||
}
|
||||
|
||||
if (_requests.count && !_suspended) {
|
||||
[self loadNextInQueueDelayed];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSuspended:(BOOL)isSuspended {
|
||||
_suspended = isSuspended;
|
||||
|
||||
if (!_suspended) {
|
||||
[self loadNextInQueue];
|
||||
} else if (_queueTimer) {
|
||||
[_queueTimer invalidate];
|
||||
_queueTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendRequest:(RKRequest*)request {
|
||||
[_requests addObject:request];
|
||||
[self loadNextInQueue];
|
||||
}
|
||||
|
||||
- (void)cancelRequest:(RKRequest*)request loadNext:(BOOL)loadNext {
|
||||
if ([_requests containsObject:request] && ![request isLoaded]) {
|
||||
[request cancel];
|
||||
request.delegate = nil;
|
||||
|
||||
[_requests removeObject:request];
|
||||
_totalLoading--;
|
||||
|
||||
if (loadNext) {
|
||||
[self loadNextInQueue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelRequest:(RKRequest*)request {
|
||||
[self cancelRequest:request loadNext:YES];
|
||||
}
|
||||
|
||||
- (void)cancelRequestsWithDelegate:(NSObject<RKRequestDelegate>*)delegate {
|
||||
NSArray* requestsCopy = [NSArray arrayWithArray:_requests];
|
||||
for (RKRequest* request in requestsCopy) {
|
||||
if (request.delegate && request.delegate == delegate) {
|
||||
[self cancelRequest:request];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelAllRequests {
|
||||
NSArray* requestsCopy = [NSArray arrayWithArray:_requests];
|
||||
for (RKRequest* request in requestsCopy) {
|
||||
[self cancelRequest:request loadNext:NO];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked via observation when a request has loaded a response. Remove
|
||||
* the completed request from the queue and continue processing
|
||||
*/
|
||||
- (void)responseDidLoad:(NSNotification*)notification {
|
||||
if (notification.object) {
|
||||
// Our RKRequest completed and we're notified with an RKResponse object
|
||||
if ([notification.object isKindOfClass:[RKResponse class]]) {
|
||||
RKRequest* request = [(RKResponse*)notification.object request];
|
||||
[_requests removeObject:request];
|
||||
_totalLoading--;
|
||||
|
||||
// Our RKRequest failed and we're notified with the original RKRequest object
|
||||
} else if ([notification.object isKindOfClass:[RKRequest class]]) {
|
||||
RKRequest* request = (RKRequest*)notification.object;
|
||||
[_requests removeObject:request];
|
||||
_totalLoading--;
|
||||
}
|
||||
|
||||
[self loadNextInQueue];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -26,7 +26,9 @@
|
||||
|
||||
- (id)initWithRequest:(RKRequest*)request {
|
||||
if (self = [self init]) {
|
||||
_request = [request retain];
|
||||
// We don't retain here as we're letting RKRequestQueue manage
|
||||
// request ownership
|
||||
_request = request;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -34,7 +36,9 @@
|
||||
|
||||
- (id)initWithSynchronousRequest:(RKRequest*)request URLResponse:(NSURLResponse*)URLResponse body:(NSData*)body error:(NSError*)error {
|
||||
if (self = [super init]) {
|
||||
_request = [request retain];
|
||||
// TODO: Does the lack of retain here cause problems with synchronous requests, since they
|
||||
// are not being retained by the RKRequestQueue??
|
||||
_request = request;
|
||||
_httpURLResponse = [URLResponse retain];
|
||||
_failureError = [error retain];
|
||||
_body = [body retain];
|
||||
@@ -47,11 +51,24 @@
|
||||
- (void)dealloc {
|
||||
[_httpURLResponse release];
|
||||
[_body release];
|
||||
[_request release];
|
||||
[_failureError release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// Handle basic auth
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
|
||||
if ([challenge previousFailureCount] == 0) {
|
||||
NSURLCredential *newCredential;
|
||||
newCredential=[NSURLCredential credentialWithUser:[NSString stringWithFormat:@"%@", _request.username]
|
||||
password:[NSString stringWithFormat:@"%@", _request.password]
|
||||
persistence:NSURLCredentialPersistenceNone];
|
||||
[[challenge sender] useCredential:newCredential
|
||||
forAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
[[challenge sender] cancelAuthenticationChallenge:challenge];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
if (NO == _loading) {
|
||||
_loading = YES;
|
||||
@@ -67,25 +84,13 @@
|
||||
_httpURLResponse = [response retain];
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
NSDate* receivedAt = [NSDate date]; // TODO - Carry around this timestamp on the response or request?
|
||||
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:[_request HTTPMethod], @"HTTPMethod", [_request URL], @"URL", receivedAt, @"receivedAt", nil];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kRKResponseReceivedNotification object:self userInfo:userInfo];
|
||||
|
||||
[[_request delegate] performSelector:[_request callback] withObject:self];
|
||||
|
||||
if ([[_request delegate] respondsToSelector:@selector(requestDidFinishLoad:)]) {
|
||||
[[_request delegate] requestDidFinishLoad:_request];
|
||||
}
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
|
||||
[_request didFinishLoad:self];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
_failureError = [error retain];
|
||||
[[_request delegate] performSelector:[_request callback] withObject:self];
|
||||
|
||||
if ([[_request delegate] respondsToSelector:@selector(request:didFailLoadWithError:)]) {
|
||||
[[_request delegate] request:_request didFailLoadWithError:error];
|
||||
}
|
||||
[_request didFailLoadWithError:_failureError];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
|
||||
@@ -94,7 +99,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (NSString*)localizedStatusCodeString {
|
||||
return [NSHTTPURLResponse localizedStringForStatusCode:[self statusCode]];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user