-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow chaining response processors, and add a new AEExpect module to …
…let you create some common blocks for response validity checking.
- Loading branch information
1 parent
5b702b1
commit b989dca
Showing
11 changed files
with
270 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// AEExpect.h | ||
// AEURLExample | ||
// | ||
// Created by Adam Ernst on 10/13/11. | ||
// Copyright (c) 2011 cosmicsoft. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
#import "AEURLConnection.h" | ||
|
||
extern NSString *AEExpectErrorDomain; | ||
|
||
typedef enum { | ||
AEExpectInvalidStatusCodeError = -101, | ||
AEExpectResponseNotHTTPError = -102, | ||
AEExpectInvalidContentTypeError = -103, | ||
AEExpectInvalidResponseClassError = -104, | ||
} AEExpectErrorCode; | ||
|
||
@interface AEExpect : NSObject | ||
|
||
// Sets an error if the HTTP status code is not in the provided set. | ||
+ (AEURLResponseProcessor)statusCode:(NSIndexSet *)acceptableCodes; | ||
|
||
// All 200 status codes | ||
+ (NSIndexSet *)defaultAcceptableStatusCodes; | ||
|
||
// Sets an error if the Content-Type header does not match one of the included | ||
// acceptable content types, after removing any "charset" or other parameters. | ||
// See [AEJSONProcessor defaultAcceptableJSONContentTypes] for an example set. | ||
+ (AEURLResponseProcessor)contentType:(NSSet *)acceptableTypes; | ||
|
||
// Sets an error if the passed data is not an instance of a certain class. | ||
// Handy for use after an AEJSONProcessor, if you want to ensure that | ||
// you're getting a dictionary vs. an array. | ||
+ (AEURLResponseProcessor)responseClass:(Class)class; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// | ||
// AEExpect.m | ||
// AEURLExample | ||
// | ||
// Created by Adam Ernst on 10/13/11. | ||
// Copyright (c) 2011 cosmicsoft. All rights reserved. | ||
// | ||
|
||
#import "AEExpect.h" | ||
|
||
NSString *AEExpectErrorDomain = @"AEExpectErrorDomain"; | ||
|
||
@implementation AEExpect | ||
|
||
+ (NSError *)error:(AEExpectErrorCode)code message:(NSString *)message { | ||
return [NSError errorWithDomain:AEExpectErrorDomain | ||
code:code | ||
userInfo:[NSDictionary dictionaryWithObject:message | ||
forKey:NSLocalizedDescriptionKey]]; | ||
} | ||
|
||
+ (AEURLResponseProcessor)statusCode:(NSIndexSet *)acceptableCodes { | ||
return [[^(NSURLResponse *response, id data, NSError **error){ | ||
if (![response isKindOfClass:[NSHTTPURLResponse class]]) { | ||
*error = [AEExpect error:AEExpectResponseNotHTTPError | ||
message:@"Response is not HTTP"]; | ||
return nil; | ||
} | ||
|
||
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode]; | ||
if (![acceptableCodes containsIndex:statusCode]) { | ||
*error = [AEExpect error:AEExpectInvalidStatusCodeError | ||
message:[NSString stringWithFormat:@"%@ (HTTP status %d)", | ||
[NSHTTPURLResponse localizedStringForStatusCode:statusCode], | ||
statusCode]]; | ||
return nil; | ||
} | ||
|
||
return data; | ||
} copy] autorelease]; | ||
} | ||
|
||
+ (NSIndexSet *)defaultAcceptableStatusCodes { | ||
return [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)]; | ||
} | ||
|
||
// Sets an error if the Content-Type header does not match one of the included | ||
// acceptable content types, after removing any "charset" or other parameters. | ||
+ (AEURLResponseProcessor)contentType:(NSSet *)acceptableTypes { | ||
return [[^(NSURLResponse *response, id data, NSError **error) { | ||
if (![acceptableTypes containsObject:[response MIMEType]]) { | ||
*error = [AEExpect error:AEExpectInvalidContentTypeError | ||
message:[NSString stringWithFormat:@"Invalid Content-Type %@", [response MIMEType]]]; | ||
return nil; | ||
} | ||
|
||
return data; | ||
} copy] autorelease]; | ||
} | ||
|
||
// Sets an error if the passed data is not an instance of a certain class. | ||
// Handy for use after an AEJSONProcessor, if you want to ensure that | ||
// you're getting a dictionary vs. an array. | ||
+ (AEURLResponseProcessor)responseClass:(Class)class { | ||
return [[^(NSURLResponse *response, id data, NSError **error) { | ||
if (![data isKindOfClass:class]) { | ||
*error = [AEExpect error:AEExpectInvalidResponseClassError | ||
message:[NSString stringWithFormat:@"Invalid response class %@", NSStringFromClass([data class])]]; | ||
return nil; | ||
} | ||
|
||
return data; | ||
} copy] autorelease]; | ||
} | ||
|
||
@end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// | ||
// AEJSONProcessor.h | ||
// AEURLExample | ||
// | ||
// Created by Adam Ernst on 10/13/11. | ||
// Copyright (c) 2011 cosmicsoft. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
#import "AEURLConnection.h" | ||
#import "AEURLRequestFactory.h" | ||
|
||
// AEJSONProcessor requires JSONKit. You can use AEURLConnection | ||
// without JSONKit; just remove the AEJSONProcessor.m/h files from your | ||
// project, and parse JSON manually. | ||
#import "JSONKit.h" | ||
|
||
|
||
@interface AEJSONProcessor : NSObject | ||
|
||
// These blocks are used to process a response from the server. | ||
+ (AEURLResponseProcessor)JSONResponseProcessor; | ||
+ (AEURLResponseProcessor)JSONResponseProcessorWithOptions:(JKParseOptionFlags)options; | ||
|
||
// This block will put parameters into a NSMutableURLRequest's HTTP body, | ||
// encoded as JSON, and set the request's Content-Type header to | ||
// "application/json; charset=UTF-8". | ||
+ (AEURLParameterProcessor)JSONParameterProcessor; | ||
|
||
// A set with the most common Content-Types for JSON. Handy with the | ||
// [AEExpect contentType:] response processor, when used in a chain. | ||
+ (NSSet *)defaultAcceptableJSONContentTypes; | ||
|
||
@end |
22 changes: 13 additions & 9 deletions
22
AEURLConnection/AEJSONProcessingBlock.m → AEURLConnection/AEJSONProcessor.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,40 @@ | ||
// | ||
// AEJSONProcessingBlock.m | ||
// AEJSONProcessor.m | ||
// AEURLExample | ||
// | ||
// Created by Adam Ernst on 10/13/11. | ||
// Copyright (c) 2011 cosmicsoft. All rights reserved. | ||
// | ||
|
||
#import "AEJSONProcessingBlock.h" | ||
#import "AEJSONProcessor.h" | ||
|
||
@implementation AEJSONProcessingBlock | ||
@implementation AEJSONProcessor | ||
|
||
static AEURLConnectionResponseProcessingBlock JSONProcessingBlock = nil; | ||
static AEURLResponseProcessor JSONProcessor = nil; | ||
|
||
+ (AEURLConnectionResponseProcessingBlock)JSONResponseProcessingBlock { | ||
+ (AEURLResponseProcessor)JSONResponseProcessor { | ||
static dispatch_once_t onceToken; | ||
dispatch_once(&onceToken, ^{ | ||
JSONProcessingBlock = [[self JSONResponseProcessingBlockWithOptions:JKParseOptionNone] retain]; | ||
JSONProcessor = [[self JSONResponseProcessorWithOptions:JKParseOptionNone] retain]; | ||
}); | ||
return JSONProcessingBlock; | ||
return JSONProcessor; | ||
} | ||
|
||
+ (AEURLConnectionResponseProcessingBlock)JSONResponseProcessingBlockWithOptions:(JKParseOptionFlags)options { | ||
+ (AEURLResponseProcessor)JSONResponseProcessorWithOptions:(JKParseOptionFlags)options { | ||
return [[(id)^(NSURLResponse *response, NSData *data, NSError **error){ | ||
return [data objectFromJSONDataWithParseOptions:options error:error]; | ||
} copy] autorelease]; | ||
} | ||
|
||
+ (AEURLConnectionParameterProcessingBlock)JSONParameterProcessingBlock { | ||
+ (AEURLParameterProcessor)JSONParameterProcessor { | ||
return [[^(NSDictionary *parameters, NSMutableURLRequest *targetRequest){ | ||
[targetRequest setHTTPBody:[parameters JSONData]]; | ||
[targetRequest setValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; | ||
} copy] autorelease]; | ||
} | ||
|
||
+ (NSSet *)defaultAcceptableJSONContentTypes { | ||
return [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil]; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.