7

In my app I need to send an array from Objective C to javascript. I read on the web that I can use this instruction: stringByEvaluatingJavaScriptFromString, also i made so:

Objective C snippet

NSMutableArray *names = [[NSMutableArray alloc]init];
NSMutableArray *srcs = [[NSMutableArray alloc]init];
for (int i = 0; i < [site count]; i++) {
    NSDictionary *dictData = [site objectAtIndex:i];
    [names addObject:[dictData objectForKey:@"name"]];
    [srcs addObject:[dictData objectForKey:@"src"]];
}
// UPDATE
NSData *jsonArray = [self arrayToJson:nameSrc];
NSString *jsonString = [[NSString alloc]initWithData:jsonArray encoding:NSUTF8StringEncoding];
NSString *econdedString = [self base64String:jsonString];
NSString *jsCall = [NSString stringWithFormat:@"dataFromObjC(\"%@\")", econdedString];
[self.webView stringByEvaluatingJavaScriptFromString:jsCall];

So in javascript I made a function that has this name dataFromObjC(names, srcs), but it doesn't shows me the alert I made. I will post here the complete code of my html so you can help me to solve this problem.

HTML code

<!DOCTYPE html>
<html lang="it">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>  
        <title>Lista coupon</title>
        <script src="../js/jquery-1.9.1.min.js" type="text/javascript"></script>
        <script src="../js/memoria.js"          type="text/javascript"></script>
        <script type="text/javascript" src="../js/base64.js"></script>
        <script type="text/javascript">
            function dataFromObjC(encodedArray) {
                var jsonString = Base64.decode(encodedArray);
                var arrayFromiOS = JSON.parse(jsonString);
                alert(jsonString);
            }
        </script>
        <style type="text/css">
            body {
                background-color: #000000;
                width: 100%;
                height: 100%;
                padding: 0;
                margin: 0;
            }
            ul {
                list-style-type: none;
                padding: 5px;
            }
            li {
                color: #FFFFFF;
                font-family: sans-serif;
                padding-bottom: 5px;
            }
            p {
                color: #FFFFFF;
                font-family: sans-serif;
                padding: 5px;
                text-align: center;
            }
            a {
                text-decoration: none;
                color: #FFFFFF;
            }
        </style>
    </head>
    <body onload="loadJson();">
        <div id="header">
        </div>
        <div id="content">
            <p>Di seguito trovi tutte le promozioni salvate</p>
            <div id="list">
            </div>          
        </div>
        <div id="footer">

        </div>
    </body>
</html>

I hope that you can help me.

Thank you

2
  • You should encode all your data as JSON using NSJSONSerialization and decode it once you're in JS land. Commented Aug 1, 2013 at 9:51
  • @MikeWeller: Let's see if I understand well: also in objective C I've to encode the 2 NSArray with NSJSONSerialization and then in javascript I've to decode? Can you explain me better maybe can you write your solution as an answer? Commented Aug 1, 2013 at 9:54

1 Answer 1

10
  • First, encode your data to a JSON string instead of a plain string, before sending it to JS. You can do this with NSJSONSerialization.

    - (NSData *) arrayToJSON:(NSArray *) inputArray
    {
        NSError *error = nil;
        id result = [NSJSONSerialization dataWithJSONObject:inputArray 
                                                    options:kNilOptions error:&error];
        if (error != nil) return nil;
        return result;    
    }
    
  • Send it to JS with stringByEvaluatingJavaScriptFromString:. Optionally, I would recommend you to encode the string with Base64, to avoid problems with special characters.

    // Convert your array to JSON data
    NSData *jsonArray = [self arrayToJSON: yourArray];
    // Pass the JSON to an UTF8 string
    NSString *jsonString = [[NSString alloc] initWithData:jsonArray                         
                                                  encoding:NSUTF8StringEncoding];
    // Base64 encode the string to avoid problems
    NSString *encodedString = [Base64 encode:jsonString];
    // Evaluate your JavaScript function with the encoded string as input
    NSString *jsCall = [NSString stringWithFormat:@"yourJsFunction(\"%@\")", encodedString];
    [self.webView stringByEvaluatingJavaScriptFromString:jsCall];
    
  • Once in JS, parse the JSON string to an object (optionally, remember to decode it if you encode first).

    function yourJsFunction(encodedArray)
    {
        // Decode and parse the received input
        var jsonString = Base64.decode(encodedArray);
        var arrayFromiOS = JSON.parse(jsonString);
    }
    

UPDATE: About Base64 utilities for iOS and JS, Internet is plenty of examples of functions and libraries, like these ones for iOS and these other ones for JS. You can choose the one you prefer.

Sign up to request clarification or add additional context in comments.

9 Comments

You think I should encode my javascriptString with an external library and pass to the javascript by using this: [self.webView stringByEvaluatingJavaScriptFromString:javascriptString];
Yes, it would be safer to encode and decode the string with Base64 for example, to avoid problems with some special characters.
I have added a complete example so you can actually test it and let me know if it works. Hope it helps!
Ok I put your code in my app, but still having problems: What's Base64 xCode mark it as an error? Why you make this @"yourJsFunction(\"encodedString\")"? I don't have to make a NSString *javascriptString = [NSString stringWithFormat:@"@"yourJsFunction(\%@\)", encodedString];?
Base64 is just an example name, you need to include a Base64 encode/decoding tool for iOS, Internet is plenty of examples, like this ones. Just choose the one you prefer. About the encodedString, sorry that was my mistake, I'll update the code now.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.