Passing NSArray containing NSDictionary objects to Javascript function
I have a requirement wherein I have huge set of information in a NSArray which contains NSDictionary objects. Now I have to pass them in开发者_Python百科to a javascript function through a webview using:
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
My questions are:
- How do I prepare my arguments at the caller end so that Javascript understands it?
- How do I receive them in Javascript? Basically, what should be the function signature and how do I read the key-value pairs of dictionary objects of the array inside java function?
I basically do not have enough experience when it comes to Javascript, so forgive me if this question is too abstract, I hope that my question is clear though!
Edit: I came across a thread which states that passing NSDictionary objects to javascript functions is not possible. So, how can we achieve it?
Thanks & Regards, Raj
Since you can only provide a string to -stringByEvaluatingJavaScriptFromString:
, you need to serialize your parameters. The simplest way would be to convert it to JSON using one of the various Cocoa JSON libraries. This can then be inserted in your code as a JavaScript literal. Something like:
NSString *json = [serialize JSON here];
NSString *scriptString = [NSString stringWithFormat:@"doSomething(%@)", json];
In the JSON, the NSDictionaries will be represented as JavaScript Objects, so you’d access their members as array[5].someKey
(or array[5]["some key"]
).
You could also rip'em'apart and string 'em back together, like it looks this guys is doing....
function stringToNSString(str) {
return ['@"',str,'"'].join('');
}
function numberToNSNumber(num) {
return ['[NSNumber numberWithLong:',num,']'].join('');
}
function booleanToNSNumber(bool) {
return ['[NSNumber numberWithBool:',(bool ? 'YES' : 'NO'),']'].join('');
}
function nullToNSNull(){
return '[NSNull null]';
}
function arrayToNSArray(array){
var lines = _(array).map(function(value){
var convertedValue;
if (_(value).isString()) {
convertedValue = stringToNSString(value);
} else if (_(value).isNumber()) {
convertedValue = numberToNSNumber(value);
} else if (_(value).isBoolean()) {
convertedValue = booleanToNSNumber(value);
} else if (_(value).isNull()) {
convertedValue = nullToNSNull();
} else if (_(value).isArray()) {
convertedValue = arrayToNSArray(value);
} else if (typeof value === 'object') {
convertedValue = objectToNSDictionary(value);
}
return convertedValue;
}).map(function(value){
return value + ', ';
});
lines.unshift('[NSArray arrayWithObjects:');
lines.push('nil]');
return lines.join('');
}
function objectToNSDictionary(obj){
var lines = _(obj).map(function(value,key){
var convertedValue;
if (_(value).isString()) {
convertedValue = stringToNSString(value);
} else if (_(value).isNumber()) {
convertedValue = numberToNSNumber(value);
} else if (_(value).isBoolean()) {
convertedValue = booleanToNSNumber(value);
} else if (_(value).isNull()) {
convertedValue = nullToNSNull();
} else if (_(value).isArray()) {
convertedValue = arrayToNSArray(value);
} else if (typeof value === 'object') {
convertedValue = objectToNSDictionary(value);
}
return [convertedValue,stringToNSString(key)];
}).map(function(valueKey){
valueKey.push('');
return valueKey.join(',');
});
lines.unshift('[NSDictionary dictionaryWithObjectsAndKeys:');
lines.push('nil]');
return lines.join('\n');
}
I'm a LOT smarter now... ☺ and I think - possibly, maybe... that this (JSONKit on GitHub) is a better solution.... JSONKit provides the following primitive types mapped to the following Objective-C Foundation classes:
╭───────────────┬─────────────────────╮
│ JSON │ Objective -C │
├───────────────┼─────────────────────┤
│ true|false │ NSNull │
├───────────────┼─────────────────────┤
│ Number │ NSNumber │
├───────────────┼─────────────────────┤
│ String │ NSString │
├───────────────┼─────────────────────┤
│ Array │ NSArray │
├───────────────┼─────────────────────┤
│ Object │ NSDictionary │
╰───────────────┴─────────────────────╯
Objects are Associative Arrays
, Key / Value Hash Tables
,
Maps
, or Dictionaries
, etc.
JSONKit uses Core Foundation, internally, and it is assumed that Core Foundation ≡ Foundation for every equivalent base type, i.e. CFString ≡ NSString. Also to note, they say it is not ARC-safe.
精彩评论