Skip to content

Commit

Permalink
Merge pull request #692 from zapcannon87/master
Browse files Browse the repository at this point in the history
feat(leaderboard): get rankings of a group of user
  • Loading branch information
zapcannon87 authored May 16, 2022
2 parents 83d4ba7 + 31fbb85 commit 272a553
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 3 deletions.
82 changes: 82 additions & 0 deletions AVOS/LeanCloudObjcTests/LCLeaderboardTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -565,4 +565,86 @@ class LCLeaderboardTestCase: BaseTestCase {
}
}
}

func testGetGroupUserRankings() {
let object = LCObject()
XCTAssertTrue(object.save())
let user = LCUser()
let objectFieldKey = "objectField"
user[objectFieldKey] = object
expecting { exp in
user.login(withAuthData: ["openid" : uuid], platformId: "test", options: nil) { _, error in
XCTAssertNil(error)
exp.fulfill()
}
}
guard let userObjectId = user.objectId else {
XCTFail()
return
}

let statisticName0 = "test-user-0"
let statisticName1 = "test-user-1"
var statistic0version = -1
var statistic1version = -1

expecting { exp in
LCLeaderboard.updateCurrentUserStatistics(
[statisticName0 : 100,
statisticName1 : 100])
{ statistics, error in
XCTAssertEqual(statistics?.count, 2)
XCTAssertNil(error)
XCTAssertNotEqual(statistics?.first?.name, statistics?.last?.name)
for item in statistics ?? [] {
XCTAssertTrue([statisticName0, statisticName1].contains(item.name ?? ""))
XCTAssertEqual(item.value, 100)
XCTAssertGreaterThanOrEqual(item.version, 0)
if (item.name ?? "") == statisticName0 {
statistic0version = item.version
} else {
statistic1version = item.version
}
}
exp.fulfill()
}
}

let leaderboard0 = LCLeaderboard(statisticName: statisticName0)
let leaderboard1 = LCLeaderboard(statisticName: statisticName1)
let option = LCLeaderboardQueryOption()
option.selectKeys = [objectFieldKey]
option.includeKeys = [objectFieldKey]

expecting(count: 2) { exp in
leaderboard0.limit = 1
leaderboard0.includeStatistics = [statisticName1]
leaderboard0.version = statistic0version
leaderboard0.getGroupUserResults(withUserIds: [userObjectId], aroundUser: userObjectId, option: option) { rankings, error in
XCTAssertEqual(rankings?.count, 1)
XCTAssertNil(error)
for item in rankings ?? [] {
XCTAssertEqual(item.statisticName, leaderboard0.statisticName)
XCTAssertGreaterThanOrEqual(item.rank, 0)
XCTAssertEqual(item.value, 100)
XCTAssertEqual(item.includedStatistics?.first?.name, statisticName1)
XCTAssertEqual(item.includedStatistics?.first?.value, 100)
XCTAssertEqual(item.user?.objectId, userObjectId)
XCTAssertNotNil((item.user?[objectFieldKey] as? LCObject)?.createdAt)
XCTAssertNil(item.object)
XCTAssertNil(item.entity)
}
exp.fulfill()
}
leaderboard1.skip = 1
leaderboard1.version = statistic1version
leaderboard1.getGroupUserResults(withUserIds: [userObjectId], option: option) { rankings, error in
for item in rankings ?? [] {
XCTAssertNotEqual(item.rank, 0)
}
XCTAssertNil(error)
exp.fulfill()
}
}
}
}
18 changes: 18 additions & 0 deletions AVOS/Sources/Foundation/Leaderboard/LCLeaderboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,24 @@ NS_ASSUME_NONNULL_BEGIN
- (void)getEntityResultsAroundEntity:(NSString * _Nullable)entity
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable rankings, NSInteger count, NSError * _Nullable error))callback;

/// Get rankings of a group of user on this leaderboard.
/// @param userIds A group of user's object id.
/// @param option The query option, see `LCLeaderboardQueryOption`.
/// @param callback Result callback.
- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
option:(LCLeaderboardQueryOption * _Nullable)option
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable rankings, NSError * _Nullable error))callback;

/// Get rankings of a group of user around one user on this leaderboard.
/// @param userIds A group of user's object id.
/// @param userId The object id of the around user.
/// @param option The query option, see `LCLeaderboardQueryOption`.
/// @param callback Result callback.
- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
aroundUser:(NSString * _Nullable)userId
option:(LCLeaderboardQueryOption * _Nullable)option
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable rankings, NSError * _Nullable error))callback;

@end

NS_ASSUME_NONNULL_END
95 changes: 94 additions & 1 deletion AVOS/Sources/Foundation/Leaderboard/LCLeaderboard.m
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ - (void)getStatisticsWithIdentities:(NSArray<NSString *> *)identities
});
return;
}
NSDictionary *parameters = @{ @"ids" : identities };
NSString *path = [NSString stringWithFormat:@"leaderboard/%@/statistics/%@", leaderboardPath, self.statisticName];
if (option) {
NSMutableArray<NSString *> *queryStrings = [NSMutableArray array];
Expand All @@ -274,7 +275,7 @@ - (void)getStatisticsWithIdentities:(NSArray<NSString *> *)identities
}
}
[[LCPaasClient sharedInstance] postObject:path
withParameters:identities
withParameters:parameters
block:^(id _Nullable object, NSError * _Nullable error) {
[[self class] handleStatisticsCallback:callback error:error object:object];
}];
Expand Down Expand Up @@ -389,6 +390,98 @@ - (void)getResultsAroundIdentity:(NSString *)identity
}];
}

- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
option:(LCLeaderboardQueryOption *)option
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable, NSError * _Nullable))callback
{
[self getGroupUserResultsWithIdentities:userIds
leaderboardPath:LCLeaderboardPathUser
aroundIdentity:nil
option:option
callback:callback];
}

- (void)getGroupUserResultsWithUserIds:(NSArray<NSString *> *)userIds
aroundUser:(NSString *)userId
option:(LCLeaderboardQueryOption *)option
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable, NSError * _Nullable))callback
{
[self getGroupUserResultsWithIdentities:userIds
leaderboardPath:LCLeaderboardPathUser
aroundIdentity:userId
option:option
callback:callback];
}

- (void)getGroupUserResultsWithIdentities:(NSArray<NSString *> *)identities
leaderboardPath:(LCLeaderboardPath)leaderboardPath
aroundIdentity:(NSString *)identity
option:(LCLeaderboardQueryOption *)option
callback:(void (^)(NSArray<LCLeaderboardRanking *> * _Nullable, NSError * _Nullable))callback
{
if (!identities || identities.count == 0) {
NSError *error = LCError(LCErrorInternalErrorCodeInconsistency, @"First parameter invalid.", nil);
[LCUtils callArrayResultBlock:callback array:nil error:error];
return;
}
NSDictionary *parameters = @{ @"ids" : identities };
NSString *path = [NSString stringWithFormat:@"leaderboard/leaderboards/%@/%@/group/ranks", leaderboardPath, self.statisticName];
if (identity && identity.length > 0) {
path = [path stringByAppendingPathComponent:identity];
}
NSMutableDictionary<NSString *, NSString *> *urlQueryDictionary = [NSMutableDictionary dictionary];
[[self class] trySetOption:option parameters:urlQueryDictionary];
if (!identity && self.skip > 0) {
urlQueryDictionary[@"startPosition"] = @(self.skip).stringValue;
}
if (self.limit > 0) {
urlQueryDictionary[@"maxResultsCount"] = @(self.limit).stringValue;
}
if (self.includeStatistics && self.includeStatistics.count > 0) {
urlQueryDictionary[@"includeStatistics"] = [self.includeStatistics componentsJoinedByString:@","];
}
if (self.version > -1) {
urlQueryDictionary[@"version"] = @(self.version).stringValue;
}
NSString *urlQuery;
if (urlQueryDictionary.count > 0) {
NSMutableArray<NSURLQueryItem *> *queryItems = [NSMutableArray arrayWithCapacity:urlQueryDictionary.count];
for (NSString *key in urlQueryDictionary) {
NSString *value = urlQueryDictionary[key];
NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:key value:value];
[queryItems addObject:queryItem];
}
NSURLComponents *urlComponents = [NSURLComponents componentsWithString:@"http://example.com"];
urlComponents.queryItems = queryItems;
urlQuery = urlComponents.URL.query;
}
if (urlQuery) {
path = [path stringByAppendingFormat:@"?%@", urlQuery];
}
[[LCPaasClient sharedInstance] postObject:path
withParameters:parameters
block:^(id _Nullable object, NSError * _Nullable error) {
if (error) {
[LCUtils callArrayResultBlock:callback array:nil error:error];
return;
}
if ([NSDictionary _lc_isTypeOf:object]) {
NSArray *results = [NSArray _lc_decoding:object key:@"results"];
NSMutableArray<LCLeaderboardRanking *> *rankings = [NSMutableArray arrayWithCapacity:results.count];
for (NSDictionary *item in results) {
if ([NSDictionary _lc_isTypeOf:item]) {
LCLeaderboardRanking *ranking = [[LCLeaderboardRanking alloc] initWithDictionary:item];
[rankings addObject:ranking];
}
}
[LCUtils callArrayResultBlock:callback array:rankings error:nil];
} else {
NSError *error = LCError(LCErrorInternalErrorCodeMalformedData, @"Malformed response data.", nil);
[LCUtils callArrayResultBlock:callback array:nil error:error];
}
}];
}

// MARK: Misc

+ (void)trySetOption:(LCLeaderboardQueryOption * _Nullable)option parameters:(NSMutableDictionary *)parameters {
Expand Down
2 changes: 1 addition & 1 deletion AVOS/Sources/Foundation/UserAgent.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define SDK_VERSION @"13.8.0"
#define SDK_VERSION @"13.9.0"
2 changes: 1 addition & 1 deletion LeanCloudObjc.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'LeanCloudObjc'
s.version = '13.8.0'
s.version = '13.9.0'
s.homepage = 'https://leancloud.cn/'
s.summary = 'LeanCloud Objective-C SDK'
s.authors = 'LeanCloud'
Expand Down

0 comments on commit 272a553

Please sign in to comment.