# StackKit (Objective-C)

Objective-C can be a pretty verbose language, especially with how I've chosen to implement the API.  That being said, here's how StackKit does this:

    SKSite * site = [SKSite stackAppsSite];

    //begin building our request for all questions  
    SKFetchRequest * request = [[SKFetchRequest alloc] init];
    [request setEntity:[SKQuestion class]];
    
    //this will hold how the favorited counts for a user
    NSCountedSet * counts = [NSCountedSet set];
    
    NSUInteger count = NSUIntegerMax;
    //retrieve all the questions
    for (NSUInteger offset = 0; offset < count; offset += 100) {
        //starting from the appropriate offset (page)
        [request setFetchOffset:offset];
        
        NSError * error = nil;
        NSArray * matches = [site executeSynchronousFetchRequest:request error:&error];

        //loop through all the questions and record how many times they've been favorited
        for (SKQuestion * question in matches) {
            NSUInteger count = [[question favoriteCount] unsignedIntegerValue];
            for (int i = 0; i < count; ++i) { [counts addObject:[question ownerID]]; }
        }
        
        if (count == NSUIntegerMax) {
            count = [[request fetchTotal] unsignedIntegerValue];
        }
    }
    [request release];
    
    //turn the counted set into a dictionary (so we can sort it)
    NSMutableArray * favoriteCounts = [NSMutableArray array];
    for (id user in counts) {
        [favoriteCounts addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                                   user, @"user",
                                   [NSNumber numberWithUnsignedInteger:[counts countForObject:user]], @"count",
                                   nil]];
    }
    //sort the dictionary by the count, descending
    [favoriteCounts sortUsingDescriptors:[NSArray arrayWithObject:[[[NSSortDescriptor alloc] initWithKey:@"count" ascending:NO] autorelease]]];
    
    //create a request to fetch all the user objects
    request = [[SKFetchRequest alloc] init];
    [request setEntity:[SKUser class]];
    [request setPredicate:[NSPredicate predicateWithFormat:@"%K = %@", SKUserID, [favoriteCounts valueForKey:@"user"]]];
    
    NSArray * users = [site executeSynchronousFetchRequest:request error:nil];
    [request release];
    
    //build a userID => user map
    NSDictionary * userMapping = [NSDictionary dictionaryWithObjects:users forKeys:[users valueForKey:SKUserID]];
    
    //print out the favorited count and username
    for (NSDictionary * top in favoriteCounts) {
        SKUser * user = [userMapping objectForKey:[top objectForKey:@"user"]];
        NSLog(@"%2d - %@ [%@]", [[top objectForKey:@"count"] unsignedIntegerValue], [user displayName], [user userID]);
    }

Outputs:

    101 - Kevin Montrose [2]
    88 - George Edison [18]
    86 - code poet [14]
    29 - Soviut [825]
    28 - lfoust [11]
    22 - Adam Wright [5]
    22 - systempuntoout [51]
    21 - S.Mark [40]
    20 - Felix [956]
    17 - Farseeker [816]
    16 - Dave DeLong [448]
    11 - Dave Swersky [29]
    10 - Bill the Lizard [9]
     9 - Franci Penov [13]
     9 - Matt S. [30]
     8 - Jeff Atwood [4]
     8 - Edan Maor [1241]
     7 - carson [33]
     7 - swanson [839]
     7 - Jedi Master Spooky [192]
     7 - nabeelmukhtar [1026]
     7 - Shay Erlichmen [614]
     7 - codeka [1290]
     6 - Kyle Cronin [42]
     6 - Jason [19]
     6 - Joel Potter [8]
     6 - Catchwa [700]
     6 - Thomas McDonald [1031]
     6 - Lucas Jones [570]
     6 - Steffen Opel [377]
     5 - SztupY [1265]
     5 - TheHurt [17]
     5 - ColinD [222]
     5 - Ricky [199]
     5 - Jonathan [938]
     5 - conmulligan [449]
     5 - Mark Rushakoff [1048]
     4 - chenyuejie [2292]
     4 - Koning Baard [451]
     4 - jjnguy [39]
     4 - Adam [1395]
     3 - Martin Plante [28]
     3 - Riduidel [2192]
     3 - Yacoby [1049]
     3 - InfinitiesLoop [1394]
     3 - Igor Zevaka [113]
     3 - phsr [693]
     3 - Robert Munteanu [358]
     3 - blork [1849]
     3 - Nick Presta [186]
     3 - johnwards [638]
     2 - John Bristowe [70]
     2 - eWolf [664]
     2 - Soldier.moth [91]
     2 - James A. Rosen [140]
     2 - Nippysaurus [1221]
     2 - Ryan Brunner [1263]
     2 - Dennis Williamson [171]
     2 - adrianbanks [127]
     2 - radius [295]
     2 - Kevin [2296]
     2 - tonklon [2734]
     2 - Peter Mortensen [151]
     2 - Josh Kelley [2287]
     2 - Mark Hurd [44]
     2 - RichH [757]
     1 - iconiK [375]
     1 - Peter Mourfield [424]
     1 - Robert Cartaino [431]
     1 - Joe [2418]
     1 - pufferfish [1689]
     1 - mlaw [2467]
     1 - Nicolas Raoul [2679]
     1 - Artefacto [1179]
     1 - jmoy [1978]
     1 - Shane [1270]
     1 - Matthew Pelser [138]
     1 - Charles Stewart [2083]
     1 - coobird [525]
     1 - Nathan Voxland [2442]
     1 - Michael B. [234]
     1 - Robert Love [1578]
     1 - balpha [43]
     1 - Matt Culbreth [2829]
     1 - voyager [20]
     1 - Lucas McCoy [239]
     1 - Alexandre Rafalovitch [2883]
     1 - Ngu Soon Hui [216]
     1 - Frank Krueger [2203]
     1 - svick [505]
     1 - Fernando [1856]
     1 - tsudot [2662]
     1 - Chacha102 [23]
     1 - Nathan Reed [680]

Calls made:

    http://api.stackapps.com/1.0/questions?body=true&key=<key>&pagesize=100&page=1
    http://api.stackapps.com/1.0/questions?body=true&key=<key>&pagesize=100&page=2
    http://api.stackapps.com/1.0/questions?body=true&key=<key>&pagesize=100&page=3
    http://api.stackapps.com/1.0/questions?body=true&key=<key>&pagesize=100&page=4
    http://api.stackapps.com/1.0/questions?body=true&key=<key>&pagesize=100&page=5
    http://api.stackapps.com/1.0/questions?body=true&key=<key>&pagesize=100&page=6
    http://api.stackapps.com/1.0/users/2;18;14;825;11;5;51;40;956;816;448;29;9;13;30;4;1241;33;839;192;1026;614;1290;42;19;8;700;1031;570;377;1265;17;222;199;938;449;1048;2292;451;39;1395;28;2192;1049;1394;113;693;358;1849;186;638;70;664;91;140;1221;1263;171;127;295;2296;2734;151;2287;44;757;375;424;431;2418;1689;2467;2679;1179;1978;1270;138;2083;525;2442;234;1578;43;2829;20;239;2883;216;2203;505;1856;2662;23;680?key=<key>&page=1&pagesize=100