CPJSONRPC 0.1.4

CPJSONRPC 0.1.4

TestsTested
LangLanguage Obj-CObjective C
License MIT
ReleasedLast Release Jul 2016

Maintained by Jacob Fenton.



CPJSONRPC 0.1.4

  • By
  • Jacob Fenton

Example

To run the example project, clone the repo, and run

$ pod install

from the Example directory first.

You can also run

$ pod try CPJSONRPC

to download the pod to a temp location, install its dependencies and open the demo project.

Installation

CPJSONRPC is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'CPJSONRPC'

Then, run the following command:

$ pod install

You should now be able to import CPJSONRPC in your project using

@import CPJSONRPC;

or if you wish to import a specific header, e.g. CPJSONRPCRequest.h, use

#import <CPJSONRPC/CPJSONRPCRequest.h>

API

CPJSONRPCMessage Protocol

@protocol CPJSONRPCMessage <NSObject>
// All of CPJSONRPCNotification, CPJSONRPCRequest and CPJSONRPCResponse implement
// this protocol.
// CPJSONRPCError doesn't, because it is only ever included as part of a JSON-RPC
// response (and thus a CPJSONRPCError is marshalled during the marshalling of
// the CPJSONRPCResponse that it's attached to).
- (NSString*)createJSONStringAndReturnError:(NSError**)err;
@end

CPJSONRPCHelper

@interface CPJSONRPCHelper : NSObject

// Returns one of the CPJSONRPC classes, depending on what type of message
// is supplied. Callers must check the error before trying to use the returned class.
+ (id<CPJSONRPCMessage>)parseIncoming:(NSString *)incoming error:(NSError *__autoreleasing *)err;

@end

CPJSONRPCNotification

@interface CPJSONRPCNotification : NSObject<CPJSONRPCMessage>

@property (strong, nonatomic, readonly) NSString *method;
@property (strong, nonatomic, readonly) id params;

// Use this method to create CPJSONRPCNotification objects. Do no try to create
// with alloc, init. Using this method ensures that all required fields are set.
+ (instancetype)notificationWithMethod:(NSString *)method params:(id)params error:(NSError *__autoreleasing *)err;

// Get the JSON-RPC string using this method.
- (NSString *)createJSONStringAndReturnError:(NSError *__autoreleasing *)err;

// This class method is used by CPJSONRPCHelper when parsing a message to
// determine if the message is a notification.
// It returns a dictionary of all the possible fields that could be present in a
// JSON-RPC notification. Each field maps to a boolean value, which is YES if the
// field MUST exist, and NO if the field MAY be omitted.
+ (NSDictionary *)ValidAndExpectedKeys;

@end

CPJSONRPCRequest

@interface CPJSONRPCRequest : NSObject<CPJSONRPCMessage>

@property (strong, nonatomic, readonly) NSString *method;
@property (strong, nonatomic, readonly) id params;
@property (strong, nonatomic, readonly) NSNumber *msgId;

// Use this method to create CPJSONRPCRequest objects. Do no try to create with
// alloc, init. Using this method ensures that all the required fields are set.
+ (instancetype)requestWithMethod:(NSString *)method params:(id)params msgId:(NSNumber *)msgId error:(NSError *__autoreleasing *)err;

// Get the JSON-RPC string using this method.
- (NSString *)createJSONStringAndReturnError:(NSError *__autoreleasing *)err;

// This class method is used by CPJSONRPCHelper when parsing a message to
// determine if the message is a request.
// It returns a dictionary of all the possible fields that could be present in a
// JSON-RPC request. Each field maps to a boolean value, which is YES if the field
// MUST exist, and NO if the field MAY be omitted.
+ (NSDictionary *)ValidAndExpectedKeys;

@end

CPJSONRPCResponse

@interface CPJSONRPCResponse : NSObject<CPJSONRPCMessage>

@property (strong, nonatomic, readonly) id result;
@property (strong, nonatomic, readonly) CPJSONRPCError *error;
@property (strong, nonatomic, readonly) NSNumber *msgId;

// Use these methods to create CPJSONRPCResponse objects. Do not try to create
// using alloc, init. Using these methods ensures we don't violate the JSON-RPC
// protocol by including both "result" and "error" fields, and that all required
// fields are set.
+ (instancetype)responseWithError:(CPJSONRPCError *)err msgId:(NSNumber *)msgId;
+ (instancetype)responseWithResult:(id)result msgId:(NSNumber *)msgId error:(NSError *__autoreleasing *)err;

