123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- //
- // XSNetwork.m
- // XenonSDK
- //
- // Created by SAGESSE on 2019/5/28.
- // Copyright © 2019 SAGESSE. All rights reserved.
- //
- #import "XenonSDK.h"
- //#import "JSONModel.h"
- #import <JSONModel/JSONModel.h>
- #import "XSTracker.h"
- #import "XSUtils.h"
- //#import "MBProgressHUD.h"
- #import <MBProgressHUD/MBProgressHUD.h>
- #if SDK_HAS_IAP_PAYMENT
- #import "IAPAgnet.h"
- #endif
- @interface XSNetwork ()
- @end
- @implementation XSNetwork
- dispatch_semaphore_t sdk_net_semaphore;
- dispatch_queue_t sdk_net_waiting;
- NSInteger sdk_net_count;
- NSString* sdk_net_baseURL;
- MBProgressHUD* sdk_net_hud;
- + (NSString*)baseURL {
- return sdk_net_baseURL;
- }
- + (void)setBaseURL:(NSString *)baseURL {
- sdk_net_baseURL = baseURL;
- }
- + (NSError*)errorWithCode:(NSInteger)code message:(NSString*)message {
-
- if (message.length == 0) {
- message = @"";
- }
- return [NSError errorWithDomain:@"XSNetwork"
- code:code
- userInfo:@{NSLocalizedDescriptionKey:message}];
- }
- + (void)showHudLoading {
- dispatch_async(dispatch_get_main_queue(), ^{
- [sdk_net_hud removeFromSuperview];
- sdk_net_hud = [MBProgressHUD showHUDAddedTo:UIApplication.sharedApplication.keyWindow animated:YES];
- sdk_net_hud.label.text = nil;
- sdk_net_hud.removeFromSuperViewOnHide = YES;
- [sdk_net_hud layoutIfNeeded];
- [sdk_net_hud showAnimated:YES];
- });
-
- }
- + (void)showHudSuccess:(id)error {
- dispatch_async(dispatch_get_main_queue(), ^{
- [sdk_net_hud removeFromSuperview];
- sdk_net_hud = [MBProgressHUD showHUDAddedTo:UIApplication.sharedApplication.keyWindow animated:YES];
- sdk_net_hud.detailsLabel.text = error;
- sdk_net_hud.userInteractionEnabled = NO;
- sdk_net_hud.mode = MBProgressHUDModeText;
- //hud?.customView = UIImageView(image: UIImage(named: "success", in: nil, compatibleWith: nil))
- sdk_net_hud.removeFromSuperViewOnHide = YES;
- [sdk_net_hud hideAnimated:YES afterDelay:1.8];
- });
- }
- + (void)showHudFailure:(id)error {
-
- NSString* message = error;
- if ([error isKindOfClass:NSError.class]) {
- message = [error localizedDescription];
- }
-
- dispatch_async(dispatch_get_main_queue(), ^{
- [sdk_net_hud removeFromSuperview];
- sdk_net_hud = [MBProgressHUD showHUDAddedTo:UIApplication.sharedApplication.keyWindow animated:YES];
- sdk_net_hud.detailsLabel.text = message;
- sdk_net_hud.userInteractionEnabled = NO;
- sdk_net_hud.mode = MBProgressHUDModeText;
- //hud?.customView = UIImageView(image: UIImage(named: "error", in: nil, compatibleWith: nil))
- sdk_net_hud.removeFromSuperViewOnHide = YES;
- [sdk_net_hud layoutIfNeeded];
- [sdk_net_hud hideAnimated:YES afterDelay:2];
- });
-
-
- }
- + (void)hideHud {
- dispatch_async(dispatch_get_main_queue(), ^{
- [sdk_net_hud removeFromSuperview];
- });
- }
- + (void)showPrompt:(NSString*)user {
-
- // If no user information is provided, it is turned off by default.
- if (user.length == 0) {
- [self showHudSuccess:@"登录成功"];
- return;
- }
-
- // Hide the hud first to prevent errors.
- [self hideHud];
- UIWindow* window = UIApplication.sharedApplication.keyWindow;
- UIView* view = [[UIView alloc] initWithFrame:window.bounds];
-
- UIToolbar* prompt = [[UIToolbar alloc] init];
- UILabel* label = [[UILabel alloc] init];
- // A tag must be set and the view hierarchy needs to be reset when adding a hover window.
- view.tag = -1;
- view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- // Additional actions are allowed during the hud pop-up.
- view.userInteractionEnabled = NO;
- NSMutableAttributedString* value = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"欢迎 %@ 加入游戏", user]];
- [value addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:0 green:0.48 blue:1 alpha:1] range:NSMakeRange(2, user.length + 2)];
- label.attributedText = value;
- label.textAlignment = NSTextAlignmentCenter;
- label.numberOfLines = 0;
- label.font = [UIFont systemFontOfSize:14];
- CGSize size = [label sizeThatFits:CGSizeMake(window.frame.size.width - 80, 0)];
- CGFloat width = fmax(size.width + 32, 120);
- CGFloat height = fmax(size.height + 16, 32);
- CGFloat sp = 8;
- if (UIApplication.sharedApplication.statusBarFrame.size.height < 20) {
- sp += 16;
- }
- CGFloat top = UIApplication.sharedApplication.statusBarFrame.size.height + sp;
- if (@available(iOS 11.0, *)) {
- top = window.safeAreaInsets.top + sp;
- }
- prompt.layer.cornerRadius = 8;
- prompt.layer.masksToBounds = YES;
- prompt.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
- prompt.frame = CGRectMake((window.frame.size.width - width) / 2, top, width, height);
- label.frame = prompt.bounds;
- // [prompt addSubview:label];
- // [view addSubview:prompt];
- // [window addSubview:view];
- prompt.transform = CGAffineTransformMakeTranslation(0, -CGRectGetMaxY(prompt.frame));
- [UIView animateWithDuration:0.25 animations:^{
- prompt.transform = CGAffineTransformIdentity;
- } completion:^(BOOL t) {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [UIView animateWithDuration:0.25 animations:^{
- prompt.transform = CGAffineTransformMakeTranslation(0, -CGRectGetMaxY(prompt.frame));
- } completion:^(BOOL x) {
- [view removeFromSuperview];
- }];
- });
- }];
- }
- + (NSData*)encryptWithParameters:(NSData*)data forKey:(NSString*)key {
- #if SDK_HAS_PROTECT_NETWORK_ENCRYPT
- if (data != nil) {
- NSString* dkey = sdk_md5(key);
- NSData* ddata = sdk_encrypt(data, [dkey substringFromIndex:dkey.length - 8]);
- return [ddata base64EncodedDataWithOptions:0];
- }
- #endif
- return data;
- }
- + (NSData*)decryptWithParameters:(NSData*)data forKey:(NSString*)key {
- #if SDK_HAS_PROTECT_NETWORK_ENCRYPT
- if (data != nil) {
- NSString* dkey = sdk_md5(key);
- NSData* ddata = [[NSData alloc] initWithBase64EncodedData:data options:0];
- return sdk_decrypt(ddata, [dkey substringFromIndex:dkey.length - 8]);
- }
- #endif
- return data;
- }
- + (NSDictionary*)bodyWithParameters:(id)parameters {
- // Generate request header parameters.
- NSString* timestamp = @((NSInteger)(NSDate.new.timeIntervalSince1970 * 1000)).stringValue;
- NSDictionary* header = @{
- @"appId": XenonSDK.sharedSDK.appId,
- @"channelId": XenonSDK.sharedSDK.channelId,
-
- @"adId": XenonSDK.sharedSDK.adId,
- @"adFlag": XenonSDK.sharedSDK.adFlag,
-
- @"sdkVersion": XenonSDK.sharedSDK.version,
- @"gameVersion": XenonSDK.sharedSDK.shortVersion,
-
- @"timestamp": timestamp,
- @"token": XenonSDK.sharedSDK.token ?: @"",
-
- @"osInfo": [NSString stringWithFormat:@"iOS%@", UIDevice.currentDevice.systemVersion],
- @"osType": @"2",
-
- @"idfa": XenonSDK.sharedSDK.advertisingIdentifier,
- @"idfv": XenonSDK.sharedSDK.advertisingVendor,
-
- @"model": XenonSDK.sharedSDK.model,
-
- @"wifi": /*Network.state.SSID ?? */@"Not Found",
- @"networkType": /*Network.state.isWifi ? "1" : */@"2", // 1 is wifi, 2 is other.
-
- @"tdid": XSCollector.shared.identifer ?: @"",
- @"trackData": @"",
-
- @"requestIp": @"",
- @"imei": @"",
- @"mac": @"",
- @"androidid": @"",
-
- @"verificationCode": sdk_signature(parameters, timestamp)
- };
-
- // Generate results, or add parameters dynamically.
- id result = @{
- @"head": header,
- @"body": parameters
- }.mutableCopy;
-
- // When the network needs encryption, 1-12 parameters are generated randomly in order to scramble the ciphertext length.
- #if SDK_HAS_PROTECT_NETWORK_ENCRYPT
- NSMutableArray* arr = [NSMutableArray new];
- for (int i = arc4random() % 12; i > 0; --i) {
- [arr addObject: sdk_md5([NSString stringWithFormat:@"%zu", (NSUInteger)arc4random()])];
- }
- [result setObject:arr forKey:@"other"];
- #endif
-
- return result;
- }
- + (void)busy {
- dispatch_async(dispatch_get_main_queue(), ^{
- sdk_net_count += 1;
- if (sdk_net_count == 1) {
- UIApplication.sharedApplication.networkActivityIndicatorVisible = YES;
- }
- });
- }
- + (void)idle {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (sdk_net_count == 0) {
- return;
- }
- sdk_net_count = sdk_net_count - 1;
- if (sdk_net_count == 0) {
- UIApplication.sharedApplication.networkActivityIndicatorVisible = NO;
- }
- });
- }
- /// Suspended all network requests.
- + (void)suspend {
- if (sdk_net_waiting != nil) {
- return;
- }
- sdk_net_waiting = dispatch_queue_create("XSNetwork", 0);
- sdk_net_semaphore = dispatch_semaphore_create(0);
- dispatch_async(sdk_net_waiting, ^{
- // Lock the thread.
- dispatch_semaphore_wait(sdk_net_semaphore, DISPATCH_TIME_FOREVER);
- });
- }
- /// Resume all network requests.
- + (void)resume {
- if (sdk_net_waiting == nil) {
- return;
- }
- sdk_net_waiting = nil;
- dispatch_semaphore_signal(sdk_net_semaphore);
- sdk_net_semaphore = nil;
- }
- /// Send a request(maybe suspend).
- + (void)requestWithURL:(id)url parameters:(id)parameters model:(Class)model complete:(void(^)(id obj, NSError* error))complete {
- // Need wait from queue?
- if (sdk_net_waiting == nil) {
- [self requestWithoutSuspend:url parameters:parameters model:model complete:complete];
- return;
- }
-
- // Enter waiting status.
- dispatch_async(sdk_net_waiting, ^{
- dispatch_async(dispatch_get_main_queue(), ^{
- [self requestWithoutSuspend:url parameters:parameters model:model complete:complete];
- });
- });
- }
- /// Send a request.
- + (void)requestWithoutSuspend:(id)url parameters:(id)parameters model:(Class)model complete:(void(^)(id obj, NSError* error))complete {
-
- // Generate encryption options.
- #if SDK_HAS_PROTECT_NETWORK_ENCRYPT
- NSUInteger options = arc4random() | 1;
- #else
- NSUInteger options = arc4random() & ~1;
- #endif
-
- // Convert to URL
- NSString* path = [NSString stringWithFormat:@"/data/%@-%@-%@-%zd", XenonSDK.sharedSDK.appId, XenonSDK.sharedSDK.adId, url, options];
- NSURL* req = [NSURL URLWithString:path relativeToURL:[NSURL URLWithString: self.baseURL]];
- if (req == nil) {
- complete(nil, nil);
- return;
- }
-
- // Generate request & parameters.
- NSDictionary* body = [self bodyWithParameters:parameters];
- NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:req cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:60];
- NSError* serror = nil;
- NSData* sdata = [NSJSONSerialization dataWithJSONObject:body options:0 error:&serror];
- if (sdata == nil || serror != nil) {
- complete(nil, serror);
- }
-
- request.HTTPBody = [self encryptWithParameters:sdata forKey:path];
- request.HTTPMethod = @"POST";
- [request addValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
- //#if DEBUG
- // NSLog(@"%@ << %@", path, [[NSString alloc] initWithData:sdata encoding:NSUTF8StringEncoding]);
- //#endif
- // Network start request.
- [self busy];
- // Send a request to server.
- NSURLSessionDataTask* task = [NSURLSession.sharedSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
- // Must be calleback in the main thread.
- dispatch_async(dispatch_get_main_queue(), ^{
-
- // Network request completed.
- [self idle];
-
- // decode data;
- NSData* ddata = [self decryptWithParameters:data forKey:path];
- NSError* derror = nil;
- NSDictionary* djson = nil;
- if (ddata) {
- djson = [NSJSONSerialization JSONObjectWithData:ddata options:0 error:&derror];
- }
-
- // #if DEBUG
- // NSLog(@"%@ >> %@", path, error.description ?: [[NSString alloc] initWithData:ddata encoding:NSUTF8StringEncoding]);
- // #endif
-
- // If data is nil, the request is failure.
- if (data == nil || error != nil || derror != nil) {
- // Request failure for system error.
- complete(nil, error ?: derror);
- return;
- }
-
- id header = djson[@"head"];
- if ([header[@"responseCode"] integerValue] != 0) {
- // Request failure for system error.
- NSInteger code = [header[@"responseCode"] integerValue];
- NSString* message = header[@"responseMsg"];
- complete(nil, [self errorWithCode:code message:message]);
- return;
- }
-
- // In request success case.
- id dbody = djson[@"body"];
- id obj = [[model alloc] initWithDictionary:dbody error:&derror];
- if (obj == nil && derror == nil) {
- obj = dbody;
- }
- complete(obj , derror);
- });
- }];
-
- // Start.
- [task resume];
- }
- /// Request systme configure.
- + (void)configureWithIdentifier:(NSString*)identifier flags:(NSString*)flags complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"0";//"/api/game/v1/active"
- id ps = @{
- @"adId": identifier,
- @"adFlag": flags
- };
-
- // Suspend requests for other.
- [self suspend];
-
- // Send a request to server.
- [self requestWithoutSuspend:url parameters:ps model:XSConfiguration.self complete:^(id obj, NSError *error) {
- // Resume requests for other.
- [self resume];
-
- // Next.
- complete(obj, error);
- }];
- }
- /// Send SMS security code.
- + (void)sendSMSWithPhone:(NSString*)phone type:(NSInteger)type complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"7";//"/api/sms/v1/send"
- id ps = @{
- @"phone": phone,
- @"sendType": @(type).stringValue // 1 bind, 2 forget, 3 login
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:^(id obj, NSError *error) {
- complete(nil, error);
- }];
- }
- /// Auth login.
- + (void)authWithUser:(NSString*)uid complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"1";//"/api/user/v1/checkToken"
- id ps = @{
- @"uid": uid
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:XSUser.self complete:complete];
- }
- /// Check user with phone
- + (void)checkWithPhone:(NSString*)phone complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"5";//"/api/user/v1/checkUserPhone"
- id ps = @{
- @"phone": phone
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:complete];
- }
- /// Bind user with phone.
- + (void)bindWithPhone:(NSString*)phone code:(NSString*)code username:(NSString*)username complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"6";//"/api/user/v1/bindPhone"
- id ps = @{
- @"userName": username,
- @"phone": phone,
- @"code": code
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:complete];
- }
- /// Reset password.
- + (void)resetWithPhone:(NSString*)phone code:(NSString*)code password:(NSString*)password complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"4";//"/api/user/v1/forget"
- id ps = @{
- @"phone": phone,
- @"pwd": [sdk_md5(password) uppercaseString],
- @"code": code
- };
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:complete];
- }
- /// Fast login a user.
- + (void)loginWithComplete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"2";//"/api/user/v1/register"
- id ps = @{
- @"userName": @"",
- @"pwd": @"",
- @"loginType": @"0" // falst login
- };
-
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:XSUser.self complete:^(XSUser* user, NSError *error) {
-
-
- if (user != nil) {
- if (user.isRegister) {
- [XSCollector.shared registerWithAccount:user.uid name:user.userName];
- } else {
- [XSCollector.shared loginWithAccount:user.uid name:user.userName];
- }
- }
-
-
- complete(user, error);
- }];
- }
- /// Phone & Security Code login a user.
- + (void)loginWithPhone:(NSString*)phone code:(NSString*)code complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"3";//"/api/user/v1/login"
- id ps = @{
- @"userName": phone,
- @"pwd": code,
- @"loginType": @"3" // Phone & Security Code login
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:XSUser.self complete:^(XSUser* user, NSError *error) {
-
- user.account = phone;
- user.pwd = nil;
-
- if (user != nil) {
- if (user.isRegister) {
- [XSCollector.shared registerWithAccount:user.uid name:user.userName];
- } else {
- [XSCollector.shared loginWithAccount:user.uid name:user.userName];
- }
- }
-
- complete(user, error);
- }];
- }
- /// Account & Password login a user.
- + (void)loginWithAccount:(NSString*)account password:(NSString*)password complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"3";//"/api/user/v1/login"
- id ps = @{
- @"userName": account,
- @"pwd": [sdk_md5(password) uppercaseString],
- @"loginType": @"1" // account login
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:XSUser.self complete:^(XSUser* user, NSError *error) {
- user.account = account;
- user.pwd = password;
-
- if (user != nil) {
- [XSCollector.shared loginWithAccount:user.uid name:user.userName];
- }
-
- complete(user, error);
- }];
- }
- /// Account & Password login a user.
- + (void)registerWithAccount:(NSString*)account password:(NSString*)password complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"2";//"/api/user/v1/register"
- id ps = @{
- @"userName": account,
- @"pwd": [sdk_md5(password) uppercaseString],
- @"loginType": @"1" // account login
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:XSUser.self complete:^(XSUser* user, NSError *error) {
- user.account = account;
- user.pwd = password;
- user.isRegister = YES;
-
- if (user != nil) {
- [XSCollector.shared registerWithAccount:user.uid name:user.userName];
- }
-
- complete(user, error);
- }];
- }
- // MARK - 广告记录
- +(void)adRecord:(NSString *)action
- spaceId:(NSString *)spaceId
- agentName:(NSString *)agentName
- medium:(NSString *)medium
- adUnitId:(NSString *)adUnitId
- type:(NSString *)type
- unitAdId:(NSString *)unitAdId
- errorMsg:(NSString *)errorMeg{
-
- NSString *uid = [XenonSDK sharedSDK].user.uid;
-
- //广告组ID,在plist文件里配置.
- //NSBundle *mainBundle = [NSBundle mainBundle];
- //NSString *unitAdId1 = mainBundle.infoDictionary[@"ironsource-app-unitAdId"];
-
- id url = @"e"; //"/api/game/v1/adAction"
- id ps = @{
- @"action": action,
- @"spaceId": spaceId,
- @"uid" : uid? uid:@"",
- @"agentName" : agentName,
- @"medium" : medium,
- @"adUnitId" : adUnitId? adUnitId:@"",
- @"type" : type,
- @"unitAdId" : unitAdId,
- @"errmsg" : errorMeg
- };
-
- // Send a request to server.
- [self requestWithoutSuspend:url parameters:ps model:XSUser.self complete:^(id obj, NSError *error) {
- //complete(obj, error);
- }];
- }
- // MARK - Utils
- /// Auto trigger;
- + (void)trigger:(NSInteger)count {
- #if SDK_HAS_PROTECT_NETWORK_PRETEND
- // If tracking is not enabled, turn it off.
- if (XSTracker.shared == nil) {
- return;
- }
-
- // Prepare request parameters.
- NSString* url = @"*";
- NSMutableDictionary* ps = [NSMutableDictionary new];
-
- for (int i = arc4random() % 12 + 1; i > 0; --i) {
- id key = [sdk_md5(@(arc4random()).stringValue) substringToIndex:((arc4random() % 14) + 1)];
- id value = [[key dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
- ps[key] = value;
- }
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:^(id obj, NSError *error) {
-
- if (error == nil || count > 0) {
- return;
- }
-
- NSInteger ft = arc4random() % 10000;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_MSEC * ft), dispatch_get_main_queue(), ^{
- [self trigger:count - 1];
- });
- }];
- #endif
- }
- + (void)log:(NSInteger)code session:(NSString*)session extra:(NSString*)extra {
-
- // Prepare request parameters.
- id url = @"9";//"/api/ardent/v1/add"
- id ps = @{
- @"digitId": [NSString stringWithFormat:@"0x%06zx", code],
- @"sessionId": session,
- @"iosStr": extra
- };
-
- // Send a request to server.
- [self requestWithoutSuspend:url parameters:ps model:nil complete:^(id obj, NSError *error) {
- // Nothing.
- }];
- }
- + (void)reportWithUser:(NSString*)uid Name:(NSString*)name level:(NSInteger)level server:(NSString*)server {
- // Prepare request parameters.
- id url = @"a";//"/api/game/v1/sendServer"
- id ps = @{
- @"uid": uid ?: @"",
- @"gameServerId": server,
- @"roleLev": @(level).stringValue,
- @"roleName": name
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:^(id obj, NSError *error) {
- }];
- }
- /// Get pay route.
- + (void)routeWithComplete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"8";//"/api/p/v1/pCheck"
- id ps = @{
- @"uid": XenonSDK.sharedSDK.user.uid ?: @""
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:complete];
- }
- #if SDK_HAS_IAP_PAYMENT
- /// Pay a product.
- + (void)payWithParameters:(id)parameters complete:(void(^)(id object, NSError* error))complete {
-
- // Prepare request parameters.
- id url = @"b";//"/api/p/v1/apple/create"
- id ps = parameters;
-
- // Check if in-app purchases are available.
- if (!SKPaymentQueue.canMakePayments) {
- complete(nil, [XSNetwork errorWithCode:-2 message:@"该设备不支持内购"]);
- return;
- }
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:^(id obj, NSError *error) {
-
- if (error != nil) {
- complete(nil, error);
- return;
- }
-
- // Get prarmeter
- NSString* orderId = [obj valueForKeyPath:@"orderId"];
- NSString* productId = [obj valueForKeyPath:@"product.productId"];
-
- if (orderId.length == 0 || productId.length == 0) {
- complete(nil, [XSNetwork errorWithCode:-2 message:@"服务器异常"]);
- return;
- }
-
- IAPAgnet* agnet = [[IAPAgnet alloc] init];
- SKProductsRequest* request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productId]];
-
- agnet.productId = productId;
- agnet.orderId = orderId;
- static IAPAgnet* value = nil;
- value = agnet;
-
- [agnet prepare];
-
- [agnet setCallback:^(id order, NSError *error) {
-
- [value clean];
- value.callback = nil;
- request.delegate = nil;
-
- if (error != nil) {
- complete(nil, error);
- return;
- }
-
- // Upload receipt information.TTOO:
- [self payWithReceipt:order orderId:orderId complete:complete];
- }];
-
- request.delegate = agnet;
- [request start];
- }];
- }
- /// Pay a product with receipt. 客户端发送苹果的票据到服务器端校验.
- + (void)payWithReceipt:(id)receipt orderId:(id)orderId complete:(void(^)(id object, NSError* error))complete {
- // Prepare request parameters.
- id url = @"c";//"/api/p/v1/apple/p"
- id ps = @{
- @"data": receipt,
- @"orderId": orderId,
- @"uid": XenonSDK.sharedSDK.user.uid ?: @""
- };
-
- // Send a request to server.
- [self requestWithURL:url parameters:ps model:nil complete:complete];
- }
- #endif
- @end
|