Skip to content

Commit 272a553

Browse files
authored
Merge pull request #692 from zapcannon87/master
feat(leaderboard): get rankings of a group of user
2 parents 83d4ba7 + 31fbb85 commit 272a553

File tree

5 files changed

+196
-3
lines changed

5 files changed

+196
-3
lines changed

AVOS/LeanCloudObjcTests/LCLeaderboardTestCase.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,4 +565,86 @@ class LCLeaderboardTestCase: BaseTestCase {
565565
}
566566
}
567567
}
568+
569+
func testGetGroupUserRankings() {
570+
let object = LCObject()
571+
XCTAssertTrue(object.save())
572+
let user = LCUser()
573+
let objectFieldKey = "objectField"
574+
user[objectFieldKey] = object
575+
expecting { exp in
576+
user.login(withAuthData: ["openid" : uuid], platformId: "test", options: nil) { _, error in
577+
XCTAssertNil(error)
578+
exp.fulfill()
579+
}
580+
}
581+
guard let userObjectId = user.objectId else {
582+
XCTFail()
583+
return
584+
}
585+
586+
let statisticName0 = "test-user-0"
587+
let statisticName1 = "test-user-1"
588+
var statistic0version = -1
589+
var statistic1version = -1
590+
591+
expecting { exp in
592+
LCLeaderboard.updateCurrentUserStatistics(
593+
[statisticName0 : 100,
594+
statisticName1 : 100])
595+
{ statistics, error in
596+
XCTAssertEqual(statistics?.count, 2)
597+
XCTAssertNil(error)
598+
XCTAssertNotEqual(statistics?.first?.name, statistics?.last?.name)
599+
for item in statistics ?? [] {
600+
XCTAssertTrue([statisticName0, statisticName1].contains(item.name ?? ""))
601+
XCTAssertEqual(item.value, 100)
602+
XCTAssertGreaterThanOrEqual(item.version, 0)
603+
if (item.name ?? "") == statisticName0 {
604+
statistic0version = item.version
605+
} else {
606+
statistic1version = item.version
607+
}
608+
}
609+
exp.fulfill()
610+
}
611+
}
612+
613+
let leaderboard0 = LCLeaderboard(statisticName: statisticName0)
614+
let leaderboard1 = LCLeaderboard(statisticName: statisticName1)
615+
let option = LCLeaderboardQueryOption()
616+
option.selectKeys = [objectFieldKey]
617+
option.includeKeys = [objectFieldKey]
618+
619+
expecting(count: 2) { exp in
620+
leaderboard0.limit = 1
621+
leaderboard0.includeStatistics = [statisticName1]
622+
leaderboard0.version = statistic0version
623+
leaderboard0.getGroupUserResults(withUserIds: [userObjectId], aroundUser: userObjectId, option: option) { rankings, error in
624+
XCTAssertEqual(rankings?.count, 1)
625+
XCTAssertNil(error)
626+
for item in rankings ?? [] {
627+
XCTAssertEqual(item.statisticName, leaderboard0.statisticName)
628+
XCTAssertGreaterThanOrEqual(item.rank, 0)
629+
XCTAssertEqual(item.value, 100)
630+
XCTAssertEqual(item.includedStatistics?.first?.name, statisticName1)
631+
XCTAssertEqual(item.includedStatistics?.first?.value, 100)
632+
XCTAssertEqual(item.user?.objectId, userObjectId)
633+
XCTAssertNotNil((item.user?[objectFieldKey] as? LCObject)?.createdAt)
634+
XCTAssertNil(item.object)
635+
XCTAssertNil(item.entity)
636+
}
637+
exp.fulfill()
638+
}
639+
leaderboard1.skip = 1
640+
leaderboard1.version = statistic1version
641+
leaderboard1.getGroupUserResults(withUserIds: [userObjectId], option: option) { rankings, error in
642+
for item in rankings ?? [] {
643+
XCTAssertNotEqual(item.rank, 0)
644+
}
645+
XCTAssertNil(error)
646+
exp.fulfill()
647+
}
648+
}
649+
}
568650
}

AVOS/Sources/Foundation/Leaderboard/LCLeaderboard.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,24 @@ NS_ASSUME_NONNULL_BEGIN
184184
- (void)getEntityResultsAroundEntity:(NSString * _Nullable)entity
185185
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable rankings, NSInteger count, NSError * _Nullable error))callback;
186186

187+
/// Get rankings of a group of user on this leaderboard.
188+
/// @param userIds A group of user's object id.
189+
/// @param option The query option, see `LCLeaderboardQueryOption`.
190+
/// @param callback Result callback.
191+
- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
192+
option:(LCLeaderboardQueryOption * _Nullable)option
193+
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable rankings, NSError * _Nullable error))callback;
194+
195+
/// Get rankings of a group of user around one user on this leaderboard.
196+
/// @param userIds A group of user's object id.
197+
/// @param userId The object id of the around user.
198+
/// @param option The query option, see `LCLeaderboardQueryOption`.
199+
/// @param callback Result callback.
200+
- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
201+
aroundUser:(NSString * _Nullable)userId
202+
option:(LCLeaderboardQueryOption * _Nullable)option
203+
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable rankings, NSError * _Nullable error))callback;
204+
187205
@end
188206

189207
NS_ASSUME_NONNULL_END