// These methods allow quick identification of whether a CPJSONRPCResponse is
// an error or result response.
- (BOOL)isError;
- (BOOL)isResult;

// Get the JSON-RPC string using this method.
- (NSString *)createJSONStringAndReturnError:(NSError *__autoreleasing *)err;

// They return sets of all the fields that should be present in JSON-RPC
// error/result responses, excluding the "jsonrpc" field, which is present in
// all messages (CPJSONRPCHelper checks this field separately).

// These class methods are used by CPJSONRPCHelper when parsing a message to
// determine if the message is a response, and what type of response it is.
// They return dictionaries of all the possible fields that could be present in
// JSON-RPC error/result responses. Each field maps to a boolean value, which is
// YES if the field MUST exist, and NO if the field MAY be omitted.
+ (NSDictionary *)ValidAndExpectedResultKeys;
+ (NSDictionary *)ValidAndExpectedErrorKeys;

@end

CPJSONRPCError

@interface CPJSONRPCError : NSObject

@property (strong, nonatomic, readonly) NSNumber *code;
@property (strong, nonatomic, readonly) NSString *message;
@property (strong, nonatomic, readonly) id data;

// Use this method to create CPJSONRPCError objects. Do not try to create using
// alloc, init. Using this method ensures all the required fields are set.
+ (instancetype)errorWithCode:(NSNumber *)code message:(NSString *)message data:(id)data error:(NSError *__autoreleasing *)err;

// This class method is used by CPJSONRPCHelper when parsing an error response.
// It returns a dictionary of all the possible fields that could be present in a
// JSON-RPC response error object. Each field maps to a boolean value, which is
// YES if the field MUST exist, and NO if the field MAY be omitted.
+ (NSDictionary *)ValidAndExpectedKeys;

@end

CPJSONRPCDefines.h

// CPJSONRPCParseError's are thrown by CPJSONRPCHelper's parseIncoming:error:
// method.
typedef NS_ENUM(NSInteger, CPJSONRPCParseError) {
    CPJSONRPCParseErrorInvalidVersion,
    CPJSONRPCParseErrorInvalidMessage,
};

// CPJSONRPCObjectError's are thrown by the actual classes, generally in the
// methods that create CPJSONRPCMessage-conforming objects.
typedef NS_ENUM(NSInteger, CPJSONRPCObjectError) {
    CPJSONRPCObjectErrorInvalidNotificationInvalidParamsType,
    CPJSONRPCObjectErrorInvalidNotificationNilMethod,
    CPJSONRPCObjectErrorInvalidRequestInvalidParamsType,
    CPJSONRPCObjectErrorInvalidRequestNilMethod,
    CPJSONRPCObjectErrorInvalidRequestNilId,
    CPJSONRPCObjectErrorInvalidResponse,
    CPJSONRPCObjectErrorInvalidResponseInvalidResultType,
    CPJSONRPCObjectErrorInvalidResponseNilResult,
    CPJSONRPCObjectErrorInvalidResponseNilId,
    CPJSONRPCObjectErrorInvalidErrorInvalidDataType,
    CPJSONRPCObjectErrorInvalidErrorNilCode,
    CPJSONRPCObjectErrorInvalidErrorNilMessage,
};

// All JSON-RPC messages should contain "jsonrpc" : "2.0"
#define JSON_RPC_VERSION @"2.0"

// These are all the JSON-RPC fields.
#define JSON_RPC_VERSION_KEY @"jsonrpc"
#define JSON_RPC_METHOD_KEY @"method"
#define JSON_RPC_PARAMS_KEY @"params"
#define JSON_RPC_ID_KEY @"id"
#define JSON_RPC_RESULT_KEY @"result"
#define JSON_RPC_ERROR_KEY @"error"
#define JSON_RPC_ERROR_CODE_KEY @"code"
#define JSON_RPC_ERROR_MESSAGE_KEY @"message"
#define JSON_RPC_ERROR_DATA_KEY @"data"

// Check the domain of any returned errors using this define.
#define CPJSONRPC_DOMAIN @"org.cocoapods.CPJSONRPC"

Unit Tests

I've written a number of tests, check CPJSONRPCSpec.m in the example project. To run these tests, open up the example project and press ⌘+U.

Author

Jacob Fenton, [email protected]

License

CPJSONRPC is available under the MIT license. See the LICENSE file for more info.