0

I make a request to the Instapaper API, and it's supposed to return JSON. It returns something close to JSON, but not completely, like follows:

2013-05-30 19:54:20.155 --[53078:c07] (
        {
        type = meta;
    },
        {
        "subscription_is_active" = 1;
        type = user;
        "user_id" = --;
        username = "--@gmail.com";
    },
        {
        "bookmark_id" = 387838931;
        description = "";
        hash = YHwQuwhW;
        "private_source" = "";
        progress = 0;
        "progress_timestamp" = 0;
        starred = 0;
        time = 1369954406;
        title = "Adobe Finally Releases Kuler Color-Picking App for iPhone - Mac Rumors";
        type = bookmark;
        url = "http://www.macrumors.com/2013/05/30/adobe-finally-releases-kuler-color-picking-app-for-iphone/";
    },

How do I then process this? Can I take it and turn it into an NSDictionary even though it doesn't seem to be valid JSON?

Doug Smith
  • 29,668
  • 57
  • 204
  • 388
  • Here's the code I'm using: https://gist.github.com/anonymous/a7eee82f03131ec17b3d Could we talk over email? clselig @ gmail dot com – Doug Smith Jun 05 '13 at 23:43

3 Answers3

2

From Instapaper API Docs:

Instapaper strings are always encoded in UTF-8, and Instapaper expects all input to be in UTF-8. Unless otherwise noted, output from every method is an array. The output array is returned as JSON by default. You can specify a jsonp parameter with a callback function name, e.g. jsonp=myCallback, to use JSONP and wrap the output in a call to the specified function.

So there is no way you will get not valid JSON!

Try following code:

NSData *jsonData = [[NSString stringWithContentsOfURL:[NSURL urlWithString:@"http://your-instapeper-API-link"] encoding:NSUTF8StringEncoding error:nil] dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
id serializationJSON = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];

And then you can log what is wrong or if result is what you expect:

NSLog(@"class of JSON input: %@ \n and possible error: %@",[serializationJSON class],error);

Of course you should expect Array and no error.

EDIT ... based on coment code:

Based on docs you should get Array or Dictionary. Please add this core instead your line #23 (numer from here):

if([JSON isKindOfClass:[NSDictionary class]]) {
   NSDictionary *jsonDictionary = JSON;
   NSLog(@"%@",[jsonDictionary allKeys]);
} else { 
  NSLog(@"JSON object class: %@",[JSON class]);
}

and please show us output.

One more thing:

You get array from request. Great! This is a valid JSON. So you need to debug it. As i said it's a shame is not a unlimited acccess public API, so i can look into it. But now you have to debug your result. I see in your code that you are trying to access bookmarks. So i look into Bookmarks section in docs and this is some kind of list (NSArray). So if you don't know what result you want. You should print them into log (or set a breakpoint). Replace code from my earlier update with this simple log:

NSDictionary *resultDictionary;
if([JSON isKindOfClass:[NSArray class]]) {
  NSArray *jsonArray = JSON;
  NSLog(@"so json is an array with %i objects",[jsonArray count]);
  for(id objectInsideArr in jsonArray) {
     NSLog(@"object in array [class]: %@ [value]: %@",[objectInsideArr class],objectInsideArr); //if here you find NSDictionary maybe is this dictionary you are looking for. I'm not sure what it is.
   if([objectInsideArr isKindOfClass:[NSDictionary class]]) {
       resultDictionary = [[NSDictionary alloc] initWithDictionary:objectInsideArr];
   }
  }
}
Jakub
  • 13,712
  • 17
  • 82
  • 139
  • I'm sorry, but I'm not exactly sure how to use that code you provided. Here's the code I'm using to retrieve the response I'm getting: https://gist.github.com/anonymous/a7eee82f03131ec17b3d I'm not sure I can just make an API request without supplying tokens and just the URL as you provided, but if I can do more please just say so. – Doug Smith Jun 05 '13 at 23:42
  • Yes, you're right. I didn't know that you have to send POST request, and I can't generate instantpaper key right now (admin have to send it). But you're using `AFXAuthClient` from `AFNetworting` (to be honest i'm not a big fan after iOS 5 and `NSJSONSerialization`). But i edit my answer. Please give this output. – Jakub Jun 06 '13 at 18:59
  • `JSON object class: __NSCFArray` was the output. – Doug Smith Jun 06 '13 at 22:46
  • Great! So this is a valid JSON. I update my answer. This should help you. – Jakub Jun 06 '13 at 23:03
  • Great, so log `object in array [class]: __NSCFDictionary` tells you that you have a valid NSDictionary. I've edit two line of codes in my answer. If you have only one row with dictionary variable `resultDictionary` will contains your expected result. – Jakub Jun 07 '13 at 07:52
-1

If it were me I would write a custom formatter to get it into JSON format and then use NSJSONSerialization once I know it is valid. What you posted is so far from valid there is no way it would work. I'm surprised they are returning it in that format, do they provide some kind of library for consuming their services?

THE_DOM
  • 4,266
  • 1
  • 18
  • 18
  • And no, they don't provide any library. http://www.instapaper.com/api/full On that page it seems to return valid JSON oddly enough. – Doug Smith Jun 04 '13 at 17:44
  • I'm thinking about using regular expressions to remove everything except the bit I need (bookmark ID and URL) and then taking the new string with just those details and acting on it. – Doug Smith Jun 04 '13 at 17:57
  • That's weird that what they document and what you are getting in your call are two different formats. I would see if it is something on their end. You really should get valid JSON back. If you have to make it work on your end, just do string manipulations until it is valid JSON. i.e replac equals with colons, remove semi-colons, add opening and closing brackets, and wrap key-value pairs in quotations. But honestly that is a lot of work and an error prone process so I would check with them first for why your call is returning an invalid format. – THE_DOM Jun 04 '13 at 20:10
-1

If you want something even simpler, I can give you my CGIJSONObject library that will handle JSON using reflection - you just need to mirror the keys in APIs with your classes andit is good to go.

Maxthon Chan
  • 1,181
  • 8
  • 15