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

Application suddenly crashes due to a severe issue: FATAL EXCEPTION: java.lang.RuntimeException, preventing the activity from starting

I recently updated my Ionic, Angular, and Capacitor application to the latest versions - Ionic 7, Angular 16, and Capacitor 5. After the update, I noticed that on Android, the app works fine when installed for the first time. However, upon restarting the a ...

"An error has occurred stating that the header is not defined in

It is a coding issue related to payment methods. The headers type is undefined in this scenario, and as a newcomer to typescript, pinpointing the exact error has been challenging. An error message is indicating an issue with the headers in the if conditio ...

Steps for automatically retrying a failed expect statement in Jest

In my React application, I am utilizing Jest for performing unit testing. One aspect of my application involves a Material UI date picker with next and previous buttons. The selected date is displayed in the browser URL. Each time the user clicks on the ne ...

React: Selecting Component Name Based on Provided Property

My goal is to dynamically load an icon component in React passed as a prop from the parent component. Dashboard (parent): import { Button } from './components'; function App() { return ( <div className="app"> <d ...

Building an array from scratch in Angular

Below is the URL to access the code: https://stackblitz.com/edit/ng-zorro-antd-start-xz4c93 Inquiring about creating a new array. For example, upon clicking the submit button, the desired output should resemble the following structure: "tasks": [ { ...

Creating routes in JavaScript to split an object like a tree: a comprehensive guide

When I receive a set of filters as a composed object in my express server, I realized that to create the query I need to split each object route into a separate array of keys. For example: $and: { age: [21, 22], name: { $like: "Alice& ...

Secure login system featuring self-contained HTML and Javascript functionalities

I want to create an idle game that will save data on the server instead of using cookies. I am looking for a straightforward method (ideally without using MySQL or PHP) to implement user registration and login functionality using HTML5 and/or Javascript. ...

``I am having trouble getting the Bootstrap carousel to start

I am having trouble getting the Bootstrap Carousel to function as expected. Despite including all the necessary code, such as initializing the carousel in jQuery.ready, the images are stacking on top of each other with navigation arrows below them instea ...

Code-based document editing with CouchBase

To test Couchbase, I need to create a servlet that will edit 1,000 JSON documents by changing the value of '"flag": false' to '"flag": true'. How can I achieve this task? Here is my view code for finding documents with '"flag": fa ...

Selenium, scrolling through web pages

I have been attempting to scroll through a webpage using Selenium at "https://jobsearch.az/vacancies". However, when you open the page and click on a job vacancy, there are two side-by-side pages that need to be scrolled. The challenge is to scroll the one ...

I am facing an issue where an AJAX post to Express is not returning any data to req.query. I have tried various solutions but nothing seems to

I have encountered an issue with my setup where the body is empty when sending data through ajax. In Chrome's network tab, I can see the post and content with the correct payload: {"EventName":"asd","PrivacyLevel":1,"TypeInt":1,"ExpectedDate":"asd"," ...

Determine the presence of a Facebook user by using JavaScript

I am trying to find a method to verify the existence of a Facebook user based on their ID. As far as I understand, there is a Graph API that can provide a Facebook user's profile picture using their ID in this format: I have noticed that if an inval ...

Troubleshooting: CSS Styles not loading when passed as property in MUI withStyles

I am currently working on a react component that has a specific style defined as shown below: const StyledInnerItem = withStyles((theme) => ({ bgColor: { backgroundColor: (props) => { console.log('styledInnerItem color: ', props ...

Combining JSON objects to form a new object within a JSON object using JavaScript

Here is the JSON data that I have: {"rows":[ {"shiftId":1,"shift":"Morning","item":"Tea","value":20}, {"shiftId":1,"shift":"Morning","item":"Coffee","value":30}, {"shiftId":2,"shift":"Evening","item":"Tea","value":40}, {"shiftId":2,"shift" ...

Is your Angular5 service failing to transmit data?

I have two components in my code, A and B. Component A contains a form with data that I want to send to component B. However, it seems like component B is not receiving any data. Here is the code for Component A: import { MyService } from 'path/my ...

The login form is experiencing issues with submission when utilizing the submitFormHandler in ReactJS

In my single-page application, I'm working on creating a separate login page that will redirect the authenticated user to the main application. However, I'm encountering an issue where my submitFormHandler is not being invoked. The purpose of aut ...

Express.js routes are malfunctioning with jade/pug, causing frequent crashes and routing errors

Here is the code for my contact router: var express = require('express'); var router = express.Router(); /* GET users listing. */ router.get('/', function(req, res, next) { res.render('contact'); }); module.exports = rou ...

Is the NPM package not being imported? How exactly is it being utilized?

mediacms-vjs-plugin is a unique plugin designed for Video.js. The MediaCmsVjsPlugin.js source code begins with: import { version as VERSION } from '../package.json'; import 'mediacms-vjs-plugin-font-icons/dist/mediacms-vjs-icons.css'; ...

Passing props from Vue3 to a component being rendered through RouterView

I'm facing an issue with the following code snippet: <template> <router-view /> </template> <script setup lang="ts"> ... const product: Ref<IProduct|undefined>: ref(); ... </script> The challenge is ...

Utilize a React function to incorporate an external link

Looking to create a link to Twitter using the href attribute but encountering errors with the atag. Is there an alternative method I could use? In essence, I want to have a picture on my homepage that, when clicked, redirects the user to Twitter. I' ...