Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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