Open athanhcong opened 14 years ago
oh, I figure out that the problem is because of the YAJL parser. I checked that the data returning from network still correct. But the object returning after YAJL parser is wrong.
Is that the parser bug? I using the lastest version of this project. http://github.com/gabriel/yajl-objc
Oh, I was wrong. Actually, the problem is in our MGTwitterEngine. MGTwitterSearchYAJLParser is a wrapper of YAJL parser. I think It is created with the intention to help developers deal with the results easier. But the way it assumes structure of Twitter Search Result is not good (assume the event "start dictionary" is start a result dictionary, and then when Twitter added a sub dictionary like "metadata" dictionary above", the assumption is suck. This problem, somehow, call "leaky abstraction": http://www.joelonsoftware.com/articles/LeakyAbstractions.html
Currently, I wrote a GeneralYAJLParser to return a JSONValue, whose structure is the same with JSON String returns from Twitter.
- (void)addToCurrentNodeValue:(id)value forKey:(NSString *)key {
id currentNode = [_nodeStack lastObject];
if ([currentNode isKindOfClass:[NSDictionary class]]) {
[currentNode setObject:value forKey:key];
} else if ([currentNode isKindOfClass:[NSArray class]]) {
[currentNode addObject:value];
} else {
NSAssert(NO, @"addToCurrentNoteValue: error");
}
}
- (void)addValue:(id)value forKey:(NSString *)key
{
[self addToCurrentNodeValue:value forKey:key];
}
- (void)startDictionaryWithKey:(NSString *)key
{
if (! _rootElement)
{
[self startParsing];
return;
}
NSMutableDictionary *newDictionary = [[[NSMutableDictionary alloc] init] autorelease];
[self addToCurrentNodeValue:newDictionary forKey:key];
[_nodeStack addObject:newDictionary];
}
- (void)endDictionary
{
[_nodeStack removeLastObject];
}
- (void)startArrayWithKey:(NSString *)key
{
if (! _rootElement)
{
[self startParsing];
return;
}
NSMutableArray *newArray = [[[NSMutableArray alloc] init] autorelease];
[self addToCurrentNodeValue:newArray forKey:key];
[_nodeStack addObject:newArray];
}
- (void)endArray
{
[_nodeStack removeLastObject];
}
I think Twitter API can continue to change, so we should find a good approach to deal with this problem. I suggest some ideas, such as:
Hi all,
I use
(void)searchResultsReceived:(NSArray )searchResults forRequest:(NSString )connectionIdentifier {
( { "created_at" = 1273651741; "from_user" = thanhcongvo; "profile_image_url" = "http://s.twimg.com/a/1273620457/images/default_profile_4_normal.png"; "result_type" = recent; "source_api_request_type" = 35; }, { "created_at" = 1273651665; "from_user" = thanhcongvo; "profile_image_url" = "http://s.twimg.com/a/1273620457/images/default_profile_4_normal.png"; "result_type" = recent; "source_api_request_type" = 35; }, { "completed_in" = 0; "from_user_id" = 113120734; geo =;
id = 13839034156;
"iso_language_code" = lt;
"max_id" = 13839071338;
page = 1;
query = "to%3Ancsomofriend+OR+to%3Ancsomo";
"refresh_url" = "?since_id=13839071338&q=to%3Ancsomofriend+OR+to%3Ancsomo";
"results_per_page" = 15;
"since_id" = 0;
source = "<a href=\"http://twitter.com/\">web";
"source_api_request_type" = 35;
text = "@ncsomo 100K okie?";
"to_user" = ncsomo;
"to_user_id" = 85458822;
total = 2;
}
)
this is my search result when I use CURL:
{ "results" : [{ "profile_image_url" : "http://s.twimg.com/a/1273620457/images/default_profile_4_normal.png", "created_at" : "Wed, 12 May 2010 08:09:01 +0000", "from_user" : "thanhcongvo", "metadata" : { "result_type" : "recent" }, "to_user_id" : 87593058, "text" : "@ncsomofriend about 100USD", "id" : 13839071338, "from_user_id" : 113120734, "to_user" : "ncsomofriend", "geo" : null, "iso_language_code" : "en", "source" : "<a href="http://twitter.com/">web</a>" }, { "profile_image_url" : "http://s.twimg.com/a/1273620457/images/default_profile_4_normal.png", "created_at" : "Wed, 12 May 2010 08:07:45 +0000", "from_user" : "thanhcongvo", "metadata" : { "result_type" : "recent" }, "to_user_id" : 85458822, "text" : "@ncsomo 100K okie?", "id" : 13839034156, "from_user_id" : 113120734, "to_user" : "ncsomo", "geo" : null, "iso_language_code" : "lt", "source" : "<a href="http://twitter.com/">web</a>" }], "max_id" : 13839071338, "since_id" : 0, "refresh_url" : "?since_id=13839071338&q=to%3Ancsomofriend+OR+to%3Ancsomo", "results_per_page" : 15, "page" : 1, "completed_in" : 0.015984, "query" : "to%3Ancsomofriend+OR+to%3Ancsomo" }
Based on this result, we can see that the parser mis-join the data of the tweet results with the data of the query. Am I right? Would you mind fixing this soon?