├── AFJSONRPCClient.podspec ├── AFJSONRPCClient.xcworkspace └── contents.xcworkspacedata ├── AFJSONRPCClient ├── AFJSONRPCClient.h └── AFJSONRPCClient.m ├── LICENSE └── README.md /AFJSONRPCClient.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'AFJSONRPCClient' 3 | s.version = '2.1.1' 4 | s.homepage = 'https://github.com/AFNetworking/AFJSONRPCClient' 5 | s.social_media_url = "https://twitter.com/AFNetworking" 6 | s.authors = { 'wiistriker' => 'wiistriker@gmail.com', 'Mattt Thompson' => 'm@mattt.me' } 7 | s.license = 'MIT' 8 | s.summary = 'A JSON-RPC client build on AFNetworking.' 9 | s.source = { :git => 'https://github.com/AFNetworking/AFJSONRPCClient.git', 10 | :tag => '2.1.1' } 11 | s.source_files = 'AFJSONRPCClient' 12 | s.requires_arc = true 13 | 14 | s.ios.deployment_target = '6.0' 15 | s.osx.deployment_target = '10.8' 16 | 17 | s.dependency 'AFNetworking', '~> 2.1' 18 | end 19 | -------------------------------------------------------------------------------- /AFJSONRPCClient.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /AFJSONRPCClient/AFJSONRPCClient.h: -------------------------------------------------------------------------------- 1 | // AFJSONRPCClient.m 2 | // 3 | // Created by wiistriker@gmail.com 4 | // Copyright (c) 2013 JustCommunication 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "AFHTTPRequestOperationManager.h" 25 | 26 | /** 27 | AFJSONRPCClient objects communicate with web services using the JSON-RPC 2.0 protocol. 28 | 29 | @see http://www.jsonrpc.org/specification 30 | */ 31 | @interface AFJSONRPCClient : AFHTTPRequestOperationManager 32 | 33 | /** 34 | The endpoint URL for the webservice. 35 | */ 36 | @property (readonly, nonatomic, strong) NSURL *endpointURL; 37 | 38 | /** 39 | Creates and initializes a JSON-RPC client with the specified endpoint. 40 | 41 | @param URL The endpoint URL. 42 | 43 | @return An initialized JSON-RPC client. 44 | */ 45 | + (instancetype)clientWithEndpointURL:(NSURL *)URL; 46 | 47 | /** 48 | Initializes a JSON-RPC client with the specified endpoint. 49 | 50 | @param URL The endpoint URL. 51 | 52 | @return An initialized JSON-RPC client. 53 | */ 54 | - (id)initWithEndpointURL:(NSURL *)URL; 55 | 56 | /** 57 | Creates a request with the specified HTTP method, parameters, and request ID. 58 | 59 | @param method The HTTP method. Must not be `nil`. 60 | @param parameters The parameters to encode into the request. Must be either an `NSDictionary` or `NSArray`. 61 | @param requestId The ID of the request. 62 | 63 | @return A JSON-RPC-encoded request. 64 | */ 65 | - (NSMutableURLRequest *)requestWithMethod:(NSString *)method 66 | parameters:(id)parameters 67 | requestId:(id)requestId; 68 | 69 | /** 70 | Creates a request with the specified method, and enqueues a request operation for it. 71 | 72 | @param method The HTTP method. Must not be `nil`. 73 | @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. 74 | @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. 75 | */ 76 | - (void)invokeMethod:(NSString *)method 77 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 78 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 79 | 80 | /** 81 | Creates a request with the specified method and parameters, and enqueues a request operation for it. 82 | 83 | @param method The HTTP method. Must not be `nil`. 84 | @param parameters The parameters to encode into the request. Must be either an `NSDictionary` or `NSArray`. 85 | @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. 86 | @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. 87 | */ 88 | - (void)invokeMethod:(NSString *)method 89 | withParameters:(id)parameters 90 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 91 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 92 | 93 | /** 94 | Creates a request with the specified method and parameters, and enqueues a request operation for it. 95 | 96 | @param method The HTTP method. Must not be `nil`. 97 | @param parameters The parameters to encode into the request. Must be either an `NSDictionary` or `NSArray`. 98 | @param requestId The ID of the request. 99 | @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. 100 | @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. 101 | */ 102 | - (void)invokeMethod:(NSString *)method 103 | withParameters:(id)parameters 104 | requestId:(id)requestId 105 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 106 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 107 | 108 | ///---------------------- 109 | /// @name Method Proxying 110 | ///---------------------- 111 | 112 | /** 113 | Returns a JSON-RPC client proxy object with methods conforming to the specified protocol. 114 | 115 | @param protocol The protocol. 116 | 117 | @discussion This approach allows Objective-C messages to be transparently forwarded as JSON-RPC calls. 118 | */ 119 | - (id)proxyWithProtocol:(Protocol *)protocol; 120 | 121 | @end 122 | 123 | ///---------------- 124 | /// @name Constants 125 | ///---------------- 126 | 127 | /** 128 | AFJSONRPCClient errors. 129 | */ 130 | extern NSString * const AFJSONRPCErrorDomain; 131 | -------------------------------------------------------------------------------- /AFJSONRPCClient/AFJSONRPCClient.m: -------------------------------------------------------------------------------- 1 | // AFJSONRPCClient.m 2 | // 3 | // Created by wiistriker@gmail.com 4 | // Copyright (c) 2013 JustCommunication 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "AFJSONRPCClient.h" 25 | #import "AFHTTPRequestOperation.h" 26 | 27 | #import 28 | 29 | NSString * const AFJSONRPCErrorDomain = @"com.alamofire.networking.json-rpc"; 30 | 31 | static NSString * AFJSONRPCLocalizedErrorMessageForCode(NSInteger code) { 32 | switch(code) { 33 | case -32700: 34 | return @"Parse Error"; 35 | case -32600: 36 | return @"Invalid Request"; 37 | case -32601: 38 | return @"Method Not Found"; 39 | case -32602: 40 | return @"Invalid Params"; 41 | case -32603: 42 | return @"Internal Error"; 43 | default: 44 | return @"Server Error"; 45 | } 46 | } 47 | 48 | @interface AFJSONRPCProxy : NSProxy 49 | - (id)initWithClient:(AFJSONRPCClient *)client 50 | protocol:(Protocol *)protocol; 51 | @end 52 | 53 | #pragma mark - 54 | 55 | @interface AFJSONRPCClient () 56 | @property (readwrite, nonatomic, strong) NSURL *endpointURL; 57 | @end 58 | 59 | @implementation AFJSONRPCClient 60 | 61 | + (instancetype)clientWithEndpointURL:(NSURL *)URL { 62 | return [[self alloc] initWithEndpointURL:URL]; 63 | } 64 | 65 | - (id)initWithEndpointURL:(NSURL *)URL { 66 | NSParameterAssert(URL); 67 | 68 | self = [super initWithBaseURL:URL]; 69 | if (!self) { 70 | return nil; 71 | } 72 | 73 | self.requestSerializer = [AFJSONRequestSerializer serializer]; 74 | [self.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 75 | 76 | self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"application/json-rpc", @"application/jsonrequest", nil]; 77 | 78 | self.endpointURL = URL; 79 | 80 | return self; 81 | } 82 | 83 | - (void)invokeMethod:(NSString *)method 84 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 85 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 86 | { 87 | [self invokeMethod:method withParameters:@[] success:success failure:failure]; 88 | } 89 | 90 | - (void)invokeMethod:(NSString *)method 91 | withParameters:(id)parameters 92 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 93 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 94 | { 95 | [self invokeMethod:method withParameters:parameters requestId:@(1) success:success failure:failure]; 96 | } 97 | 98 | - (void)invokeMethod:(NSString *)method 99 | withParameters:(id)parameters 100 | requestId:(id)requestId 101 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 102 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 103 | { 104 | NSMutableURLRequest *request = [self requestWithMethod:method parameters:parameters requestId:requestId]; 105 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 106 | [self.operationQueue addOperation:operation]; 107 | } 108 | 109 | - (NSMutableURLRequest *)requestWithMethod:(NSString *)method 110 | parameters:(id)parameters 111 | requestId:(id)requestId 112 | { 113 | NSParameterAssert(method); 114 | 115 | if (!parameters) { 116 | parameters = @[]; 117 | } 118 | 119 | NSAssert([parameters isKindOfClass:[NSDictionary class]] || [parameters isKindOfClass:[NSArray class]], @"Expect NSArray or NSDictionary in JSONRPC parameters"); 120 | 121 | if (!requestId) { 122 | requestId = @(1); 123 | } 124 | 125 | NSMutableDictionary *payload = [NSMutableDictionary dictionary]; 126 | payload[@"jsonrpc"] = @"2.0"; 127 | payload[@"method"] = method; 128 | payload[@"params"] = parameters; 129 | payload[@"id"] = [requestId description]; 130 | 131 | return [self.requestSerializer requestWithMethod:@"POST" URLString:[self.endpointURL absoluteString] parameters:payload error:nil]; 132 | } 133 | 134 | #pragma mark - AFHTTPClient 135 | 136 | - (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)urlRequest 137 | success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 138 | failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure 139 | { 140 | return [super HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject) { 141 | NSInteger code = 0; 142 | NSString *message = nil; 143 | id data = nil; 144 | 145 | if ([responseObject isKindOfClass:[NSDictionary class]]) { 146 | id result = responseObject[@"result"]; 147 | id error = responseObject[@"error"]; 148 | 149 | if (result && result != [NSNull null]) { 150 | if (success) { 151 | success(operation, result); 152 | return; 153 | } 154 | } else if (error && error != [NSNull null]) { 155 | if ([error isKindOfClass:[NSDictionary class]]) { 156 | if (error[@"code"]) { 157 | code = [error[@"code"] integerValue]; 158 | } 159 | 160 | if (error[@"message"]) { 161 | message = error[@"message"]; 162 | } else if (code) { 163 | message = AFJSONRPCLocalizedErrorMessageForCode(code); 164 | } 165 | 166 | data = error[@"data"]; 167 | } else { 168 | message = NSLocalizedStringFromTable(@"Unknown Error", @"AFJSONRPCClient", nil); 169 | } 170 | } else { 171 | message = NSLocalizedStringFromTable(@"Unknown JSON-RPC Response", @"AFJSONRPCClient", nil); 172 | } 173 | } else { 174 | message = NSLocalizedStringFromTable(@"Unknown JSON-RPC Response", @"AFJSONRPCClient", nil); 175 | } 176 | 177 | if (failure) { 178 | NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; 179 | if (message) { 180 | userInfo[NSLocalizedDescriptionKey] = message; 181 | } 182 | 183 | if (data) { 184 | userInfo[@"data"] = data; 185 | } 186 | 187 | NSError *error = [NSError errorWithDomain:AFJSONRPCErrorDomain code:code userInfo:userInfo]; 188 | 189 | failure(operation, error); 190 | } 191 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 192 | if (failure) { 193 | failure(operation, error); 194 | } 195 | }]; 196 | } 197 | 198 | - (id)proxyWithProtocol:(Protocol *)protocol { 199 | return [[AFJSONRPCProxy alloc] initWithClient:self protocol:protocol]; 200 | } 201 | 202 | @end 203 | 204 | #pragma mark - 205 | 206 | typedef void (^AFJSONRPCProxySuccessBlock)(id responseObject); 207 | typedef void (^AFJSONRPCProxyFailureBlock)(NSError *error); 208 | 209 | @interface AFJSONRPCProxy () 210 | @property (readwrite, nonatomic, strong) AFJSONRPCClient *client; 211 | @property (readwrite, nonatomic, strong) Protocol *protocol; 212 | @end 213 | 214 | @implementation AFJSONRPCProxy 215 | 216 | - (id)initWithClient:(AFJSONRPCClient*)client 217 | protocol:(Protocol *)protocol 218 | { 219 | self.client = client; 220 | self.protocol = protocol; 221 | 222 | return self; 223 | } 224 | 225 | - (BOOL)respondsToSelector:(SEL)selector { 226 | struct objc_method_description description = protocol_getMethodDescription(self.protocol, selector, YES, YES); 227 | 228 | return description.name != NULL; 229 | } 230 | 231 | - (NSMethodSignature *)methodSignatureForSelector:(__unused SEL)selector { 232 | // 0: v->RET || 1: @->self || 2: :->SEL || 3: @->arg#0 (NSArray) || 4,5: ^v->arg#1,2 (block) 233 | NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"v@:@^v^v"]; 234 | 235 | return signature; 236 | } 237 | 238 | - (void)forwardInvocation:(NSInvocation *)invocation { 239 | NSParameterAssert(invocation.methodSignature.numberOfArguments == 5); 240 | 241 | NSString *RPCMethod = [NSStringFromSelector([invocation selector]) componentsSeparatedByString:@":"][0]; 242 | 243 | __unsafe_unretained id arguments; 244 | __unsafe_unretained AFJSONRPCProxySuccessBlock unsafeSuccess; 245 | __unsafe_unretained AFJSONRPCProxyFailureBlock unsafeFailure; 246 | 247 | [invocation getArgument:&arguments atIndex:2]; 248 | [invocation getArgument:&unsafeSuccess atIndex:3]; 249 | [invocation getArgument:&unsafeFailure atIndex:4]; 250 | 251 | [invocation invokeWithTarget:nil]; 252 | 253 | __strong AFJSONRPCProxySuccessBlock strongSuccess = [unsafeSuccess copy]; 254 | __strong AFJSONRPCProxyFailureBlock strongFailure = [unsafeFailure copy]; 255 | 256 | [self.client invokeMethod:RPCMethod withParameters:arguments success:^(__unused AFHTTPRequestOperation *operation, id responseObject) { 257 | if (strongSuccess) { 258 | strongSuccess(responseObject); 259 | } 260 | } failure:^(__unused AFHTTPRequestOperation *operation, NSError *error) { 261 | if (strongFailure) { 262 | strongFailure(error); 263 | } 264 | }]; 265 | } 266 | 267 | @end 268 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 JustCommunication 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AFJSONRPCClient 2 | 3 | **A [JSON-RPC](http://json-rpc.org/) Client built on [AFNetworking](https://github.com/AFNetworking/AFNetworking)** 4 | 5 | > [JSON-RPC](http://json-rpc.org/) is a [remote procedure call](http://en.wikipedia.org/wiki/Remote_procedure_call) protocol encoded in [JSON](http://en.wikipedia.org/wiki/JSON). It is a simple protocol (and very similar to [XML-RPC](http://en.wikipedia.org/wiki/XML-RPC)), defining only a handful of data types and commands. JSON-RPC allows for notifications (info sent to the server that does not require a response) and for multiple calls to be sent to the server which may be answered out of order. 6 | 7 | ## Example Usage 8 | 9 | ``` objective-c 10 | AFJSONRPCClient *client = [AFJSONRPCClient clientWithEndpointURL:[NSURL URLWithString:@"http://path.to/json-rpc/service/"]]; 11 | 12 | // Invocation 13 | [client invokeMethod:@"method.name" 14 | success:^(AFHTTPRequestOperation *operation, id responseObject) 15 | { 16 | // ... 17 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 18 | // ... 19 | }]; 20 | 21 | // Invocation with Parameters 22 | [client invokeMethod:@"method.name" 23 | parameters:@{@"foo" : @"bar", @"baz" : @(13)} 24 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 25 | // ... 26 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 27 | // ... 28 | }]; 29 | 30 | // Invocation with Parameters and Request ID 31 | [client invokeMethod:@"method.name" 32 | parameters:@[@(YES), @(42)] 33 | requestId:@(2) 34 | success:^(AFHTTPRequestOperation *operation, id responseObject) { 35 | // ... 36 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 37 | // ... 38 | }]; 39 | ``` 40 | 41 | ## Using Protocol & NSProxy 42 | 43 | Combine your JSON-RPC client with an Objective-C protocol for fun and profit! 44 | 45 | ``` objective-c 46 | @protocol ArithemeticProtocol 47 | - (void)sum:(NSArray *)numbers 48 | success:(void (^)(NSNumber *sum))success; 49 | failure:(void (^)(NSError *error))failure; 50 | @end 51 | 52 | AFJSONRPCClient *client = [AFJSONRPCClient clientWithEndpointURL:[NSURL URLWithString:@"http://path.to/json-rpc/service/"]]; 53 | 54 | [[client proxyForProtocol:@protocol(ArithemeticProtocol)] sum:@[@(1), @(2)] 55 | success:^(NSNumber *sum) { 56 | // ... 57 | } failure:^(NSError *error) { 58 | // ... 59 | }]; 60 | ``` 61 | 62 | ## Subclassing 63 | 64 | You can also subclass `AFJSONRPCClient` for shared class and service-related methods: 65 | 66 | ``` objective-c 67 | MyJSONRPCClient *client = [MyJSONRPCClient sharedClient]; 68 | 69 | [client sum:@[@(1), @(2)] 70 | success:^(NSNumber *sum) { 71 | // ... 72 | } failure:^(NSError *error) { 73 | // ... 74 | }]; 75 | ``` 76 | 77 | ## Installation 78 | 79 | [CocoaPods](http://cocoapods.org) is the recommended way to add AFJSONRPCClient to your project. 80 | 81 | Here's an example podfile that installs AFJSONRPCClient and its dependency, AFNetworking. 82 | 83 | ### Podfile 84 | 85 | ```ruby 86 | platform :ios, '5.0' 87 | 88 | pod 'AFJSONRPCClient', '0.1.0' 89 | ``` 90 | 91 | Note the specification of iOS 5.0 as the platform; leaving out the 5.0 will cause CocoaPods to fail with the following message: 92 | 93 | > [!] AFJSONRPCClient is not compatible with iOS 4.3. 94 | 95 | ## License 96 | 97 | AFJSONRPCClient and AFNetworking are available under the MIT license. See the LICENSE file for more info. 98 | --------------------------------------------------------------------------------