iOS: Best Way to do This w/o Calling Method 32 Times?

主宰稳场 提交于 2020-01-11 14:07:59

问题


I'm currently retrieving the Top 100 Scores for one of my leaderboards the following way:

- (void) retrieveTop100Scores {

__block int totalScore = 0;

GKLeaderboard *myLB = [[GKLeaderboard alloc] init];
myLB.identifier = [Team currentTeam];
myLB.timeScope = GKLeaderboardTimeScopeAllTime;
myLB.playerScope = GKLeaderboardPlayerScopeGlobal;
myLB.range = NSMakeRange(1, 100);

[myLB loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
    if (error != nil) {

        NSLog(@"%@", [error localizedDescription]);
    }

    if (scores != nil) {

        for (GKScore *score in scores) {

            NSLog(@"%lld", score.value);

            totalScore += score.value;

        }

        NSLog(@"Total Score: %d", totalScore);
        [self loadingDidEnd];
    }
}];

}

The problem is I want to do this for 32 leaderboards. I have an array with all 32 leaderboard identifiers:

NSArray *leaderboardIDs;

So my question is, how can I combine those 2 segments of code to pull in the 100 values for each leaderboard, resulting in a dictionary with all of the leaderboard names as keys, and the Total (of each 100 scores) of the leaderboards for values.

UPDATED:

So I have updated my answer using CrimsonChris' help. The only question I have is, how can I know when it is done totaling the score for all 32 teams? The reason I ask, is because I would then like to organize them from highest to lowest, and display them in that order in a tableView.

This is what I've updated my answer to:

In my viewDidLoad:

- (void)loadLeaderboardData {

// Array of leaderboard ID's to get high scores for
NSArray *leaderboardIDs = @[@"algeria", @"argentina", @"australia", @"belgium", @"bosniaandherzegovina", @"brazil", @"cameroon", @"chile", @"colombia", @"costarica", @"croatia", @"ecuador", @"england", @"france", @"germany", @"ghana", @"greece", @"honduras", @"iran", @"italy", @"ivorycoast", @"japan", @"mexico", @"netherlands", @"nigeria", @"portugal", @"russia", @"southkorea", @"spain", @"switzerland", @"unitedstates", @"uruguay"];

    scoresByLeaderboardID = [NSMutableDictionary dictionary];
    __block int requestCount = (int)leaderboardIDs.count;
    for (NSString *leaderboardID in leaderboardIDs) {
        [self loadScoresForLeaderboardID:leaderboardID range:NSMakeRange(1, 100) callback:^(NSArray *scores) {
            scoresByLeaderboardID[leaderboardID] = scores;
            if (--requestCount <= 0) { 
                if (callback)callback(scoresByLeaderboardID);
            }
        }];
    }
}



- (void)loadScoresForLeaderboardID:(NSString*)leaderboardID range:(NSRange)range callback:(CallbackBlock)callback {

__block int totalScore = 0;

GKLeaderboard *myLB = [[GKLeaderboard alloc] init];
myLB.identifier = leaderboardID;
myLB.timeScope = GKLeaderboardTimeScopeAllTime;
myLB.playerScope = GKLeaderboardPlayerScopeGlobal;
myLB.range = range;

[myLB loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
    if (error != nil) {
        //NSLog(@"%@", [error localizedDescription]);
    }

    if (scores != nil) {
        for (GKScore *score in scores) {
            //NSLog(@"Individual Scores: %lld (For %@)", score.value, leaderboardID);
        }

    }
}];
}

回答1:


Your method can be cleaned up by using callback blocks.

typedef void(^CallbackBlock)(id object);

//callback accepts an NSArray* of GKScore*
- (void)loadScoresForLeaderboardID:(NSString *)leaderboardID range:(NSRange)range callback:(CallbackBlock)callback {
    GKLeaderboard *myLB = [[GKLeaderboard alloc] init];
    myLB.identifier = leaderboardID;
    myLB.timeScope = GKLeaderboardTimeScopeAllTime;
    myLB.playerScope = GKLeaderboardPlayerScopeGlobal;
    myLB.range = range;

    [myLB loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
        if (error != nil) NSLog(@"%@", [error localizedDescription]);
        if (callback) callback(scores);
    }];
}

You can then loop over your leaderboards.

//callback accepts an NSDictionary* of NSArray*(of GKScore*) by NSNumber*
- (void)loadScoresForLeaderboardIDs:(NSArray *)leaderboardIDs withCallback:(CallbackBlock)callback { 
    NSMutableDictionary *scoresByLeaderboardID = [NSMutableDictionary dictionary];
    __block int requestCount = leaderboardIDs.count;
    for (NSString *leaderboardID in leaderboardIDs) {
        [LeaderboardLoader loadScoresForLeaderboardID:leaderboardID range:NSMakeRange(1, 100) callback:^(NSArray *scores) {
            scoresByLeaderboardID[leaderboardID] = scores;
            if (--requestCount <= 0) { //not thread safe
                if (callback) callback(scoresByLeaderboardID);
            }
        }];
    }
}

Once this method fires its callback you should have all your scores.

[LeaderboardLoader loadScoresForLeaderboardIDs:@[@"FirstID", @"SecondID", @"ThirdID"] withCallback:^(NSDictionary *scoresByLeaderboardID) {
    NSLog(@"%@", scoresByLeaderboardID);
    //do whatever you need to with all your scores here.
}];


来源:https://stackoverflow.com/questions/24154141/ios-best-way-to-do-this-w-o-calling-method-32-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!