mattgemmell / MGTwitterEngine

Objective-C Twitter integration library for Mac OS X and iPhone. Official repository.
http://mattgemmell.com/source
1.13k stars 164 forks source link

bug with Search Method #30

Open athanhcong opened 14 years ago

athanhcong commented 14 years ago

Hi all,

I use

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?

athanhcong commented 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

athanhcong commented 14 years ago

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];
}
athanhcong commented 14 years ago

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: