Quick and dirty JSON validation in Cocoa

[Tweet : nvALT]

I revamped the UI for advanced MathJax configuration for the upcoming Marked 2.5 update I mentioned recently. The configuration is simply a field where you can input additional inline configuration options using the JSON syntax you’d find in a script tag in an HTML document.

When writing JSON in a text field without the benefit of syntax highlighting and linters, though, it’s easy to make a mistake, and Marked would only let you know that when refreshing a document and attempting to implement the configuration during load. I wanted it to be able to provide immediate feedback.

Cocoa provides some decent JSON parsing libraries, but all I needed to know was whether it was valid syntax for a JavaScript engine to parse. I ended up using JavaScriptCore to quickly allocate and validate the string. It works quite well, though I haven’t benchmarked it very thoroughly.

This below code is from an NSTextView subclass. It takes the field’s current string, trims it and removes newlines, then attempts to run a JSON.stringify() in a JavaScriptCore context.

- (void)didChangeText
  [super didChangeText];

  NSColor *errColor = [NSColor colorWithCalibratedRed:0.445
  NSColor *okColor = [NSColor blackColor];

  NSString *input = [[[self string] straightenQuotes] trim];
  input = [input replace:RX(@"[\\n\\r]+") with:@""];
  if (![input isMatch:RX(@"^\\{.*?\\}$")])
    input = [NSString stringWithFormat:@"{%@}",

  NSString *scriptString = [NSString stringWithFormat:@"JSON.stringify(%@)",
  JSGlobalContextRef jsx = JSGlobalContextCreate(NULL);
  JSStringRef scriptJS = JSStringCreateWithCFString(

  BOOL valid = JSCheckScriptSyntax(jsx, scriptJS, NULL, 0, NULL);


  if (!valid)
      [self setTextColor:errColor];
      [self setTextColor:okColor];

For reference, the RX() methods come from Objective-C Regex Categories by Josh Wright. They are very handy shortcuts for the NSRegularExpression syntax1. Also note that it calls a method called “straightenQuotes”, which is from an NSString category and simply dumbs down smart quotes:

- (NSString *)straightenQuotes
	NSString *input = [self replace:RX(@"[“”]") with:@"\""];
	input = [input replace:RX(@"[‘’]") with:@"'"];
	return input;

This is because even though the text field disables smart quotes, system settings can override it, and users can paste them into the field, which can be a hard bug to track down in customer support.

If this is useful to you, great. If you see any major issues with the choice or in the implementation, I welcome the input.

Here’s a good (though aging) intro to JavaScriptCore.

  1. Yes, I should be working toward Swift, but this codebase is quite well grounded in Obj-C, and I’m easily intimidated by large undertakings that will break things that are working.