It would appear that one of the primary reasons behind the inclusion of the JavaScriptCore Framework in iOS is for the manipulation of JSON. At least from the minimal description to be found here, this would seem to be true.
Getting started with the JavaScriptCore Framework and JSON
In order to use the JavaScriptCore Framework you'll need to add the Framework to your app by navigating to Targets > General > Linked Frameworks and Libraries and adding it in. Then use #import in the .h file of your view controller to include it.At present there's no documentation for the iOS version of the Framework and so you have to rely on the header files (in the Frameworks folder of your app). But to get us started I'll borrow and adapt the initial code from this Big Nerd Ranch post.
//
// JSViewController.m
// JavaScriptCore
//
//
#import "JSViewController.h"
@interface JSViewController ()
@end
@implementation JSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// First a context and JS virtual machine is created
JSContext *context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Next we send the context a function
[context evaluateScript:@"var valueForKeyTitle = function(json) {var obj = JSON.parse(json); return(obj.Title);}"];
// Prepare a JSValue to receive the JSON
JSValue *returnElement = context[@"valueForKeyTitle"];
// Call the function by sending JSON
JSValue *resultOfFunction = [returnElement callWithArguments:@[@"{\"Title\":\"Greatest Book in the World!!\", \"Length\":214}"]];
// Print result in console
NSLog(@"Book Title: %@", resultOfFunction);
}
@end
// JSViewController.m
// JavaScriptCore
//
//
#import "JSViewController.h"
@interface JSViewController ()
@end
@implementation JSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// First a context and JS virtual machine is created
JSContext *context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Next we send the context a function
[context evaluateScript:@"var valueForKeyTitle = function(json) {var obj = JSON.parse(json); return(obj.Title);}"];
// Prepare a JSValue to receive the JSON
JSValue *returnElement = context[@"valueForKeyTitle"];
// Call the function by sending JSON
JSValue *resultOfFunction = [returnElement callWithArguments:@[@"{\"Title\":\"Greatest Book in the World!!\", \"Length\":214}"]];
// Print result in console
NSLog(@"Book Title: %@", resultOfFunction);
}
@end
The important thing to note is that we're sending a text string (not an NSData object). This is because the text is being parsed into objects within the JavaScript rather than the Objective-C. The other thing to note is that the quotation marks have been escaped. (This escaping is necessary because of the conflict between NSString and JSON keys and values both using double quotation marks.)
Loading JSON from a file
Now that we've managed to get started, the next thing you'll want to do is load the JSON from a file or from the web. And since we're only interested in importing it as a string to send to the JavaScript function we don't need to do the NSData type transformations performed in this earlier post. Instead we load the contents of the file as a text string.
//
// JSViewController.m
// JavaScriptCore
//
//
#import "JSViewController.h"
@interface JSViewController ()
@end
@implementation JSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Establish path to JSON file
NSString* path = [[NSBundle mainBundle] pathForResource:@"book"
ofType:@"json"];
// Load contents into a string
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
// First a context and JS virtual machine is created
JSContext *context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Next we send the context a function
[context evaluateScript:@"var valueForKeyTitle = function(json) {var obj = JSON.parse(json); return(obj.Title);}"];
// Prepare a JSValue to receive the JSON
JSValue *returnElement = context[@"valueForKeyTitle"];
// Call the function by sending JSON
JSValue *resultOfFunction = [returnElement callWithArguments:@[content]];
// Print result in console
NSLog(@"Book Title: %@", resultOfFunction);
}
@end
// JSViewController.m
// JavaScriptCore
//
//
#import "JSViewController.h"
@interface JSViewController ()
@end
@implementation JSViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Establish path to JSON file
NSString* path = [[NSBundle mainBundle] pathForResource:@"book"
ofType:@"json"];
// Load contents into a string
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
// First a context and JS virtual machine is created
JSContext *context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Next we send the context a function
[context evaluateScript:@"var valueForKeyTitle = function(json) {var obj = JSON.parse(json); return(obj.Title);}"];
// Prepare a JSValue to receive the JSON
JSValue *returnElement = context[@"valueForKeyTitle"];
// Call the function by sending JSON
JSValue *resultOfFunction = [returnElement callWithArguments:@[content]];
// Print result in console
NSLog(@"Book Title: %@", resultOfFunction);
}
@end
Of course for this to work you'll need a local file named book.json saved inside your project containing the same json as before, but you won't need to worry about escaping the quotation marks in this context.
Next steps
First I'd recommend reading the Big Nerd Ranch post cited above and then I'd recommend you work methodically through the header files of the JavaScriptCore Framework.Further reading
Explore JSValueMakeFromJSONString (StackOverflow) and JSValueCreateJSONString (Apple).JavaScriptCoreHeadstart (Apple)
Comments
Post a Comment