0

For some reason, this works on the emulator running iOS 6+ but not on an actual iPad running iOS 5+. When I run it my app on the iPad it gives me this error (and others).

Error parsing JSON: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Badly formed object around character 316.) UserInfo=0x650260 {NSDebugDescription=Badly formed object around character 316.}

JSON used is this (which is passed from Javascript): {"functionname":"setItem","args":{"key":"http://localhost:3000/assets/tasks/task.js","value":"function Task(){this.steps=new Array,this.completed=!1,this.loaded=!1,this.stepCount=-1,this.points=0,this.newpoints=0,this.prevpoints=0,this.circleGesture=!1,this.customGesture=!1,this.subtaskCounter=0,this.className=/"/"}(goes on for a while since it is a js script)"}}

Code to convert json string to json in iOS

if ([[urlStr lowercaseString] hasPrefix:protocolPrefix])
{
    //strip protocol from the URL. We will get input to call a native method
    urlStr = [urlStr substringFromIndex:protocolPrefix.length];

    //Decode the url string
    urlStr = [urlStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSError *jsonError;

    //parse JSON input in the URL
    NSDictionary *callInfo = [NSJSONSerialization
                              JSONObjectWithData:[urlStr dataUsingEncoding:NSUTF8StringEncoding]
                              options:0
                              error:&jsonError];

    //check if there was error in parsing JSON input
    if (jsonError != nil)
    {
        NSLog(@"Error parsing JSON: %@",[jsonError debugDescription]);
        NSLog(@"%@", urlStr);
        return NO;
    } 

    ....
}

CoffeeScript

callNativeFunction: (func, args, callback)->
  if global_phone_os == 'ios'
    url = "js2native://"
    callInfo = {}
    callInfo.functionname = func
    if args?
      callInfo.args = args
    if callback?
      cid = Math.random().toString(36).substr(2,10)
      @callback[cid] = callback
      callInfo.callback_id = cid
    url += JSON.stringify callInfo
    @openCustomURLinIFrame url

Any ideas how to get this to work on both emulator and actual device?

UPDATE

So far I think I fixed it. If I did, this will be marked as the answer. I had to do the following in the coffeescript:

url += encodeURIComponent JSON.stringify callInfo

That made a difference.

Thanks.

Scott Deutsch
  • 637
  • 1
  • 8
  • 24
  • _Yo dawg, I heard you like JSON._ Why do you have a JSON string in your JSON string? Character 42 of your string is the first escaped `"` is in that embedded JSON string, so the problem is clearly related to your unescaping of that data. – Alex Wayne Aug 16 '13 at 22:56
  • @AlexWayne so is the problem within the coffeeScript or objective-c code? – Scott Deutsch Aug 16 '13 at 23:38
  • Looks like the objective-c code since I just did a test in coffeescript.org and I can do JSON.stringify within a json and stringify that. I can then get all that back correctly. – Scott Deutsch Aug 16 '13 at 23:42
  • The technical problem is in your ObjC somewhere in the unescaping. But I would argue there is a logical problem is your coffee script. You shouldn't need JSON in your JSON in this case, even though it is technically possible to do that. See what the json string is via `NSLog` after you unescape it. – Alex Wayne Aug 16 '13 at 23:43

2 Answers2

0

It looks to me like you are trying to parse the url string instead of parsing the URL contents. Are you sure this works in the emulator?

Your Code:

//parse JSON input in the URL
NSDictionary *callInfo = [NSJSONSerialization
                          JSONObjectWithData:[urlStr dataUsingEncoding:NSUTF8StringEncoding]
                          options:0
                          error:&jsonError];

I think should be:

//parse JSON input in the URL
NSDictionary *callInfo = [NSJSONSerialization
                          JSONObjectWithData:[NSData dataWithContentsOfURL:
                urlStr],
                          options:0
                          error:&jsonError];
ahmedalkaff
  • 313
  • 1
  • 3
  • When I try that, it gives me WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: data parameter is nil – Scott Deutsch Aug 17 '13 at 00:21
0

This did fix the issue.

url += encodeURIComponent JSON.stringify callInfo
Scott Deutsch
  • 637
  • 1
  • 8
  • 24