views:

611

answers:

2

Hi,

I'm using Matt Gemmell's amazing MGTwitterEngine for an iPhone project, and my lack of familiarity with Obj-C and JSON parsing is making a simple job seem rather daunting.

I've read this link, and while it helps me understand how the data is structured, I still can't seem to be able to parse it.

If I do an NSLog of the output of getSearchResultsForQuery like so:

NSLog(@"getSearchResultsForQuery: connectionIdentifier = %@", [myTwitterEngine getSearchResultsForQuery:@"#joke" sinceID:0 startingAtPage:1 count:5]);

I get this in the console:

2009-12-05 00:14:46.518 Entendu[90565:207] getSearchResultsForQuery: connectionIdentifier = DED541CB-A3DA-4C04-8B23-ED20D13B147E
2009-12-05 00:14:46.843 Entendu[90565:207] Request succeeded for connectionIdentifier = DED541CB-A3DA-4C04-8B23-ED20D13B147E
2009-12-05 00:14:46.884 Entendu[90565:207] Got search results for DED541CB-A3DA-4C04-8B23-ED20D13B147E:
(
        {
        "created_at" = 1259989857;
        "from_user" = royanramadhan;
        "from_user_id" = 64716299;
        geo = <null>;
        id = 6361369664;
        "iso_language_code" = sv;
        "profile_image_url" = "http://a3.twimg.com/profile_images/455943541/Dup_01_Foto006_normal.jpg";
        source = "<a href=\"http://m.twitter.com/\" rel=\"nofollow\">mobile web</a>";
        "source_api_request_type" = 37;
        text = "kenapa di keybord komputer tulisnya \"ENTER\" ? #joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259988269;
        "from_user" = alivenkickin;
        "from_user_id" = 2547330;
        geo = <null>;
        id = 6360783744;
        "iso_language_code" = en;
        "profile_image_url" = "http://a3.twimg.com/profile_images/65068323/calvin_normal.jpg";
        source = "<a href=\"http://www.tweetdeck.com/\" rel=\"nofollow\">TweetDeck</a>";
        "source_api_request_type" = 37;
        text = "RT @andycrash: A nice, calm and respectable lady went into the pharmacy...#joke http://bit.ly/BGDfJ";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259988217;
        "from_user" = lilbytes;
        "from_user_id" = 18943691;
        geo = <null>;
        id = 6360764474;
        "iso_language_code" = en;
        "profile_image_url" = "http://a3.twimg.com/profile_images/477338701/twitterProfilePhoto_normal.jpg";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "RT @Pyeman: LOL - Great post RT @cahlan: RT @jac_: Christmas light fun: http://bit.ly/828q7K #lol #funny #joke #christmas";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259987890;
        "from_user" = jscognam;
        "from_user_id" = 41472147;
        geo = <null>;
        id = 6360648482;
        "iso_language_code" = en;
        "profile_image_url" = "http://a3.twimg.com/profile_images/432856397/AJ_normal.png";
        source = "<a href=\"http://www.tweetdeck.com/\" rel=\"nofollow\">TweetDeck</a>";
        "source_api_request_type" = 37;
        text = "RT @jokestweet: Give me ambiguity or give me something else. #joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259987587;
        "from_user" = jokestweet;
        "from_user_id" = 54008906;
        geo = <null>;
        id = 6360534281;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/403925746/jokes_twitter_normal.jpg";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "Give me ambiguity or give me something else. #joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259987426;
        "from_user" = RickyRicardoABN;
        "from_user_id" = 79758746;
        geo = <null>;
        id = 6360472740;
        "iso_language_code" = en;
        "profile_image_url" = "http://a3.twimg.com/profile_images/554599647/l_92120d47e5744fee9da32c4ac71b9eee_normal.jpg";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "#Why do people tell you when they are speechless? #joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259984750;
        "from_user" = socialEspeaking;
        "from_user_id" = 80950838;
        geo = <null>;
        id = 6359413973;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/542502866/jack_sm_normal.jpg";
        source = "<a href=\"http://apiwiki.twitter.com/\" rel=\"nofollow\">API</a>";
        "source_api_request_type" = 37;
        text = "RT @andycrash A nice, calm and respectable lady went into the pharmacy...#joke http://x4.lol.0sp.in o_O";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259984140;
        "from_user" = oceanbutterfly7;
        "from_user_id" = 70740820;
        geo = <null>;
        id = 6359164521;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/558958306/Tiger-puppy_love_normal.jpg";
        source = "<a href=\"/devices\" rel=\"nofollow\">txt</a>";
        "source_api_request_type" = 37;
        text = "@jokestweet: \" Hire a teenage while they still know everything,\" #joke";
        "to_user" = jokestweet;
        "to_user_id" = 54008906;
    },
        {
        "created_at" = 1259983842;
        "from_user" = "Fab_DTY";
        "from_user_id" = 51115644;
        geo = <null>;
        id = 6359037805;
        "iso_language_code" = en;
        "profile_image_url" = "http://a3.twimg.com/profile_images/515204077/moto_0326_normal.jpeg";
        source = "<a href=\"http://ubertwitter.com\" rel=\"nofollow\">UberTwitter</a>";
        "source_api_request_type" = 37;
        text = "RT @nutshellcards: Energizer Bunny arrested, charged with battery. lmao #Joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259983640;
        "from_user" = chunyip;
        "from_user_id" = 1221169;
        geo = <null>;
        id = 6358953626;
        "iso_language_code" = en;
        "profile_image_url" = "http://s.twimg.com/a/1259808911/images/default_profile_6_normal.png";
        source = "<a href=\"http://mobileways.de/gravity\" rel=\"nofollow\">Gravity</a>";
        "source_api_request_type" = 37;
        text = "RT @jokestweet: If electricity comes from electrons, does that mean that morality comes from morons? #joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259983356;
        "from_user" = nutshellcards;
        "from_user_id" = 54486591;
        geo = <null>;
        id = 6358837191;
        "iso_language_code" = en;
        "profile_image_url" = "http://a3.twimg.com/profile_images/515618469/blue_normal.png";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "Energizer Bunny arrested, charged with battery. lmao\n#Joke";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259983222;
        "from_user" = sagewhistler;
        "from_user_id" = 3737203;
        geo = <null>;
        id = 6358780332;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/552759084/cowboycig_normal.GIF";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "#Joke \"What's the shotgun for?\" asks the homeowner. The bear remover replies, \"If the bear knocks me off the roof, shoot the dog.\" [end]";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259983181;
        "from_user" = sagewhistler;
        "from_user_id" = 3737203;
        geo = <null>;
        id = 6358763080;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/552759084/cowboycig_normal.GIF";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "#Joke The bear will then be subdued enough for me to put him in the cage in the back of the van.\"He hands the shotgun to the homeowner...";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259983144;
        "from_user" = sagewhistler;
        "from_user_id" = 3737203;
        geo = <null>;
        id = 6358748440;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/552759084/cowboycig_normal.GIF";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "#Joke When the bear falls off, the pit bull is trained to grab his testicles and not let go...";
        "to_user_id" = <null>;
    },
        {
        "created_at" = 1259983112;
        "from_user" = sagewhistler;
        "from_user_id" = 3737203;
        geo = <null>;
        id = 6358736099;
        "iso_language_code" = en;
        "profile_image_url" = "http://a1.twimg.com/profile_images/552759084/cowboycig_normal.GIF";
        source = "<a href=\"http://twitter.com/\"&gt;web&lt;/a&gt;";
        "source_api_request_type" = 37;
        text = "#Joke \"I'm going to put this ladder up against the roof, then I'm going to go up there & knock the bear off the roof with this baseball bat";
        "to_user_id" = <null>;
    },
        {
        "completed_in" = 0;
        "max_id" = 6361369664;
        "next_page" = "?page=2&max_id=6361369664&q=%23joke";
        page = 1;
        query = "%23joke";
        "refresh_url" = "?since_id=6361369664&q=%23joke";
        "results_per_page" = 15;
        "since_id" = 0;
        "source_api_request_type" = 37;
    }
)

