-
-
Save khanlou/e4d24affadbf6694391c to your computer and use it in GitHub Desktop.
Requests
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
@interface SKRequestBuilder () | |
@property (nonatomic) SKSafeRequestTemplate *safeTemplate; | |
@end | |
@implementation SKRequestBuilder | |
- (instancetype)initWithRequestTemplate:(id<SKRequestTemplate>)template { | |
self = [super init]; | |
if (!self) return nil; | |
_safeTemplate = [[SKSafeRequestTemplate alloc] initWithTemplate:template]; | |
return self; | |
} | |
- (id<SKRequestTemplate>)template { | |
return self.safeTemplate.unsafeTemplate; | |
} | |
- (NSData *)HTTPBody { | |
if (!self.safeTemplate.parameters || self.safeTemplate.isGETRequest) { | |
return nil; | |
} | |
return [NSJSONSerialization dataWithJSONObject:self.safeTemplate.parameters options:0 error:nil]; | |
} | |
- (NSURL *)URL { | |
NSURLComponents *URLComponents = [NSURLComponents componentsWithURL:self.safeTemplate.baseURL resolvingAgainstBaseURL:YES]; | |
NSString *path = [URLComponents.path stringByAppendingString:self.safeTemplate.path]; | |
URLComponents.path = path; | |
if (self.safeTemplate.isGETRequest) { | |
URLComponents.queryItems = [[self parametersAsQueryItems] arrayByAddingObjectsFromArray:URLComponents.queryItems]; | |
} | |
return URLComponents.URL; | |
} | |
- (NSArray *)parametersAsQueryItems { | |
NSMutableArray *queryItems = [NSMutableArray array]; | |
[self.safeTemplate.parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { | |
[queryItems addObject:[NSURLQueryItem queryItemWithName:key value:obj]]; | |
}]; | |
return queryItems; | |
} | |
- (NSURLRequest *)URLRequest { | |
NSMutableURLRequest *mutableURLRequest = [[NSMutableURLRequest alloc] init]; | |
mutableURLRequest.HTTPMethod = self.safeTemplate.method; | |
mutableURLRequest.HTTPBody = [self HTTPBody]; | |
mutableURLRequest.URL = [self URL]; | |
[self.safeTemplate.headers enumerateKeysAndObjectsUsingBlock:^(NSString *fieldName, NSString *value, BOOL *stop) { | |
[mutableURLRequest addValue:value forHTTPHeaderField:fieldName]; | |
}]; | |
return [mutableURLRequest copy]; | |
} | |
@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
@protocol SKRequestTemplate <NSObject> | |
@property (readonly) NSURL *baseURL; | |
@optional | |
@property (readonly) NSString *method; | |
@property (readonly) NSString *path; | |
@property (readonly) NSDictionary *parameters; | |
@property (readonly) NSDictionary *headers; | |
- (void)finalizeWithResponse:(SKResponseHandler *)response; | |
@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
@interface SKResponseHandler () | |
@end | |
@implementation SKResponseHandler | |
- (instancetype)initWithResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *)error { | |
self = [super init]; | |
if (!self) return nil; | |
_response = response; | |
_data = data; | |
_error = error; | |
_result = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:nil]; | |
return self; | |
} | |
- (NSHTTPURLResponse *)HTTPResponse { | |
if ([self.response isKindOfClass:[NSHTTPURLResponse class]]) { | |
return (NSHTTPURLResponse *)self.response; | |
} | |
return nil; | |
} | |
- (NSInteger)statusCode { | |
return self.HTTPResponse.statusCode; | |
} | |
@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
@implementation SKSafeRequestTemplate | |
- (instancetype)initWithTemplate:(id<SKRequestTemplate>)template { | |
self = [super init]; | |
if (!self) return nil; | |
_unsafeTemplate = template; | |
return self; | |
} | |
- (NSString *)method { | |
if ([self.unsafeTemplate respondsToSelector:@selector(method)]) { | |
return [self.unsafeTemplate method]; | |
} | |
return @"GET"; | |
} | |
- (BOOL)isGETRequest { | |
return [self.method isEqualToString:@"GET"]; | |
} | |
- (NSURL *)baseURL { | |
if ([self.unsafeTemplate respondsToSelector:@selector(baseURL)]) { | |
return [self.unsafeTemplate baseURL]; | |
} | |
return nil; | |
} | |
- (NSString *)path { | |
if ([self.unsafeTemplate respondsToSelector:@selector(path)]) { | |
return [self.unsafeTemplate path]; | |
} | |
return nil; | |
} | |
- (NSDictionary *)parameters { | |
if ([self.unsafeTemplate respondsToSelector:@selector(parameters)]) { | |
return [self.unsafeTemplate parameters]; | |
} | |
return nil; | |
} | |
- (NSDictionary *)headers { | |
if ([self.unsafeTemplate respondsToSelector:@selector(headers)]) { | |
return [self.unsafeTemplate headers]; | |
} | |
return nil; | |
} | |
- (void)finalizeWithResponse:(id<SKResponse>)response { | |
if ([self.unsafeTemplate respondsToSelector:@selector(finalizeWithResponse:)]) { | |
[self.unsafeTemplate finalizeWithResponse:response]; | |
} | |
} | |
@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
@interface SKSendableRequest () | |
@property (nonatomic) SKRequestBuilder *requestBuilder; | |
@end | |
@implementation SKSendableRequest | |
- (instancetype)initWithRequestTemplate:(id<SKRequestTemplate>)template { | |
self = [super init]; | |
if (!self) return nil; | |
_requestBuilder = [[SKRequestBuilder alloc] initWithRequestTemplate:template]; | |
return self; | |
} | |
- (id<BAKRequestTemplate>)template { | |
return self.requestBuilder.template; | |
} | |
- (BAKSafeRequestTemplate *)safeTemplate { | |
return self.requestBuilder.safeTemplate; | |
} | |
- (void)sendRequestWithSuccessBlock:(void (^)(id result))successBlock failureBlock:(void (^)(NSError *error))failureBlock { | |
[[[NSURLSession sharedSession] dataTaskWithRequest:self.requestBuilder.URLRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { | |
dispatch_async(dispatch_get_main_queue(), ^{ | |
BAKResponseHandler *responseHandler = [[BAKResponseHandler alloc] initWithResponse:response data:data error:error]; | |
[self.safeTemplate finalizeWithResponse:responseHandler]; | |
if (error || responseHandler.error) { | |
if (failureBlock) { | |
failureBlock(responseHandler.error); | |
} | |
} else { | |
if (successBlock) { | |
successBlock(responseHandler.result); | |
} | |
} | |
}); | |
}] resume]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the great blog post. But finally, it seems you choose the "One object per request", which is to instantiate the object, make request, and wait for result in the completion block