Permalink
Browse files

Replace Restkit with AFNetworking

  • Loading branch information...
winfield committed Mar 10, 2012
1 parent 3361316 commit cd4c1de0114c775fb772095225f1eea4b498f5b6
View
@@ -1,3 +0,0 @@
-[submodule "RestKit"]
- path = RestKit
- url = git://github.com/RestKit/RestKit.git
View

Large diffs are not rendered by default.

Oops, something went wrong.
View

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,109 @@
+// AFHTTPOperation.h
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+#import "AFURLConnectionOperation.h"
+
+/**
+ `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request.
+ */
+@interface AFHTTPRequestOperation : AFURLConnectionOperation {
+@private
+ NSIndexSet *_acceptableStatusCodes;
+ NSSet *_acceptableContentTypes;
+ NSError *_HTTPError;
+ dispatch_queue_t _successCallbackQueue;
+ dispatch_queue_t _failureCallbackQueue;
+}
+
+///----------------------------------------------
+/// @name Getting HTTP URL Connection Information
+///----------------------------------------------
+
+/**
+ The last HTTP response received by the operation's connection.
+ */
+@property (readonly, nonatomic, retain) NSHTTPURLResponse *response;
+
+
+///----------------------------------------------------------
+/// @name Managing And Checking For Acceptable HTTP Responses
+///----------------------------------------------------------
+
+/**
+ Returns an `NSIndexSet` object containing the ranges of acceptable HTTP status codes. When non-`nil`, the operation will set the `error` property to an error in `AFErrorDomain`. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+
+ By default, this is the range 200 to 299, inclusive.
+ */
+@property (nonatomic, retain) NSIndexSet *acceptableStatusCodes;
+
+/**
+ A Boolean value that corresponds to whether the status code of the response is within the specified set of acceptable status codes. Returns `YES` if `acceptableStatusCodes` is `nil`.
+ */
+@property (readonly) BOOL hasAcceptableStatusCode;
+
+/**
+ Returns an `NSSet` object containing the acceptable MIME types. When non-`nil`, the operation will set the `error` property to an error in `AFErrorDomain`. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17
+
+ By default, this is `nil`.
+ */
+@property (nonatomic, retain) NSSet *acceptableContentTypes;
+
+/**
+ A Boolean value that corresponds to whether the MIME type of the response is among the specified set of acceptable content types. Returns `YES` if `acceptableContentTypes` is `nil`.
+ */
+@property (readonly) BOOL hasAcceptableContentType;
+
+/**
+ The callback dispatch queue on success. If `NULL` (default), the main queue is used.
+ */
+@property (nonatomic) dispatch_queue_t successCallbackQueue;
+
+/**
+ The callback dispatch queue on failure. If `NULL` (default), the main queue is used.
+ */
+@property (nonatomic) dispatch_queue_t failureCallbackQueue;
+
+
+/**
+ A Boolean value determining whether or not the class can process the specified request. For example, `AFJSONRequestOperation` may check to make sure the content type was `application/json` or the URL path extension was `.json`.
+
+ @param urlRequest The request that is determined to be supported or not supported for this class.
+ */
++ (BOOL)canProcessRequest:(NSURLRequest *)urlRequest;
+
+///-----------------------------------------------------------
+/// @name Setting Completion Block Success / Failure Callbacks
+///-----------------------------------------------------------
+
+/**
+ Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed.
+
+ @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request.
+ @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occured during the request.
+
+ @discussion This method should be overridden in subclasses in order to specify the response object passed into the success block.
+ */
+- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
+ failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
+
+@end
@@ -0,0 +1,190 @@
+// AFHTTPOperation.m
+//
+// Copyright (c) 2011 Gowalla (http://gowalla.com/)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "AFHTTPRequestOperation.h"
+
+static NSString * AFStringFromIndexSet(NSIndexSet *indexSet) {
+ NSMutableString *string = [NSMutableString string];
+
+ NSRange range = NSMakeRange([indexSet firstIndex], 1);
+ while (range.location != NSNotFound) {
+ NSUInteger nextIndex = [indexSet indexGreaterThanIndex:range.location];
+ while (nextIndex == range.location + range.length) {
+ range.length++;
+ nextIndex = [indexSet indexGreaterThanIndex:nextIndex];
+ }
+
+ if (string.length) {
+ [string appendString:@","];
+ }
+
+ if (range.length == 1) {
+ [string appendFormat:@"%u", range.location];
+ } else {
+ NSUInteger firstIndex = range.location;
+ NSUInteger lastIndex = firstIndex + range.length - 1;
+ [string appendFormat:@"%u-%u", firstIndex, lastIndex];
+ }
+
+ range.location = nextIndex;
+ range.length = 1;
+ }
+
+ return string;
+}
+
+#pragma mark -
+
+@interface AFHTTPRequestOperation ()
+@property (readwrite, nonatomic, retain) NSError *HTTPError;
+@end
+
+@implementation AFHTTPRequestOperation
+@synthesize acceptableStatusCodes = _acceptableStatusCodes;
+@synthesize acceptableContentTypes = _acceptableContentTypes;
+@synthesize HTTPError = _HTTPError;
+@synthesize successCallbackQueue = _successCallbackQueue;
+@synthesize failureCallbackQueue = _failureCallbackQueue;
+
+
+- (id)initWithRequest:(NSURLRequest *)request {
+ self = [super initWithRequest:request];
+ if (!self) {
+ return nil;
+ }
+
+ self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
+
+ return self;
+}
+
+- (void)dealloc {
+ [_acceptableStatusCodes release];
+ [_acceptableContentTypes release];
+ [_HTTPError release];
+
+ if (_successCallbackQueue) {
+ dispatch_release(_successCallbackQueue);
+ _successCallbackQueue = NULL;
+ }
+
+ if (_failureCallbackQueue) {
+ dispatch_release(_failureCallbackQueue);
+ _failureCallbackQueue = NULL;
+ }
+
+ [super dealloc];
+}
+
+- (NSHTTPURLResponse *)response {
+ return (NSHTTPURLResponse *)[super response];
+}
+
+- (NSError *)error {
+ if (self.response && !self.HTTPError) {
+ if (![self hasAcceptableStatusCode]) {
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+ [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected status code in (%@), got %d", nil), AFStringFromIndexSet(self.acceptableStatusCodes), [self.response statusCode]] forKey:NSLocalizedDescriptionKey];
+ [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
+
+ self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorBadServerResponse userInfo:userInfo] autorelease];
+ } else if ([self.responseData length] > 0 && ![self hasAcceptableContentType]) { // Don't invalidate content type if there is no content
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+ [userInfo setValue:[NSString stringWithFormat:NSLocalizedString(@"Expected content type %@, got %@", nil), self.acceptableContentTypes, [self.response MIMEType]] forKey:NSLocalizedDescriptionKey];
+ [userInfo setValue:[self.request URL] forKey:NSURLErrorFailingURLErrorKey];
+
+ self.HTTPError = [[[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo] autorelease];
+ }
+ }
+
+ if (self.HTTPError) {
+ return self.HTTPError;
+ } else {
+ return [super error];
+ }
+}
+
+- (BOOL)hasAcceptableStatusCode {
+ return !self.acceptableStatusCodes || [self.acceptableStatusCodes containsIndex:[self.response statusCode]];
+}
+
+- (BOOL)hasAcceptableContentType {
+ return !self.acceptableContentTypes || [self.acceptableContentTypes containsObject:[self.response MIMEType]];
+}
+
+- (void)setSuccessCallbackQueue:(dispatch_queue_t)successCallbackQueue {
+ if (successCallbackQueue != _successCallbackQueue) {
+ if (_successCallbackQueue) {
+ dispatch_release(_successCallbackQueue);
+ }
+
+ if (successCallbackQueue) {
+ dispatch_retain(successCallbackQueue);
+ _successCallbackQueue = successCallbackQueue;
+ }
+ }
+}
+
+- (void)setFailureCallbackQueue:(dispatch_queue_t)failureCallbackQueue {
+ if (failureCallbackQueue != _failureCallbackQueue) {
+ if (_failureCallbackQueue) {
+ dispatch_release(_failureCallbackQueue);
+ }
+
+ if (failureCallbackQueue) {
+ dispatch_retain(failureCallbackQueue);
+ _failureCallbackQueue = failureCallbackQueue;
+ }
+ }
+}
+
+- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
+ failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
+{
+ self.completionBlock = ^ {
+ if ([self isCancelled]) {
+ return;
+ }
+
+ if (self.error) {
+ if (failure) {
+ dispatch_async(self.failureCallbackQueue ? self.failureCallbackQueue : dispatch_get_main_queue(), ^{
+ failure(self, self.error);
+ });
+ }
+ } else {
+ if (success) {
+ dispatch_async(self.successCallbackQueue ? self.successCallbackQueue : dispatch_get_main_queue(), ^{
+ success(self, self.responseString);
+ });
+ }
+ }
+ };
+}
+
+#pragma mark - AFHTTPClientOperation
+
++ (BOOL)canProcessRequest:(NSURLRequest *)request {
+ return YES;
+}
+
+@end
Oops, something went wrong.

0 comments on commit cd4c1de

Please sign in to comment.