1

I'm attempting to generate some javascript from objective C. I have a simple objective-c object: only NSStrings, NSArrays, NSDictionarys, and NSNumbers - and I'd like to insert it as an object literal into javascript. What's the best way to do this?

So far I've managed to serialize the object and get a JSON string, but JSON isn't exactly equivalent to javascript object literals. I could insert it as a JSON.parse('%@') call, but that seems inefficient:

(controller.createWindow).apply((controller), JSON.parse('[\"LoggedIn\",3,1,[0,0,480,320],false,false]'))
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • How did you generate the JSON? – James Sumners Sep 10 '13 at 20:47
  • @jsumners: `[NSJSONSerialization dataWithJSONObject:args options:0 error:&error];`, then `[[[NSString alloc] initWithData:utf8stringified encoding:NSUTF8StringEncoding] autorelease];` to get an `NSString`, then [this](http://stackoverflow.com/questions/15843570/objective-c-how-to-convert-nsstring-to-escaped-json-string) to escape it – Claudiu Sep 10 '13 at 21:00
  • @Claudiu: Why the additional escaping? Isn't the NSJSONSerialization (converted to NSString) what you need? – Martin R Sep 10 '13 at 21:04
  • @MartinR: [JSON: The JavaScript subset that isn't](http://timelessrepo.com/json-isnt-a-javascript-subset). Oh although I remember going through this before and the solution was to just replace those characters... hmm yes that's a lot more straightforward – Claudiu Sep 10 '13 at 21:05
  • @MartinR: as far as I know.. I remember solving this problem before and I've been using the python equivalent of the solution I posted below for a few months without running into problems – Claudiu Sep 10 '13 at 21:16

1 Answers1

0

Here's the full code:

//turn an NSObject into an NSString
+ (NSString *)jsonDumps:(id)obj {
    NSError *error;
    NSData *utf8stringified = [NSJSONSerialization dataWithJSONObject:obj options:0 error:&error];
    if (utf8stringified == nil) {
        [NSException raise:@"Failed to jsonify arguments" format:@"Failed to jsonify arguments %@: %@",
         obj, error];
    }

    NSString *stringified = [[[NSString alloc] initWithData:utf8stringified encoding:NSUTF8StringEncoding]
                             autorelease];
    return stringified;
}

//turn a JSON string into a JS literal
+(NSString *)jsonToJSLit:(NSString *)jsonString {
    NSMutableString *s = [NSMutableString stringWithString:jsonString];
    [s replaceOccurrencesOfString:@"\u2028" withString:@"\\u2028" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [s length])];
    [s replaceOccurrencesOfString:@"\u2029" withString:@"\\u2029" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [s length])];
    return [NSString stringWithString:s];
}

//turn an object into a JS string literal
+(NSString *)objToJSLiteral:(id)obj {
    return [self jsonToJSLit:[self jsonDumps:obj]];
}

I thought there was more of a difference between JSON and JS literals, but apparently it's just those two unicode characters!

Claudiu
  • 224,032
  • 165
  • 485
  • 680