#import "JSONHTTPClient.h"
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-/**
- * @discussion Class for working with JSON APIs. It builds upon the JSONHTTPClient class
- * and facilitates making requests to the same web host. Also features helper
- * method for making calls to a JSON RPC service
- */
+DEPRECATED_ATTRIBUTE
@interface JSONAPI : NSObject
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-/** @name Configuring the API */
-/**
- * Sets the API url
- * @param base the API url as a string
- */
-+(void)setAPIBaseURLWithString:(NSString*)base;
-
-/**
- * Sets the default content type for the requests/responses
- * @param ctype The content-type as a string. Some possible types,
- * depending on the service: application/json, text/json, x-application/javascript, etc.
- */
-+(void)setContentType:(NSString*)ctype;
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-/** @name Making GET API requests */
-/**
- * Makes an asynchronious GET request to the API
- * @param path the URL path to add to the base API URL for this HTTP call
- * @param params the variables to pass to the API
- * @param completeBlock a JSONObjectBlock block to execute upon completion
- */
-+(void)getWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock;
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-/** @name Making POST API requests */
-/**
- * Makes a POST request to the API
- * @param path the URL path to add to the base API URL for this HTTP call
- * @param params the variables to pass to the API
- * @param completeBlock a JSONObjectBlock block to execute upon completion
- */
-+(void)postWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock;
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-/** @name JSON RPC methods */
-/**
- * Makes an asynchronious JSON RPC request to the API. Read more: http://www.jsonrpc.org
- * @param method the HTTP method name; GET or POST only
- * @param args the list of arguments to pass to the API
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)rpcWithMethodName:(NSString*)method andArguments:(NSArray*)args completion:(JSONObjectBlock)completeBlock;
-
-/** @name JSON RPC (2.0) request method */
-/**
- * Makes an asynchronious JSON RPC 2.0 request to the API. Read more: http://www.jsonrpc.org
- * @param method the HTTP method name; GET or POST only
- * @param params the params to pass to the API - an NSArray or an NSDictionary,
- * depending whether you're using named or unnamed parameters
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)rpc2WithMethodName:(NSString*)method andParams:(id)params completion:(JSONObjectBlock)completeBlock;
-
-/////////////////////////////////////////////////////////////////////////////////////////////
++ (void)setAPIBaseURLWithString:(NSString *)base DEPRECATED_ATTRIBUTE;
++ (void)setContentType:(NSString *)ctype DEPRECATED_ATTRIBUTE;
++ (void)getWithPath:(NSString *)path andParams:(NSDictionary *)params completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)postWithPath:(NSString *)path andParams:(NSDictionary *)params completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)rpcWithMethodName:(NSString *)method andArguments:(NSArray *)args completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)rpc2WithMethodName:(NSString *)method andParams:(id)params completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
@end
diff --git a/JSONModel/JSONModelNetworking/JSONAPI.m b/JSONModel/JSONModelNetworking/JSONAPI.m
index 212803d7..a7e33262 100644
--- a/JSONModel/JSONModelNetworking/JSONAPI.m
+++ b/JSONModel/JSONModelNetworking/JSONAPI.m
@@ -1,21 +1,13 @@
//
// JSONAPI.m
+// JSONModel
//
-// @version 1.0.2
-// @author Marin Todorov, http://www.touch-code-magazine.com
-//
-
-// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd.
-// This code is distributed under the terms and conditions of the MIT license.
-//
-// 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.
-//
-// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense
#import "JSONAPI.h"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
+
#pragma mark - helper error model class
@interface JSONAPIRPCErrorModel: JSONModel
@property (assign, nonatomic) int code;
@@ -26,6 +18,7 @@ @interface JSONAPIRPCErrorModel: JSONModel
#pragma mark - static variables
static JSONAPI* sharedInstance = nil;
+
static long jsonRpcId = 0;
#pragma mark - JSONAPI() private interface
@@ -64,7 +57,7 @@ +(void)setContentType:(NSString*)ctype
+(void)getWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock
{
NSString* fullURL = [NSString stringWithFormat:@"%@%@", sharedInstance.baseURLString, path];
-
+
[JSONHTTPClient getJSONFromURLWithString: fullURL params:params completion:^(NSDictionary *json, JSONModelError *e) {
completeBlock(json, e);
}];
@@ -74,7 +67,7 @@ +(void)getWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(J
+(void)postWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock
{
NSString* fullURL = [NSString stringWithFormat:@"%@%@", sharedInstance.baseURLString, path];
-
+
[JSONHTTPClient postJSONFromURLWithString: fullURL params:params completion:^(NSDictionary *json, JSONModelError *e) {
completeBlock(json, e);
}];
@@ -83,7 +76,7 @@ +(void)postWithPath:(NSString*)path andParams:(NSDictionary*)params completion:(
#pragma mark - RPC methods
+(void)__rpcRequestWithObject:(id)jsonObject completion:(JSONObjectBlock)completeBlock
{
-
+
NSData* jsonRequestData = [NSJSONSerialization dataWithJSONObject:jsonObject
options:kNilOptions
error:nil];
@@ -111,7 +104,7 @@ +(void)__rpcRequestWithObject:(id)jsonObject completion:(JSONObjectBlock)complet
e = [JSONModelError errorBadResponse];
}
}
-
+
//invoke the callback
completeBlock(result, e);
}
@@ -122,7 +115,7 @@ +(void)rpcWithMethodName:(NSString*)method andArguments:(NSArray*)args completio
{
NSAssert(method, @"No method specified");
if (!args) args = @[];
-
+
[self __rpcRequestWithObject:@{
//rpc 1.0
@"id": @(++jsonRpcId),
@@ -135,7 +128,7 @@ +(void)rpc2WithMethodName:(NSString*)method andParams:(id)params completion:(JSO
{
NSAssert(method, @"No method specified");
if (!params) params = @[];
-
+
[self __rpcRequestWithObject:@{
//rpc 2.0
@"jsonrpc": @"2.0",
diff --git a/JSONModel/JSONModelNetworking/JSONHTTPClient.h b/JSONModel/JSONModelNetworking/JSONHTTPClient.h
index f946c788..0f47cef9 100644
--- a/JSONModel/JSONModelNetworking/JSONHTTPClient.h
+++ b/JSONModel/JSONModelNetworking/JSONHTTPClient.h
@@ -1,184 +1,33 @@
//
// JSONModelHTTPClient.h
+// JSONModel
//
-// @version 1.0.2
-// @author Marin Todorov, http://www.touch-code-magazine.com
-//
-
-// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd.
-// This code is distributed under the terms and conditions of the MIT license.
-//
-// 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.
-//
-// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense
#import "JSONModel.h"
-#pragma mark - definitions
-
-/**
- * HTTP Request methods
- */
-extern NSString* const kHTTPMethodGET;
-extern NSString* const kHTTPMethodPOST;
-
-/**
- * Content-type strings
- */
-extern NSString* const kContentTypeAutomatic;
-extern NSString* const kContentTypeJSON;
-extern NSString* const kContentTypeWWWEncoded;
-
-/**
- * A block type to handle incoming JSON object and an error.
- * You pass it to methods which fetch JSON asynchroniously. When the operation is finished
- * you receive back the fetched JSON (or nil) and an error (or nil)
- *
- * @param json object derived from a JSON string
- * @param err JSONModelError or nil
- */
-typedef void (^JSONObjectBlock)(id json, JSONModelError* err);
+extern NSString *const kHTTPMethodGET DEPRECATED_ATTRIBUTE;
+extern NSString *const kHTTPMethodPOST DEPRECATED_ATTRIBUTE;
+extern NSString *const kContentTypeAutomatic DEPRECATED_ATTRIBUTE;
+extern NSString *const kContentTypeJSON DEPRECATED_ATTRIBUTE;
+extern NSString *const kContentTypeWWWEncoded DEPRECATED_ATTRIBUTE;
-/////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark - configuration methods
+typedef void (^JSONObjectBlock)(id json, JSONModelError *err) DEPRECATED_ATTRIBUTE;
-/**
- * @discussion A very thin HTTP client that can do GET and POST HTTP requests.
- * It fetches only JSON data and also deserializes it using NSJSONSerialization.
- */
+DEPRECATED_ATTRIBUTE
@interface JSONHTTPClient : NSObject
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-
-/** @name HTTP Client configuration */
-/**
- * Returns a modifyable dictionary of the client's default HTTP headers.
- * @result A mutable dictionary of pairs - HTTP header names and values.
- * @discussion You can use the result to modify the http client headers like so:
- *
- * NSMutableDictionary* headers = [JSONHTTPClient requestHeaders];
- * headers[@"APIToken"] = @"MySecretTokenValue";
- *
- */
-+(NSMutableDictionary*)requestHeaders;
-
-/**
- * Sets the default encoding of the request body.
- * See NSStringEncoding for a list of supported encodings
- * @param encoding text encoding constant
- */
-+(void)setDefaultTextEncoding:(NSStringEncoding)encoding;
-
-/**
- * Sets the policies for caching HTTP data
- * See NSURLRequestCachePolicy for a list of the pre-defined policies
- * @param policy the caching policy
- */
-+(void)setCachingPolicy:(NSURLRequestCachePolicy)policy;
-
-/**
- * Sets the timeout for network calls
- * @param seconds the amount of seconds to wait before considering the call failed
- */
-+(void)setTimeoutInSeconds:(int)seconds;
-
-/**
- * A method to enable/disable automatic network indicator showing.
- * Set to YES by default.
- * @param doesControlIndicator if YES, the library shows and hides the
- * system network indicator automatically on begin and end of
- * network operations
- */
-+(void)setControlsNetworkIndicator:(BOOL)doesControlIndicator;
-
-/**
- * A method to set the default conent type of the request body
- * By default the content type is set to kContentTypeAutomatic
- * which checks the body request and decides between "application/json"
- * and "application/x-www-form-urlencoded"
- */
-+(void)setRequestContentType:(NSString*)contentTypeString;
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark - GET asynchronious JSON calls
-
-/** @name Making asynchronious HTTP requests */
-/**
- * Makes GET request to the given URL address and fetches a JSON response.
- * @param urlString the URL as a string
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)getJSONFromURLWithString:(NSString*)urlString completion:(JSONObjectBlock)completeBlock;
-
-/**
- * Makes GET request to the given URL address and fetches a JSON response. Sends the params as a query string variables.
- * @param urlString the URL as a string
- * @param params a dictionary of key / value pairs to be send as variables to the request
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)getJSONFromURLWithString:(NSString*)urlString params:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock;
-
-/**
- * Makes a request to the given URL address and fetches a JSON response.
- * @param urlString the URL as a string
- * @param method the method of the request as a string
- * @param params a dictionary of key / value pairs to be send as variables to the request
- * @param bodyString the body of the POST request as a string
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary*)params orBodyString:(NSString*)bodyString completion:(JSONObjectBlock)completeBlock;
-
-/**
- * Makes a request to the given URL address and fetches a JSON response.
- * @param urlString the URL as a string
- * @param method the method of the request as a string
- * @param params a dictionary of key / value pairs to be send as variables to the request
- * @param bodyString the body of the POST request as a string
- * @param headers the headers to set on the request - overrides those in +requestHeaders
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary*)params orBodyString:(NSString*)bodyString headers:(NSDictionary*)headers completion:(JSONObjectBlock)completeBlock;
-
-/**
- * Makes a request to the given URL address and fetches a JSON response.
- * @param urlString the URL as a string
- * @param method the method of the request as a string
- * @param params a dictionary of key / value pairs to be send as variables to the request
- * @param bodyData the body of the POST request as raw binary data
- * @param headers the headers to set on the request - overrides those in +requestHeaders
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary *)params orBodyData:(NSData*)bodyData headers:(NSDictionary*)headers completion:(JSONObjectBlock)completeBlock;
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark - POST synchronious JSON calls
-
-/**
- * Makes POST request to the given URL address and fetches a JSON response. Sends the bodyString param as the POST request body.
- * @param urlString the URL as a string
- * @param params a dictionary of key / value pairs to be send as variables to the request
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)postJSONFromURLWithString:(NSString*)urlString params:(NSDictionary*)params completion:(JSONObjectBlock)completeBlock;
-
-/**
- * Makes POST request to the given URL address and fetches a JSON response. Sends the bodyString param as the POST request body.
- * @param urlString the URL as a string
- * @param bodyString the body of the POST request as a string
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)postJSONFromURLWithString:(NSString*)urlString bodyString:(NSString*)bodyString completion:(JSONObjectBlock)completeBlock;
-
-/**
- * Makes POST request to the given URL address and fetches a JSON response. Sends the bodyString param as the POST request body.
- * @param urlString the URL as a string
- * @param bodyData the body of the POST request as an NSData object
- * @param completeBlock JSONObjectBlock to execute upon completion
- */
-+(void)postJSONFromURLWithString:(NSString*)urlString bodyData:(NSData*)bodyData completion:(JSONObjectBlock)completeBlock;
-
++ (NSMutableDictionary *)requestHeaders DEPRECATED_ATTRIBUTE;
++ (void)setDefaultTextEncoding:(NSStringEncoding)encoding DEPRECATED_ATTRIBUTE;
++ (void)setCachingPolicy:(NSURLRequestCachePolicy)policy DEPRECATED_ATTRIBUTE;
++ (void)setTimeoutInSeconds:(int)seconds DEPRECATED_ATTRIBUTE;
++ (void)setRequestContentType:(NSString *)contentTypeString DEPRECATED_ATTRIBUTE;
++ (void)getJSONFromURLWithString:(NSString *)urlString completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)getJSONFromURLWithString:(NSString *)urlString params:(NSDictionary *)params completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)JSONFromURLWithString:(NSString *)urlString method:(NSString *)method params:(NSDictionary *)params orBodyString:(NSString *)bodyString completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)JSONFromURLWithString:(NSString *)urlString method:(NSString *)method params:(NSDictionary *)params orBodyString:(NSString *)bodyString headers:(NSDictionary *)headers completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)JSONFromURLWithString:(NSString *)urlString method:(NSString *)method params:(NSDictionary *)params orBodyData:(NSData *)bodyData headers:(NSDictionary *)headers completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)postJSONFromURLWithString:(NSString *)urlString params:(NSDictionary *)params completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)postJSONFromURLWithString:(NSString *)urlString bodyString:(NSString *)bodyString completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)postJSONFromURLWithString:(NSString *)urlString bodyData:(NSData *)bodyData completion:(JSONObjectBlock)completeBlock DEPRECATED_ATTRIBUTE;
@end
diff --git a/JSONModel/JSONModelNetworking/JSONHTTPClient.m b/JSONModel/JSONModelNetworking/JSONHTTPClient.m
index b5e5d263..6c72dc5b 100644
--- a/JSONModel/JSONModelNetworking/JSONHTTPClient.m
+++ b/JSONModel/JSONModelNetworking/JSONHTTPClient.m
@@ -1,21 +1,15 @@
//
// JSONModelHTTPClient.m
+// JSONModel
//
-// @version 1.0.2
-// @author Marin Todorov, http://www.touch-code-magazine.com
-//
-
-// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd.
-// This code is distributed under the terms and conditions of the MIT license.
-//
-// 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.
-//
-// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense
#import "JSONHTTPClient.h"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
+
+typedef void (^RequestResultBlock)(NSData *data, JSONModelError *error);
+
#pragma mark - constants
NSString* const kHTTPMethodGET = @"GET";
NSString* const kHTTPMethodPOST = @"POST";
@@ -34,11 +28,6 @@
static int defaultTimeoutInSeconds = 60;
-/**
- * Whether the iPhone net indicator automatically shows when making requests
- */
-static BOOL doesControlIndicator = YES;
-
/**
* Custom HTTP headers to send over with *each* request
*/
@@ -83,11 +72,6 @@ +(void)setTimeoutInSeconds:(int)seconds
defaultTimeoutInSeconds = seconds;
}
-+(void)setControlsNetworkIndicator:(BOOL)does
-{
- doesControlIndicator = does;
-}
-
+(void)setRequestContentType:(NSString*)contentTypeString
{
requestContentType = contentTypeString;
@@ -105,7 +89,7 @@ +(NSString*)contentTypeForRequestString:(NSString*)requestString
[requestString substringToIndex:1],
[requestString substringFromIndex: requestString.length -1]
];
-
+
if ([firstAndLastChar isEqualToString:@"{}"] || [firstAndLastChar isEqualToString:@"[]"]) {
//guessing for a JSON request
contentType = kContentTypeJSON;
@@ -126,27 +110,31 @@ +(NSString*)urlEncode:(id)value
if ([value isKindOfClass:[NSNumber class]]) {
value = [(NSNumber*)value stringValue];
}
-
+
NSAssert([value isKindOfClass:[NSString class]], @"request parameters can be only of NSString or NSNumber classes. '%@' is of class %@.", value, [value class]);
-
+
+ NSString *str = (NSString *)value;
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9
+ return [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
+
+#else
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
- (__bridge CFStringRef) value,
+ (__bridge CFStringRef)str,
NULL,
(CFStringRef)@"!*'();:@&=+$,/?%#[]",
kCFStringEncodingUTF8));
+#endif
}
#pragma mark - networking worker methods
-+(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method requestBody:(NSData*)bodyData headers:(NSDictionary*)headers etag:(NSString**)etag error:(JSONModelError**)err
++(void)requestDataFromURL:(NSURL*)url method:(NSString*)method requestBody:(NSData*)bodyData headers:(NSDictionary*)headers handler:(RequestResultBlock)handler
{
- //turn on network indicator
- if (doesControlIndicator) dispatch_async(dispatch_get_main_queue(), ^{[self setNetworkIndicatorVisible:YES];});
-
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url
cachePolicy: defaultCachePolicy
timeoutInterval: defaultTimeoutInSeconds];
- [request setHTTPMethod:method];
+ [request setHTTPMethod:method];
if ([requestContentType isEqualToString:kContentTypeAutomatic]) {
//automatic content type
@@ -158,60 +146,69 @@ +(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method requestBod
//user set content type
[request setValue: requestContentType forHTTPHeaderField:@"Content-type"];
}
-
+
//add all the custom headers defined
for (NSString* key in [requestHeaders allKeys]) {
[request setValue:requestHeaders[key] forHTTPHeaderField:key];
}
-
+
//add the custom headers
for (NSString* key in [headers allKeys]) {
[request setValue:headers[key] forHTTPHeaderField:key];
}
-
+
if (bodyData) {
[request setHTTPBody: bodyData];
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)bodyData.length] forHTTPHeaderField:@"Content-Length"];
}
-
- //prepare output
- NSHTTPURLResponse* response = nil;
-
- //fire the request
- NSData *responseData = [NSURLConnection sendSynchronousRequest: request
- returningResponse: &response
- error: err];
- //convert an NSError to a JSONModelError
- if (*err != nil) {
- NSError* errObj = *err;
- *err = [JSONModelError errorWithDomain:errObj.domain code:errObj.code userInfo:errObj.userInfo];
- }
-
- //turn off network indicator
- if (doesControlIndicator) dispatch_async(dispatch_get_main_queue(), ^{[self setNetworkIndicatorVisible:NO];});
-
- //if not OK status set the err to a JSONModelError instance
- if (response.statusCode >= 300 || response.statusCode < 200) {
- //create a new error
- if (*err==nil) *err = [JSONModelError errorBadResponse];
- }
-
- //if there was an error, include the HTTP response and return
- if (*err) {
- //assign the response to the JSONModel instance
- [*err setHttpResponse: [response copy]];
+
+ void (^completionHandler)(NSData *, NSURLResponse *, NSError *) = ^(NSData *data, NSURLResponse *origResponse, NSError *origError) {
+ NSHTTPURLResponse *response = (NSHTTPURLResponse *)origResponse;
+ JSONModelError *error = nil;
+
+ //convert an NSError to a JSONModelError
+ if (origError) {
+ error = [JSONModelError errorWithDomain:origError.domain code:origError.code userInfo:origError.userInfo];
+ }
+
+ //special case for http error code 401
+ if (error.code == NSURLErrorUserCancelledAuthentication) {
+ response = [[NSHTTPURLResponse alloc] initWithURL:url statusCode:401 HTTPVersion:@"HTTP/1.1" headerFields:@{}];
+ }
+
+ //if not OK status set the err to a JSONModelError instance
+ if (!error && (response.statusCode >= 300 || response.statusCode < 200)) {
+ error = [JSONModelError errorBadResponse];
+ }
+
+ //if there was an error, assign the response to the JSONModel instance
+ if (error) {
+ error.httpResponse = [response copy];
+ }
//empty respone, return nil instead
- if ([responseData length]<1) {
- return nil;
+ if (!data.length) {
+ data = nil;
}
- }
-
- //return the data fetched from web
- return responseData;
+
+ handler(data, error);
+ };
+
+ //fire the request
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_10
+ NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:completionHandler];
+ [task resume];
+#else
+ NSOperationQueue *queue = [NSOperationQueue new];
+
+ [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
+ completionHandler(data, response, error);
+ }];
+#endif
}
-+(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method params:(NSDictionary*)params headers:(NSDictionary*)headers etag:(NSString**)etag error:(JSONModelError**)err
++(void)requestDataFromURL:(NSURL*)url method:(NSString*)method params:(NSDictionary*)params headers:(NSDictionary*)headers handler:(RequestResultBlock)handler
{
//create the request body
NSMutableString* paramsString = nil;
@@ -226,7 +223,7 @@ +(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method params:(NS
paramsString = [[NSMutableString alloc] initWithString: [paramsString substringToIndex: paramsString.length-1]];
}
}
-
+
//set the request params
if ([method isEqualToString:kHTTPMethodGET] && params) {
@@ -237,14 +234,13 @@ +(NSData*)syncRequestDataFromURL:(NSURL*)url method:(NSString*)method params:(NS
paramsString
]];
}
-
+
//call the more general synq request method
- return [self syncRequestDataFromURL: url
- method: method
- requestBody: [method isEqualToString:kHTTPMethodPOST]?[paramsString dataUsingEncoding:NSUTF8StringEncoding]:nil
- headers: headers
- etag: etag
- error: err];
+ [self requestDataFromURL: url
+ method: method
+ requestBody: [method isEqualToString:kHTTPMethodPOST]?[paramsString dataUsingEncoding:NSUTF8StringEncoding]:nil
+ headers: headers
+ handler:handler];
}
#pragma mark - Async network request
@@ -270,65 +266,48 @@ +(void)JSONFromURLWithString:(NSString *)urlString method:(NSString *)method par
+(void)JSONFromURLWithString:(NSString*)urlString method:(NSString*)method params:(NSDictionary *)params orBodyData:(NSData*)bodyData headers:(NSDictionary*)headers completion:(JSONObjectBlock)completeBlock
{
- NSDictionary* customHeaders = headers;
-
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
-
+ RequestResultBlock handler = ^(NSData *responseData, JSONModelError *error) {
id jsonObject = nil;
- JSONModelError* error = nil;
- NSData* responseData = nil;
- NSString* etag = nil;
-
- @try {
- if (bodyData) {
- responseData = [self syncRequestDataFromURL: [NSURL URLWithString:urlString]
- method: method
- requestBody: bodyData
- headers: customHeaders
- etag: &etag
- error: &error];
- } else {
- responseData = [self syncRequestDataFromURL: [NSURL URLWithString:urlString]
- method: method
- params: params
- headers: customHeaders
- etag: &etag
- error: &error];
- }
- }
- @catch (NSException *exception) {
- error = [JSONModelError errorBadResponse];
- }
-
+
//step 3: if there's no response so far, return a basic error
- if (!responseData && !jsonObject) {
+ if (!responseData && !error) {
//check for false response, but no network error
error = [JSONModelError errorBadResponse];
}
//step 4: if there's a response at this and no errors, convert to object
- if (error==nil && jsonObject==nil) {
- // Note: it is possible to have a valid response with empty response data (204 No Content).
- // So only create the JSON object if there is some response data.
- if(responseData.length > 0)
- {
- //convert to an object
- jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
- }
+ if (error==nil) {
+ // Note: it is possible to have a valid response with empty response data (204 No Content).
+ // So only create the JSON object if there is some response data.
+ if(responseData.length > 0)
+ {
+ //convert to an object
+ jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
+ }
}
//step 4.5: cover an edge case in which meaningful content is return along an error HTTP status code
else if (error && responseData && jsonObject==nil) {
- //try to get the JSON object, while preserving the origianl error object
+ //try to get the JSON object, while preserving the original error object
jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
+ //keep responseData just in case it contains error information
+ error.responseData = responseData;
}
-
+
//step 5: invoke the complete block
dispatch_async(dispatch_get_main_queue(), ^{
if (completeBlock) {
completeBlock(jsonObject, error);
}
});
- });
+ };
+
+ NSURL *url = [NSURL URLWithString:urlString];
+
+ if (bodyData) {
+ [self requestDataFromURL:url method:method requestBody:bodyData headers:headers handler:handler];
+ } else {
+ [self requestDataFromURL:url method:method params:params headers:headers handler:handler];
+ }
}
#pragma mark - request aliases
@@ -379,12 +358,4 @@ +(void)postJSONFromURLWithString:(NSString*)urlString bodyData:(NSData*)bodyData
}];
}
-#pragma mark - iOS UI helper
-+(void)setNetworkIndicatorVisible:(BOOL)isVisible
-{
-#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
- [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:isVisible];
-#endif
-}
-
@end
diff --git a/JSONModel/JSONModelNetworking/JSONModel+networking.h b/JSONModel/JSONModelNetworking/JSONModel+networking.h
index 88e329ef..444f26d9 100644
--- a/JSONModel/JSONModelNetworking/JSONModel+networking.h
+++ b/JSONModel/JSONModelNetworking/JSONModel+networking.h
@@ -1,66 +1,18 @@
//
// JSONModel+networking.h
+// JSONModel
//
-// @version 1.0.2
-// @author Marin Todorov, http://www.touch-code-magazine.com
-//
-
-// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd.
-// This code is distributed under the terms and conditions of the MIT license.
-//
-// 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.
-//
-// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense
#import "JSONModel.h"
#import "JSONHTTPClient.h"
-typedef void (^JSONModelBlock)(id model, JSONModelError* err);
-
-/**
- * The JSONModel(networking) class category adds networking to JSONModel.
- * It adds initFromURLWithString: initializer, which makes a GET http request
- * to the URL given and initializes the model with the returned JSON.
- * Use #import "JSONModel+networking.h" to import networking capabilities.
- */
-@interface JSONModel(Networking)
-
-@property (assign, nonatomic) BOOL isLoading;
-/** @name Asynchroniously create a model over the network */
-/**
- * Asynchroniously create a model over the network. Create a new model instance and initialize it with the JSON fetched from the given URL
- * @param urlString the absolute URL address of the JSON feed as a string
- * @param completeBlock JSONModelBlock executed upon completion. The JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* e); the first parameter is the initialized model or nil,
- * and second parameter holds the model initialization error, if any
- */
--(instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock;
-
-/**
- * Asynchronously gets the contents of a URL and constructs a JSONModel object from the response.
- * The constructed JSONModel object passed as the first parameter to the completion block will be of the same
- * class as the receiver. So call this method on yourJSONModel sub-class rather than directly on JSONModel.
- * @param urlString The absolute URL of the JSON resource, as a string
- * @param completeBlock The block to be called upon completion.
- * JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* err);
- * The first parameter is the initialized model (of the same JSONModel sub-class as the receiver) or nil if there was an error;
- * The second parameter is the initialization error, if any.
- */
-+ (void)getModelFromURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock;
+typedef void (^JSONModelBlock)(id model, JSONModelError *err) DEPRECATED_ATTRIBUTE;
-/**
- * Asynchronously posts a JSONModel object (as JSON) to a URL and constructs a JSONModel object from the response.
- * The constructed JSONModel object passed as the first parameter to the completion block will be of the same
- * class as the receiver. So call this method on yourJSONModel sub-class rather than directly on JSONModel.
- * @param post A JSONModel object that will be converted to JSON and sent as the POST data to the HTTP request.
- * @param urlString The absolute URL of the JSON resource, as a string
- * @param completeBlock The block to be called upon completion.
- * JSONModelBlock type is defined as: void (^JSONModelBlock)(JSONModel* model, JSONModelError* err);
- * The first parameter is the initialized model (of the same JSONModel sub-class as the receiver) or nil if there was an error;
- * The second parameter is the initialization error, if any.
- */
-+ (void)postModel:(JSONModel*)post toURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock;
+@interface JSONModel (Networking)
+@property (assign, nonatomic) BOOL isLoading DEPRECATED_ATTRIBUTE;
+- (instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)getModelFromURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock DEPRECATED_ATTRIBUTE;
++ (void)postModel:(JSONModel *)post toURLWithString:(NSString *)urlString completion:(JSONModelBlock)completeBlock DEPRECATED_ATTRIBUTE;
@end
diff --git a/JSONModel/JSONModelNetworking/JSONModel+networking.m b/JSONModel/JSONModelNetworking/JSONModel+networking.m
index 7d4d1ff3..b3e0aa42 100644
--- a/JSONModel/JSONModelNetworking/JSONModel+networking.m
+++ b/JSONModel/JSONModelNetworking/JSONModel+networking.m
@@ -1,22 +1,14 @@
//
// JSONModel+networking.m
+// JSONModel
//
-// @version 1.0.2
-// @author Marin Todorov, http://www.touch-code-magazine.com
-//
-
-// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd.
-// This code is distributed under the terms and conditions of the MIT license.
-//
-// 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.
-//
-// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense
#import "JSONModel+networking.h"
#import "JSONHTTPClient.h"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#pragma GCC diagnostic ignored "-Wdeprecated-implementations"
+
BOOL _isLoading;
@implementation JSONModel(Networking)
@@ -37,25 +29,25 @@ -(instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModel
{
id placeholder = [super init];
__block id blockSelf = self;
-
+
if (placeholder) {
//initialization
self.isLoading = YES;
-
+
[JSONHTTPClient getJSONFromURLWithString:urlString
completion:^(NSDictionary *json, JSONModelError* e) {
-
+
JSONModelError* initError = nil;
blockSelf = [self initWithDictionary:json error:&initError];
-
+
if (completeBlock) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
completeBlock(blockSelf, e?e:initError );
});
}
-
+
self.isLoading = NO;
-
+
}];
}
return placeholder;
@@ -63,47 +55,47 @@ -(instancetype)initFromURLWithString:(NSString *)urlString completion:(JSONModel
+ (void)getModelFromURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock
{
- [JSONHTTPClient getJSONFromURLWithString:urlString
- completion:^(NSDictionary* jsonDict, JSONModelError* err)
- {
- JSONModel* model = nil;
-
- if(err == nil)
- {
- model = [[self alloc] initWithDictionary:jsonDict error:&err];
- }
-
- if(completeBlock != nil)
- {
- dispatch_async(dispatch_get_main_queue(), ^
- {
- completeBlock(model, err);
- });
- }
+ [JSONHTTPClient getJSONFromURLWithString:urlString
+ completion:^(NSDictionary* jsonDict, JSONModelError* err)
+ {
+ JSONModel* model = nil;
+
+ if(err == nil)
+ {
+ model = [[self alloc] initWithDictionary:jsonDict error:&err];
+ }
+
+ if(completeBlock != nil)
+ {
+ dispatch_async(dispatch_get_main_queue(), ^
+ {
+ completeBlock(model, err);
+ });
+ }
}];
}
+ (void)postModel:(JSONModel*)post toURLWithString:(NSString*)urlString completion:(JSONModelBlock)completeBlock
{
- [JSONHTTPClient postJSONFromURLWithString:urlString
- bodyString:[post toJSONString]
- completion:^(NSDictionary* jsonDict, JSONModelError* err)
- {
- JSONModel* model = nil;
-
- if(err == nil)
- {
- model = [[self alloc] initWithDictionary:jsonDict error:&err];
- }
-
- if(completeBlock != nil)
- {
- dispatch_async(dispatch_get_main_queue(), ^
- {
- completeBlock(model, err);
- });
- }
- }];
+ [JSONHTTPClient postJSONFromURLWithString:urlString
+ bodyString:[post toJSONString]
+ completion:^(NSDictionary* jsonDict, JSONModelError* err)
+ {
+ JSONModel* model = nil;
+
+ if(err == nil)
+ {
+ model = [[self alloc] initWithDictionary:jsonDict error:&err];
+ }
+
+ if(completeBlock != nil)
+ {
+ dispatch_async(dispatch_get_main_queue(), ^
+ {
+ completeBlock(model, err);
+ });
+ }
+ }];
}
@end
diff --git a/JSONModel/JSONModelTransformations/JSONKeyMapper.h b/JSONModel/JSONModelTransformations/JSONKeyMapper.h
index 75822c6e..61ea929f 100644
--- a/JSONModel/JSONModelTransformations/JSONKeyMapper.h
+++ b/JSONModel/JSONModelTransformations/JSONKeyMapper.h
@@ -1,26 +1,15 @@
//
// JSONKeyMapper.h
+// JSONModel
//
-// @version 1.0.2
-// @author Marin Todorov, http://www.touch-code-magazine.com
-//
-
-// Copyright (c) 2012-2014 Marin Todorov, Underplot ltd.
-// This code is distributed under the terms and conditions of the MIT license.
-//
-// 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.
-//
-// The MIT License in plain English: http://www.touch-code-magazine.com/JSONModel/MITLicense
#import