Sending an array of dictionary objects to a JavaScript function

I have a situation where I need to pass a large amount of data stored in an NSArray containing NSDictionary objects to a JavaScript function using a webview and the method:

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script

My inquiries are:

  1. How can I properly format my arguments at the caller end so that JavaScript can interpret them?
  2. How do I retrieve these arguments in JavaScript? Specifically, what should the function signature look like and how can I access the key-value pairs of dictionary objects within the array in the JavaScript function?

I am not very experienced with JavaScript, so please forgive me if this question seems too vague. I hope it is clear enough!

Edit: I stumbled upon this thread which mentions that passing NSDictionary objects to JavaScript functions is not feasible. So, how can we accomplish this?

Thanks & Regards, Raj

Answer №1

When passing parameters to

-stringByEvaluatingJavaScriptFromString:
, it is important to serialize them as a string. A convenient method is to convert the parameters to JSON using one of the available Cocoa JSON libraries. Once serialized, you can include this JSON string in your JavaScript code like so:

NSString *json = [serialize JSON here];
NSString *scriptString = [NSString stringWithFormat:@"doSomething(%@)", json];

Within the JSON representation, NSDictionaries will be transformed into JavaScript Objects, allowing you to access their elements using syntax such as array[5].someKey(or array[5]["some key"]).

Answer №2

If you wanted to, you could dismantle them and piece them back together, just like this individual seems to be 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');
}

Answer №3

After gaining more knowledge, I now consider that this (JSONKit on GitHub) may be a superior solution. JSONKit offers mappings of primitive types to Objective-C Foundation classes:

╭───────────────┬─────────────────────╮
│  JSON         │  Objective -C       │
├───────────────┼─────────────────────┤
│  true|false   │  NSNull             │
├───────────────┼─────────────────────┤
│  Number       │  NSNumber           │   
├───────────────┼─────────────────────┤
│  String       │  NSString           │
├───────────────┼─────────────────────┤
│  Array        │  NSArray            │
├───────────────┼─────────────────────┤
│  Object       │  NSDictionary       │
╰───────────────┴─────────────────────╯

In JSONKit, Objects can be viewed as Associative Arrays, Key / Value Hash Tables, Maps, or Dictionaries, etc.

It is mentioned that JSONKit utilizes Core Foundation internally and assumes equivalence between Core Foundation and Foundation for base types, such as CFString ≡ NSString. Additionally, it is noted that JSONKit is not considered ARC-safe.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Running "vue ui" with Node.js v17.2.0 - A step-by-step guide