AVOS/Sources/Foundation/Leaderboard/LCLeaderboard.m

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ - (void)getStatisticsWithIdentities:(NSArray<NSString *> *)identities
256256
});
257257
return;
258258
}
259+
NSDictionary *parameters = @{ @"ids" : identities };
259260
NSString *path = [NSString stringWithFormat:@"leaderboard/%@/statistics/%@", leaderboardPath, self.statisticName];
260261
if (option) {
261262
NSMutableArray<NSString *> *queryStrings = [NSMutableArray array];
@@ -274,7 +275,7 @@ - (void)getStatisticsWithIdentities:(NSArray<NSString *> *)identities
274275
}
275276
}
276277
[[LCPaasClient sharedInstance] postObject:path
277-
withParameters:identities
278+
withParameters:parameters
278279
block:^(id _Nullable object, NSError * _Nullable error) {
279280
[[self class] handleStatisticsCallback:callback error:error object:object];
280281
}];
@@ -389,6 +390,98 @@ - (void)getResultsAroundIdentity:(NSString *)identity
389390
}];
390391
}
391392

393+
- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
394+
option:(LCLeaderboardQueryOption *)option
395+
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable, NSError * _Nullable))callback
396+
{
397+
[self getGroupUserResultsWithIdentities:userIds
398+
leaderboardPath:LCLeaderboardPathUser
399+
aroundIdentity:nil
400+
option:option
401+
callback:callback];
402+
}
403+
404+
- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
405+
aroundUser:(NSString *)userId
406+
option:(LCLeaderboardQueryOption *)option
407+
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable, NSError * _Nullable))callback
408+
{
409+
[self getGroupUserResultsWithIdentities:userIds
410+
leaderboardPath:LCLeaderboardPathUser
411+
aroundIdentity:userId
412+
option:option
413+
callback:callback];
414+
}
415+
416+
- (void)getGroupUserResultsWithIdentities:(NSArray<NSString *> *)identities
417+
leaderboardPath:(LCLeaderboardPath)leaderboardPath
418+
aroundIdentity:(NSString *)identity
419+
option:(LCLeaderboardQueryOption *)option
420+
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable, NSError * _Nullable))callback
421+
{
422+
if (!identities || identities.count == 0) {
423+
NSError *error = LCError(LCErrorInternalErrorCodeInconsistency, @"First parameter invalid.", nil);
424+
[LCUtils callArrayResultBlock:callback array:nil error:error];
425+
return;
426+
}
427+
NSDictionary *parameters = @{ @"ids" : identities };
428+
NSString *path = [NSString stringWithFormat:@"leaderboard/leaderboards/%@/%@/group/ranks", leaderboardPath, self.statisticName];
429+
if (identity && identity.length > 0) {
430+
path = [path stringByAppendingPathComponent:identity];
431+
}
432+
NSMutableDictionary<NSString *, NSString *> *urlQueryDictionary = [NSMutableDictionary dictionary];
433+
[[self class] trySetOption:option parameters:urlQueryDictionary];
434+
if (!identity && self.skip > 0) {
435+
urlQueryDictionary[@"startPosition"] = @(self.skip).stringValue;
436+
}
437+
if (self.limit > 0) {
438+
urlQueryDictionary[@"maxResultsCount"] = @(self.limit).stringValue;
439+
}
440+
if (self.includeStatistics && self.includeStatistics.count > 0) {
441+
urlQueryDictionary[@"includeStatistics"] = [self.includeStatistics componentsJoinedByString:@","];
442+
}
443+
if (self.version > -1) {
444+
urlQueryDictionary[@"version"] = @(self.version).stringValue;
445+
}
446+
NSString *urlQuery;
447+
if (urlQueryDictionary.count > 0) {
448+
NSMutableArray<NSURLQueryItem *> *queryItems = [NSMutableArray arrayWithCapacity:urlQueryDictionary.count];
449+
for (NSString *key in urlQueryDictionary) {
450+
NSString *value = urlQueryDictionary[key];
451+
NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:key value:value];
452+
[queryItems addObject:queryItem];
453+
}
454+
NSURLComponents *urlComponents = [NSURLComponents componentsWithString:@"http://example.com"];
455+
urlComponents.queryItems = queryItems;
456+
urlQuery = urlComponents.URL.query;
457+
}
458+
if (urlQuery) {
459+
path = [path stringByAppendingFormat:@"?%@", urlQuery];
460+
}
461+
[[LCPaasClient sharedInstance] postObject:path
462+
withParameters:parameters
463+
block:^(id _Nullable object, NSError * _Nullable error) {
464+
if (error) {
465+
[LCUtils callArrayResultBlock:callback array:nil error:error];
466+
return;
467+
}
468+
if ([NSDictionary _lc_isTypeOf:object]) {
469+
NSArray *results = [NSArray _lc_decoding:object key:@"results"];
470+
NSMutableArray<LCLeaderboardRanking *> *rankings = [NSMutableArray arrayWithCapacity:results.count];
471+
for (NSDictionary *item in results) {
472+
if ([NSDictionary _lc_isTypeOf:item]) {
473+
LCLeaderboardRanking *ranking = [[LCLeaderboardRanking alloc] initWithDictionary:item];
474+
[rankings addObject:ranking];
475+
}
476+
}
477+
[LCUtils callArrayResultBlock:callback array:rankings error:nil];
478+
} else {
479+
NSError *error = LCError(LCErrorInternalErrorCodeMalformedData, @"Malformed response data.", nil);
480+
[LCUtils callArrayResultBlock:callback array:nil error:error];
481+
}
482+
}];
483+
}
484+
392485
// MARK: Misc
393486

394487
+ (void)trySetOption:(LCLeaderboardQueryOption * _Nullable)option parameters:(NSMutableDictionary *)parameters {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define SDK_VERSION @"13.8.0"
1+
#define SDK_VERSION @"13.9.0"

LeanCloudObjc.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'LeanCloudObjc'
3-
s.version = '13.8.0'
3+
s.version = '13.9.0'
44
s.homepage = 'https://leancloud.cn/'
55
s.summary = 'LeanCloud Objective-C SDK'
66
s.authors = 'LeanCloud'

0 commit comments

Comments
 (0)