The strange thing is I have count:5, yet I'm getting many more results.

For the actual parsing, would I save the output to an NSArray, and then an NSDictionary, which I can query with valueForKey:@"text" for example?

I know two delegate methods are being called too (requestSucceeded: and searchResultsReceived:forRequest: ) but I'm not sure how this affects parsing.

The actual delegate method for searchResultsReceived:forRequest: is:

- (void)searchResultsReceived:(NSArray *)searchResults forRequest:(NSString *)connectionIdentifier
{
 NSLog(@"Got search results for %@:\r%@", connectionIdentifier, searchResults);
}

This suggests that the results are actually stored by variable searchResults.

Still, how do I get the individual strings?

Thanks for the help!

A: 

I'm not sure what parsing you need to do. You're supposed to be supplying a delegate to the engine (like a callback, but an actual object), which the engine will use to notify you when it has results. The results should be coming back as an NSArray of NSDictionarys, which means you don't have to do any parsing at all.

Dave DeLong
Ah, got it now! Thanks.
Parimal
+1  A: 

The searchResults variable in your delegate is an array of dictionaries. You just index into that array and then start grabbing values for the keys in the dictionaries. For example

- (void)searchResultsReceived:(NSArray *)searchResults 
                   forRequest:(NSString *)connectionIdentifier
{
    if ([searchResults count] > 0)
    {
        NSDictionary *result = [searchResults objectAtIndex:0];

        NSString *fromUser = [result valueForKey:@"from_user"];
        NSString *fromUserID = [result valueForKey@"from_user_id"];
        // ...
        NSString *text = [result valueForKey@"text"];

        NSLog(@"User %@(%@): %@", fromUser, fromUserID, text);
    }
}
Matt Long
Thank you! This gives me a way to go on ahead and work on the data. To access the individual strings out of the scope of the delegate function, could I set a return type of Array and return one with just the information I need? Or just return the original array itself to do the extraction elsewhere?Again, thanks!
Parimal
You can just create an NSArray instance variable (ivar) property and hold onto it, e.g. [self setItems:searchResults]; This would require your instance variable be declared as a property like, @property (assign) NSArray *items; in your .h and then @synthesize items in the .m.
Matt Long
Oh, excellent! Thank you so much for your help!
Parimal