After updating to Node.js v17.2.0, I am facing issues with running "vue ui" in my project. The error message I receive indicates a problem with node modules: at Object.readdirSync (node:fs:1390:3) at exports.readdir (/usr/local/lib/node_modules/@vu ...

What could be causing the QullJS delta to display in a nonsensical sequence?

The outcome showcased in the delta appears as: {"ops":[{"retain":710},{"insert":" yesterday, and she says—”\n“The clinic?","attributes":{"prediction":"prediction"}},{"del ...

Enhance Your HTML Skills: Amplifying Table Display with Images

Recently, I utilized HTML to design a table. The Table Facts : In the first row, I included an appealing image. The second row contains several pieces of content. In continuation, I added a third row. The contents in this row are extensive, resulting i ...

What are the security benefits of using Res.cookie compared to document.cookie?

When it comes to setting cookies to save data of signed in members, I faced a dilemma between two options. On one hand, there's res.cookie which utilizes the Express framework to set/read cookies on the server-side. On the other hand, there's d ...

Tips for extracting both the div and entire inner content using JavaScript

I need to retrieve the inner content of a div using JavaScript For example: <div id="content" style="height: 20px; overflow: hidden"> content<br>content<br>content<br> </div> This is my HTML code. I only know the div&apos ...

using angularjs to dynamically apply css styles

Below is the input I have: The HTML code is shown below: <input type="number" ng-class="{negative: amount < 0}" ng-model="amount"/> This is the corresponding CSS code: .negative { color: red; } If the amount is positive, no specif ...

Preventing Content Changes When Ajax Request Fails: Tips for Error Checking

I was struggling to find the right words for my question -- My issue involves a basic ajax request triggered by a checkbox that sends data to a database. I want to prevent the checkbox from changing if the ajax request fails. Currently, when the request ...

TypeScript does not perform type checking on arrays created using the Array() constructor and filled with the fill method

Using TypeScript version 2.4.2, compiled with the --target ES6 option has interesting results. For example, when using this line of code: var coins: { coin: number}[] = [1,1,1] TypeScript throws an error: Error TS2322: Type 'number[]' is no ...

Issue encountered where Moment locale functionality is working in local development environment, but not functioning properly in the

My application built with Next.js requires displaying the date in Bengali instead of English. The issue arises after running the build command 'build:next build' where the production version displays the date in English (e.g. '20 January, Su ...

A guide on organizing nested JSON objects in JavaScript

I am currently using JavaScript to retrieve JSON data that looks like this: [{ "data": { "serialNumber": "12345678", "loopCount": 2, "temperature3": 22.74921781259558, "temperature2": 21.459065450414467, "temper ...

Utilize Dojo to programmatically showcase an image

I'm facing an issue while trying to programmatically display an image using dojo. I have tried using both "dijit/Dialog" and "dojox/image/Lightbox". However, when using the Dialog method, instead of displaying the image, some random characters are sh ...

Tips on inserting text into form input fields

I need some guidance on how to enhance my form input functionality. The form currently consists of an input box and a submit button. When the user clicks submit, the form content is submitted and processed using javascript. What I am aiming for is to autom ...

Unable to retrieve Angular Service variable from Controller

I am facing an issue with my Angular Service. I have set up two controllers and one service. The first controller fetches data through an AJAX call and stores it in the service. Then, the second controller tries to access this data from the service. While ...

What is the best way to showcase a photo selected using an HTML input within a div container?

My goal is to select a photo from a folder and display it on a webpage, but I have struggled to find a working solution. Can this be achieved using just basic HTML, CSS, and JS? I am new to web development, so please forgive me for any beginner questions. ...

When combining CSS grids, nesting them can sometimes cause issues with the height layout

Check out the code on jsFiddle .component-container { width: 800px; height: 200px; background-color: lightyellow; border: 1px solid red; padding: 10px; overflow: hidden; } .component-container .grid-container-1 { display: grid; grid-tem ...

employing flush for lodash's throttle wrapper

When using TypeScript with JavaScript and Angular: I am trying to use the throttle decorator from lodash to limit an API call while a user is navigating around the page, ensuring that it fires before they leave the site. In my TypeScript constructor, I h ...

Toggle the play/pause function by clicking - Trigger Ajax

I have a campaign that can be either played or paused. Currently, I have implemented the pause feature using AJAX and now I need to add the play feature as well. When I click on the pause button, I want it to be replaced with the play button. This is the ...

Flashing bug in the outFunction of jquery hover()

My friends and I are working on a website for a class project, but we're running into a strange issue with the outFunction part of our hover function. Whenever the mouse hovers over an element, a grey square fades in using .fadeIn(), but then immediat ...

JavaScript-based tool for extracting content from Sketch file

My goal is to extract the contents of a .sketch file. I have a file named myfile.sketch. When I rename the file extension to myfile.zip and extract it in Finder, I can see the files inside. However, when I try the same process on the server using Node.js ...

Pressing the button will activate the Ctrl+z and Ctrl+y key commands

I have created two separate buttons for triggering actions equivalent to pressing Ctrl+z and Ctrl+y. I am attempting to make these actions occur with the click of a single button. However, when trying to set up the functionality to trigger Ctrl+z and Ctr ...