From 283d9cffea95afe99069ab3d8ead7f8082b39f70 Mon Sep 17 00:00:00 2001 From: Mattt Thompson Date: Mon, 24 Oct 2011 10:49:25 -0500 Subject: [PATCH] Initial implementation of decoupling specific JSON libraries from AFNetworking, in favor of being able to specify which one to use --- AFNetworking/AFHTTPClient.m | 23 ++--- AFNetworking/AFJSONRequestOperation.m | 16 +--- AFNetworking/AFJSONUtilities.h | 92 +++++++++++++++++++ .../project.pbxproj | 2 + .../project.pbxproj | 2 + 5 files changed, 104 insertions(+), 31 deletions(-) create mode 100644 AFNetworking/AFJSONUtilities.h diff --git a/AFNetworking/AFHTTPClient.m b/AFNetworking/AFHTTPClient.m index d670b8f..b31aa04 100644 --- a/AFNetworking/AFHTTPClient.m +++ b/AFNetworking/AFHTTPClient.m @@ -24,6 +24,7 @@ #import "AFHTTPClient.h" #import "AFHTTPRequestOperation.h" +#import "AFJSONUtilities.h" #import @@ -31,8 +32,6 @@ #import #endif -#import "JSONKit.h" - static NSString * const kAFMultipartFormLineDelimiter = @"\r\n"; // CRLF static NSString * const kAFMultipartFormBoundary = @"Boundary+0xAbCdEfGbOuNdArY"; @@ -108,23 +107,13 @@ static NSString * AFQueryStringFromParameters(NSDictionary *parameters) { } static NSString * AFJSONStringFromParameters(NSDictionary *parameters) { - NSString *JSONString = nil; - -#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_4_3 || __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_6 - if ([NSJSONSerialization class]) { - NSError *error = nil; - NSData *JSONData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]; - if (!error) { - JSONString = [[[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding] autorelease]; - } + NSError *error = nil; + NSData *JSONData = AFJSONEncode(parameters, &error); + if (!error) { + return [[[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding] autorelease]; } else { - JSONString = [parameters JSONString]; + return nil; } -#else - JSONString = [parameters JSONString]; -#endif - - return JSONString; } static NSString * AFPropertyListStringFromParameters(NSDictionary *parameters) { diff --git a/AFNetworking/AFJSONRequestOperation.m b/AFNetworking/AFJSONRequestOperation.m index 16d1465..908fba5 100644 --- a/AFNetworking/AFJSONRequestOperation.m +++ b/AFNetworking/AFJSONRequestOperation.m @@ -21,10 +21,7 @@ // THE SOFTWARE. #import "AFJSONRequestOperation.h" - -#include - -#import "JSONKit.h" +#import "AFJSONUtilities.h" static dispatch_queue_t af_json_request_operation_processing_queue; static dispatch_queue_t json_request_operation_processing_queue() { @@ -117,16 +114,7 @@ static dispatch_queue_t json_request_operation_processing_queue() { if ([self.responseData length] == 0) { self.responseJSON = nil; } else { - -#if __IPHONE_OS_VERSION_MIN_REQUIRED > __IPHONE_4_3 || __MAC_OS_X_VERSION_MIN_REQUIRED > __MAC_10_6 - if ([NSJSONSerialization class]) { - self.responseJSON = [NSJSONSerialization JSONObjectWithData:self.responseData options:0 error:&error]; - } else { - self.responseJSON = [[JSONDecoder decoder] objectWithData:self.responseData error:&error]; - } -#else - self.responseJSON = [[JSONDecoder decoder] objectWithData:self.responseData error:&error]; -#endif + self.responseJSON = AFJSONDecode(self.responseData, &error); } self.JSONError = error; diff --git a/AFNetworking/AFJSONUtilities.h b/AFNetworking/AFJSONUtilities.h new file mode 100644 index 0000000..0ffb519 --- /dev/null +++ b/AFNetworking/AFJSONUtilities.h @@ -0,0 +1,92 @@ +// AFJSONUtilities.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 + +#include + +#if defined(_AF_USE_JSONKIT) +#import "JSONKit.h" +#elif defined(_AF_USE_SBJSON) +#import "SBJSON.h" + +static SBJsonParser * _SBJSONParser() { + static SBJsonParser *_af_SBJSONParser = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_SBJSONParser = [[SBJsonParser alloc] init]; + }); + + return _af_SBJSONParser; +} + +static SBJsonWriter * _SBJSONWriter() { + static SBJsonWriter *_af_SBJSONWriter = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_SBJSONWriter = [[SBJsonWriter alloc] init]; + }); + + return _af_SBJSONWriter; +} +#elif defined(_AF_USE_YAJL) + #if __IPHONE_OS_VERSION_MIN_REQUIRED + #import + #elif __MAC_OS_X_VERSION_MIN_REQUIRED + #import + #endif +#endif + +static inline NSData * AFJSONEncode(id object, NSError **error) { +#if defined(_AF_USE_JSONKIT) + return [object JSONData]; +#elif defined(_AF_USE_SBJSON) + SBJsonWriter *writer = _SBJSONWriter(); + return [writer dataWithObject:object]; +#elif defined(_AF_USE_YAJL) + return [[object yajl_JSONString] dataUsingEncoding:NSUTF8StringEncoding]]; +#else + if ([NSJSONSerialization class]) { + return [NSJSONSerialization dataWithJSONObject:object options:0 error:error]; + } +#endif + + return nil; +} + +static inline id AFJSONDecode(NSData *data, NSError **error) { + +#if defined(_AF_USE_JSONKIT) + return [[JSONDecoder decoder] objectWithData:data error:error]; +#elif defined(_AF_USE_SBJSON) + SBJsonParser *parser = _SBJsonParser(); + return [parser objectWithData:data]; +#elif defined(_AF_USE_YAJL) + return [data yajl_JSON]; +#else + if ([NSJSONSerialization class]) { + return [NSJSONSerialization JSONObjectWithData:data options:0 error:error]; + } +#endif + + return nil; +} diff --git a/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj b/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj index 4074804..bd4688d 100644 --- a/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj +++ b/Mac Example/AFNetworking Mac Example.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + F8323C901455B4FE00190CCB /* AFJSONUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFJSONUtilities.h; sourceTree = ""; }; F87A159D1444926300318955 /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFURLConnectionOperation.h; sourceTree = ""; }; F87A159E1444926300318955 /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFURLConnectionOperation.m; sourceTree = ""; }; F87A15A01444926900318955 /* AFXMLRequestOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFXMLRequestOperation.h; sourceTree = ""; }; @@ -140,6 +141,7 @@ F897DE70142CFEDC000DDD35 /* AFImageRequestOperation.m */, F897DE6D142CFEDC000DDD35 /* AFImageCache.h */, F897DE6E142CFEDC000DDD35 /* AFImageCache.m */, + F8323C901455B4FE00190CCB /* AFJSONUtilities.h */, ); name = AFNetworking; path = ../../AFNetworking; diff --git a/iOS Example/AFNetworking iOS Example.xcodeproj/project.pbxproj b/iOS Example/AFNetworking iOS Example.xcodeproj/project.pbxproj index 15377fc..d465b27 100644 --- a/iOS Example/AFNetworking iOS Example.xcodeproj/project.pbxproj +++ b/iOS Example/AFNetworking iOS Example.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + F8323C941455C03400190CCB /* AFJSONUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFJSONUtilities.h; path = ../AFNetworking/AFJSONUtilities.h; sourceTree = ""; }; F86E5527143A28F3002B438C /* AFURLConnectionOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AFURLConnectionOperation.h; path = ../AFNetworking/AFURLConnectionOperation.h; sourceTree = ""; }; F86E5528143A28F3002B438C /* AFURLConnectionOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFURLConnectionOperation.m; path = ../AFNetworking/AFURLConnectionOperation.m; sourceTree = ""; }; F874B5C913E0AA6500B28E3E /* AFHTTPRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AFHTTPRequestOperation.m; path = ../AFNetworking/AFHTTPRequestOperation.m; sourceTree = ""; }; @@ -243,6 +244,7 @@ F874B5D013E0AA6500B28E3E /* UIImageView+AFNetworking.m */, F874B5D513E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.h */, F874B5CD13E0AA6500B28E3E /* AFNetworkActivityIndicatorManager.m */, + F8323C941455C03400190CCB /* AFJSONUtilities.h */, ); name = AFNetworking; sourceTree = "";