Files
peko-ios/YuMi/Modules/YMMine/View/Recharge/IAPManager.m

744 lines
26 KiB
Mathematica
Raw Normal View History

2024-09-24 18:01:08 +08:00
//
// IAPManager.m
// YuMi
//
// Created by P on 2024/9/24.
//
#import "IAPManager.h"
#import <Bugly/Bugly.h>
2024-09-24 18:01:08 +08:00
#import "Api+Mine.h"
#import "YuMi-swift.h"
#import "RechargeStorage.h"
#define MAX_RETRY_COUNT 50
2024-09-24 18:01:08 +08:00
@interface IAPManager()
2024-09-27 11:17:04 +08:00
@property (nonatomic, assign) BOOL isLogin;
@property (nonatomic, assign) NSInteger recheckInterval;
@property (nonatomic, assign) NSInteger recheckIndex;
@property (nonatomic, strong) NSTimer *recheckTimer;
@property (nonatomic, assign) BOOL isProcessing;
2024-09-24 18:01:08 +08:00
@property (nonatomic, copy) NSString *orderID;
@property (nonatomic, copy) NSString *transactionID;
2024-09-27 11:17:04 +08:00
@property (nonatomic, copy) void(^successPurchase)(NSString *transactionID, NSString *orderID);
@property (nonatomic, copy) void(^successRecheck)(void);
2024-09-24 18:01:08 +08:00
@property (nonatomic, copy) void(^failurePurchase)(NSError *error);
@property (nonatomic, copy) void(^contactCustomerService)(NSString *uid);
//
@property (nonatomic, strong) NSMutableDictionary *retryCountDict;
// 线
@property (nonatomic, strong) dispatch_queue_t retryCountQueue;
2024-09-24 18:01:08 +08:00
@end
@implementation IAPManager
+ (instancetype)sharedManager {
static IAPManager *proxy;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
proxy = [[self alloc] init];
2024-09-27 11:17:04 +08:00
proxy.recheckIndex = 0;
proxy.recheckInterval = 1.0;
proxy.retryCountDict = [NSMutableDictionary dictionary];
proxy.retryCountQueue = dispatch_queue_create("com.iapmanager.retrycount.queue", DISPATCH_QUEUE_CONCURRENT);
proxy.isProcessing = NO;
proxy.isLogin = NO;
2024-09-24 18:01:08 +08:00
});
return proxy;
}
2024-09-27 11:17:04 +08:00
- (void)handleLogin {
self.isLogin = YES;
}
- (void)handleLogout {
self.isLogin = NO;
if (self.recheckTimer) {
[self.recheckTimer invalidate];
}
}
- (NSString *)fetchEncodedReceipt {
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
if (!receiptData) return nil;
return [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
}
- (BOOL)isValidTransactionID:(NSString *)tID orderID:(NSString *)orderID {
return (tID.length > 0 && orderID.length > 0);
}
2024-09-27 11:17:04 +08:00
//
2024-09-24 18:01:08 +08:00
- (void)purchase:(NSString *)productId
2024-09-27 11:17:04 +08:00
success:(void(^)(NSString *transactionID, NSString *orderID))success
2024-09-24 18:01:08 +08:00
failure:(void(^)(NSError *error))failure
contactCS:(void(^)(NSString *uid))contactCS {
self.successPurchase = success;
self.failurePurchase = failure;
self.contactCustomerService = contactCS;
[self handleIAPState];
2024-09-27 11:17:04 +08:00
[self requestAPPOrderData:productId isFroRecheck:NO];
}
//
- (void)retryCheckAllReceipt {
//
if (self.recheckTimer) {
[self.recheckTimer invalidate];
self.recheckTimer = nil;
}
//
[self cleanupStaleTransactions];
//
NSTimeInterval interval = MIN(self.recheckInterval, 300.0);
// 使iOS
self.recheckTimer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(handleRetryCheckReceipt)
userInfo:nil
repeats:NO];
//
[[NSRunLoop mainRunLoop] addTimer:self.recheckTimer forMode:NSRunLoopCommonModes];
2024-09-27 11:17:04 +08:00
}
//
- (void)handleRetryCheckReceipt {
NSLog(@"[YuMi IAP] 用户触发补单检查 - Retry checking receipts");
//
if (self.isProcessing || !self.isLogin) {
//
if (self.recheckTimer) {
[self.recheckTimer invalidate];
self.recheckTimer = nil;
2024-09-27 11:17:04 +08:00
}
//
self.recheckInterval = MIN(self.recheckInterval * 1.5, 300.0);
[self retryCheckAllReceipt];
return;
}
NSArray *array = [RechargeStorage getAllReceiptsWithUid:[AccountInfoStorage instance].getUid];
NSLog(@" ------------.------------ 尝试:%@", array);
//
if (array.count == 0) {
NSLog(@" ------------.------------ 没有需要验单的数据");
if (self.recheckTimer) {
[self.recheckTimer invalidate];
self.recheckTimer = nil;
2024-09-27 11:17:04 +08:00
}
// 10
self.recheckInterval = 600.0;
[self retryCheckAllReceipt];
return;
}
//
if (self.recheckIndex >= array.count) {
self.recheckIndex = 0;
}
//
self.isProcessing = YES;
//
NSDictionary *dic = [array xpSafeObjectAtIndex:self.recheckIndex];
NSString *transactionId = dic[@"transactionId"];
NSString *orderId = dic[@"orderId"];
//
[self _logToBugly:transactionId oID:orderId status:0];
//
NSInteger retryCount = [self getRetryCountForTransaction:transactionId];
if (retryCount > MAX_RETRY_COUNT) {
//
[self _logToBugly:transactionId oID:orderId status:4]; //
[RechargeStorage delegateTransactionId:transactionId uid:[AccountInfoStorage instance].getUid];
[self removeRetryCountForTransaction:transactionId];
//
self.isProcessing = NO;
//
self.recheckIndex = (self.recheckIndex + 1) % array.count;
if (self.recheckTimer) {
[self.recheckTimer invalidate];
self.recheckTimer = nil;
}
[self retryCheckAllReceipt];
return;
}
//
[self incrementRetryCountForTransaction:transactionId];
@kWeakify(self);
[self backgroundCheckReceiptWithTransactionID:transactionId
orderID:orderId
next:^(BOOL isSuccess){
@kStrongify(self);
if (isSuccess) {
//
[RechargeStorage delegateTransactionId:transactionId
uid:[AccountInfoStorage instance].getUid];
//
self.recheckInterval = MAX(self.recheckInterval / 2, 1.0);
[self _logToBugly:transactionId oID:orderId status:1];
//
[self removeRetryCountForTransaction:transactionId];
} else {
//
self.recheckInterval = MIN(self.recheckInterval * 1.5, 300.0);
[self _logToBugly:transactionId oID:orderId status:2];
}
//
self.recheckIndex = (self.recheckIndex + 1) % array.count;
//
self.isProcessing = NO;
//
if (self.recheckTimer) {
2024-09-27 11:17:04 +08:00
[self.recheckTimer invalidate];
self.recheckTimer = nil;
}
[self retryCheckAllReceipt];
}];
2024-09-24 18:01:08 +08:00
}
- (void)_logToBugly:(NSString *)tid oID:(NSString *)oid status:(NSInteger)status {
NSMutableDictionary *logDic = [NSMutableDictionary dictionary];
// ID
if ([NSString isEmpty:tid]) {
[logDic setObject:@"" forKey:@"内购 transactionId"];
tid = @"";
} else {
[logDic setObject:tid forKey:@"内购 transactionId"];
}
// ID
if ([NSString isEmpty:oid]) {
[logDic setObject:@"" forKey:@"内购 orderId"];
} else {
[logDic setObject:oid forKey:@"内购 orderId"];
}
// ID
NSString *uid = [AccountInfoStorage instance].getUid ?: @"未知用户";
[logDic setObject:uid forKey:@"内购 用户id"];
//
[logDic setObject:@([self getRetryCountForTransaction:tid]) forKey:@"重试次数"];
[logDic setObject:@(self.recheckInterval) forKey:@"重试间隔"];
[logDic setObject:@(self.recheckIndex) forKey:@"当前索引"];
[logDic setObject:@(self.isProcessing) forKey:@"处理中状态"];
[logDic setObject:@(self.isLogin) forKey:@"登录状态"];
NSString *statusMsg = @"";
NSInteger code = -20000;
switch (status) {
case 0:
statusMsg = [NSString stringWithFormat:@"UID: %@, 尝试验单", uid];
break;
case 1:
statusMsg = [NSString stringWithFormat:@"UID: %@, 验单-补单成功", uid];
code = -20001;
break;
case 2:
statusMsg = [NSString stringWithFormat:@"UID: %@, 验单-补单失败", uid];
code = -20002;
break;
case 3:
statusMsg = [NSString stringWithFormat:@"UID: %@, 验单-补单 id 异常", uid];
code = -20002;
break;
case 4:
statusMsg = [NSString stringWithFormat:@"UID: %@, 重试次数过多", uid];
code = -20003;
break;
case 5:
statusMsg = [NSString stringWithFormat:@"UID: %@, 过期交易清理", uid];
code = -20004;
break;
default:
break;
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[Bugly reportError:[NSError errorWithDomain:statusMsg
code:code
userInfo:logDic]];
});
}
2024-09-27 11:17:04 +08:00
//
- (void)handleSuccessPurchase:(NSString *)tID order:(NSString *)orderID {
2024-09-24 18:01:08 +08:00
if (self.successPurchase) {
@kWeakify(self);
dispatch_async(dispatch_get_main_queue(), ^{
@kStrongify(self);
2024-09-27 11:17:04 +08:00
self.successPurchase(tID, orderID);
});
}
if (self.successRecheck) {
@kWeakify(self);
dispatch_async(dispatch_get_main_queue(), ^{
@kStrongify(self);
self.successRecheck();
2024-09-24 18:01:08 +08:00
});
}
}
2024-09-27 11:17:04 +08:00
//
2024-09-24 18:01:08 +08:00
- (void)handleFailurePurchase:(NSString *)errorMsg {
if (self.failurePurchase) {
@kWeakify(self);
dispatch_async(dispatch_get_main_queue(), ^{
@kStrongify(self);
if (errorMsg.length == 0) {
self.failurePurchase(nil);
} else {
self.failurePurchase([NSError errorWithDomain:errorMsg code:-1 userInfo:nil]);
}
});
}
}
2024-09-27 11:17:04 +08:00
//
2024-09-24 18:01:08 +08:00
- (void)handleContactCS {
@kWeakify(self);
dispatch_async(dispatch_get_main_queue(), ^{
@kStrongify(self);
TTAlertConfig *config = [[TTAlertConfig alloc]init];
config.title = YMLocalizedString(@"XPIAPRechargeViewController7");
config.message = YMLocalizedString(@"XPIAPRechargeViewController8");
TTAlertButtonConfig *confirmButtonConfig = [[TTAlertButtonConfig alloc]init];
confirmButtonConfig.title = YMLocalizedString(@"XPIAPRechargeViewController9");
UIImage *image = [UIImage gradientColorImageFromColors:@[UIColorFromRGB(0x13E2F5),UIColorFromRGB(0x9DB4FF),UIColorFromRGB(0xCC67FF)] gradientType:GradientTypeLeftToRight imgSize:CGSizeMake(200, 200)];
confirmButtonConfig.backgroundColor = [UIColor colorWithPatternImage:image];
confirmButtonConfig.cornerRadius = 38/2;
config.confirmButtonConfig = confirmButtonConfig;
@kWeakify(self);
[TTPopup alertWithConfig:config confirmHandler:^{
@kStrongify(self);
[self loadCSUid];
} cancelHandler:^{}];
});
}
2024-09-27 11:17:04 +08:00
// UID
- (void)loadCSUid {
if (self.contactCustomerService) {
[Api requestContactCustomerServiceCompletion:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200) {
NSString *uid = [NSString stringWithFormat:@"%@",data.data];
self.contactCustomerService(uid);
}
}];
}
}
//
2024-09-24 18:01:08 +08:00
- (void)handleIAPState {
if (@available(iOS 15.0, *)) {
@kWeakify(self);
2024-09-27 11:17:04 +08:00
[[PIIAPRegulate shared] setConditionBlock:^(enum StoreConditionResult state, NSDictionary<NSString *,NSString *> * _Nullable param) {
2024-09-24 18:01:08 +08:00
@kStrongify(self);
switch (state) {
case StoreConditionResultStart:
NSLog(@"~~~```~~~ Purchase started");
2024-09-24 18:01:08 +08:00
break;
case StoreConditionResultPay:
NSLog(@"~~~```~~~ Processing payment");
2024-09-24 18:01:08 +08:00
break;
case StoreConditionResultVerifiedServer:
NSLog(@"~~~```~~~ Verified by server");
2024-09-24 18:01:08 +08:00
[self handleIAPSuccess:param];
break;
case StoreConditionResultUserCancelled:
NSLog(@"~~~```~~~ User cancelled purchase");
2024-09-24 18:01:08 +08:00
[self handleFailurePurchase:@""];
break;
case StoreConditionResultNoProduct:
NSLog(@"~~~```~~~ No product found");
2024-09-24 18:01:08 +08:00
[self handleFailurePurchase:[NSString stringWithFormat:@"%@ No product found", YMLocalizedString(@"XPIAPRechargeViewController1")]];
break;
case StoreConditionResultFailedVerification:
NSLog(@"~~~```~~~ Verification failed");
2024-09-24 18:01:08 +08:00
[self handleFailurePurchase:YMLocalizedString(@"XPIAPRechargeViewController1")];
break;
case StoreConditionResultUnowned:
NSLog(@"~~~```~~~ Result Unowned");
2024-09-24 18:01:08 +08:00
[self handleFailurePurchase:YMLocalizedString(@"XPIAPRechargeViewController1")];
break;
default:
[self handleFailurePurchase:YMLocalizedString(@"XPIAPRechargeViewController0")];
break;
}
}];
}
}
//
2024-09-27 11:17:04 +08:00
- (void)requestAPPOrderData:(NSString *)productId isFroRecheck:(BOOL)isFroRecheck {
2024-09-24 18:01:08 +08:00
if (@available(iOS 15.0, *)) {
@kWeakify(self);
[Api requestIAPRecharge:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
2024-09-27 11:17:04 +08:00
if (isFroRecheck) {
return;
}
2024-09-24 18:01:08 +08:00
@kStrongify(self);
if (code == 200) {
NSString *orderId = (NSString *)data.data[@"recordId"];
NSString *uuid = (NSString *)data.data[@"appAccountToken"];
[self requestIAPOrder:orderId
productID:productId
uuid:uuid];
} else if (code == 50000) {
[self handleContactCS];
[self handleFailurePurchase:@""];
} else {
[self handleFailurePurchase:msg];
}
}
chargeProdId:productId
uid:[AccountInfoStorage instance].getUid
ticket:[AccountInfoStorage instance].getTicket
deviceInfo:[YYUtility deviceID]
clientIp:[YYUtility ipAddress]];
} else {
[self handleFailurePurchase:YMLocalizedString(@"XPIAPRechargeViewController10")];
}
}
2024-09-27 11:17:04 +08:00
// 线 productID PIIAPRegulate - purchase
2024-09-24 18:01:08 +08:00
- (void)requestIAPOrder:(NSString *)orderID productID:(NSString *)productID uuid:(NSString *)uuid {
self.orderID = orderID;
if (@available(iOS 15.0, *)) {
2024-09-27 11:17:04 +08:00
// @kWeakify(self);
2024-09-24 18:01:08 +08:00
[[PIIAPRegulate shared] demandCommodityThingWithProductId:productID
uuid:uuid
completionHandler:^(NSError * _Nullable error) {
2024-09-27 11:17:04 +08:00
// @kStrongify(self);
2024-09-24 18:01:08 +08:00
if (error) {
// ConditionBlock
}
}];
}
}
//
- (void)handleIAPSuccess:(NSDictionary *)param {
2024-09-27 11:17:04 +08:00
id tid = param[@"transactionId"];
self.transactionID = tid;
2024-09-24 18:01:08 +08:00
if (self.transactionID.length == 0) {
[self handleFailurePurchase:YMLocalizedString(@"XPIAPRechargeViewController1")];
return;
}
[self saveTransactionID];
2024-09-27 11:17:04 +08:00
[self checkReceiptWithTransactionID:self.transactionID
orderID:self.orderID];
2024-09-24 18:01:08 +08:00
}
// id
- (void)saveTransactionID {
NSString *encodedReceipt = [self fetchEncodedReceipt];
2024-09-24 18:01:08 +08:00
NSMutableDictionary *receiptInfo = [NSMutableDictionary dictionary];
2024-09-24 18:01:08 +08:00
[self addValueIfNotNil:self.transactionID forKey:@"transactionId" toDictionary:receiptInfo];
[self addValueIfNotNil:encodedReceipt forKey:@"receipt" toDictionary:receiptInfo];
[self addValueIfNotNil:self.orderID forKey:@"orderId" toDictionary:receiptInfo];
// 便
[receiptInfo setObject:[[NSDate date] description] forKey:@"timestamp"];
2024-09-27 11:17:04 +08:00
@synchronized (self.transactionID) {
[RechargeStorage saveTransactionId:self.transactionID
receipt:[receiptInfo toJSONString]
uid:[AccountInfoStorage instance].getUid];
2024-09-27 11:17:04 +08:00
}
2024-09-24 18:01:08 +08:00
}
//
// MARK:
2024-09-27 11:17:04 +08:00
- (void)checkReceiptWithTransactionID:(NSString *)tID
orderID:(NSString *)orderID {
NSLog(@" ------------.------------ 后端验单:%@ | %@", tID, orderID);
2024-09-27 11:17:04 +08:00
2024-09-24 18:01:08 +08:00
@kWeakify(self);
[Api checkReceipt:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
if (code == 200) {
2024-09-27 11:17:04 +08:00
[self handleSuccessPurchase:tID order:orderID];
[self handleCheckReceiptSuccess:tID isFromRecheck:NO];
2024-09-24 18:01:08 +08:00
} else {
[self handleFailurePurchase:msg];
if (code == 1444) {
2024-09-27 11:17:04 +08:00
//
2024-09-24 18:01:08 +08:00
}
}
NSLog(@" ------------.------------ 后端验单结果:%@ ",msg);
2024-09-24 18:01:08 +08:00
}
chooseEnv:@"true"
2024-09-27 11:17:04 +08:00
chargeRecordId:orderID
transcationId:tID
2024-09-24 18:01:08 +08:00
uid:[AccountInfoStorage instance].getUid
ticket:[AccountInfoStorage instance].getTicket];
}
2024-09-27 11:17:04 +08:00
//
- (void)backgroundCheckReceiptWithTransactionID:(NSString *)tID
orderID:(NSString *)orderID
next:(void(^)(BOOL isSuccess))next {
//
if (![self isValidTransactionID:tID orderID:orderID]) {
if (next) {
next(NO);
}
return;
}
//
UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"VerifyReceipt"
expirationHandler:^{
//
if (next) {
next(NO);
}
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
}];
2024-09-27 11:17:04 +08:00
//
2024-09-27 11:17:04 +08:00
@kWeakify(self);
[Api checkReceipt:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
BOOL isSuccess = (code == 200);
if (isSuccess) {
[self handleCheckReceiptSuccess:tID isFromRecheck:YES];
NSLog(@" ------------.------------ 后台验单成功:%@ | %@", tID, orderID);
} else {
NSLog(@" ------------.------------ 后台验单失败:%@ | %@ | %@", tID, orderID, msg);
}
//
if (next) {
next(isSuccess);
}
2024-09-27 11:17:04 +08:00
//
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
2024-09-27 11:17:04 +08:00
}
chooseEnv:@"true"
chargeRecordId:orderID
transcationId:tID
uid:[AccountInfoStorage instance].getUid
ticket:[AccountInfoStorage instance].getTicket];
}
// transactionID apple
- (void)handleCheckReceiptSuccess:(NSString *)tID
isFromRecheck:(BOOL)isFromRecheck {
//
if (tID.length == 0) {
NSLog(@" ------------.------------ apple 验单失败交易ID为空");
return;
}
2024-09-24 18:01:08 +08:00
if (@available(iOS 15.0, *)) {
@kWeakify(self);
2024-09-27 11:17:04 +08:00
[[PIIAPRegulate shared] verifyBusinessAccomplishWithTransactionID:tID
2024-09-24 18:01:08 +08:00
completionHandler:^(BOOL success, NSError * _Nullable error) {
@kStrongify(self);
if (success) {
NSLog(@" ------------.------------ apple 验单成功");
2024-09-27 11:17:04 +08:00
//
[RechargeStorage delegateTransactionId:tID
uid:[AccountInfoStorage instance].getUid];
//
[self removeRetryCountForTransaction:tID];
2024-09-24 18:01:08 +08:00
} else {
2024-09-27 11:17:04 +08:00
//
NSLog(@" ------------.------------ apple 验单失败:%@ ",error);
2024-09-27 11:17:04 +08:00
if (error == nil) {
// appstore
[RechargeStorage delegateTransactionId:tID
uid:[AccountInfoStorage instance].getUid];
//
[self removeRetryCountForTransaction:tID];
2024-09-27 11:17:04 +08:00
} else {
//
if (isFromRecheck) {
//
}
2024-09-27 11:17:04 +08:00
}
}
if (!isFromRecheck) {
//
self.orderID = @"";
self.transactionID = @"";
2024-09-24 18:01:08 +08:00
}
}];
}
}
2024-09-27 11:17:04 +08:00
- (void)addValueIfNotNil:(id)value
forKey:(NSString *)key
toDictionary:(NSMutableDictionary *)dictionary {
2024-09-24 18:01:08 +08:00
if (value != nil && key != nil) {
dictionary[key] = value;
}
}
// dealloc
- (void)dealloc {
if (self.recheckTimer) {
[self.recheckTimer invalidate];
self.recheckTimer = nil;
}
}
//
- (void)applicationDidEnterBackground {
if (self.recheckTimer) {
[self.recheckTimer invalidate];
self.recheckTimer = nil;
}
}
//
- (void)applicationWillEnterForeground {
if (self.isLogin) {
[self retryCheckAllReceipt];
}
}
//
- (void)cleanupStaleTransactions {
NSArray *receipts = [RechargeStorage getAllReceiptsWithUid:[AccountInfoStorage instance].getUid];
if (!receipts || receipts.count == 0) {
return;
}
NSDate *now = [NSDate date];
NSInteger cleanupDays = 70; // 70
for (NSDictionary *receipt in receipts) {
//
NSString *timestamp = receipt[@"timestamp"];
if (!timestamp || timestamp.length == 0) {
continue;
}
NSDate *transactionDate = nil;
//
NSArray *dateFormats = @[
@"yyyy-MM-dd HH:mm:ss Z",
@"yyyy-MM-dd'T'HH:mm:ssZ",
@"EEE MMM dd HH:mm:ss Z yyyy"
];
for (NSString *format in dateFormats) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:format];
[dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
transactionDate = [dateFormatter dateFromString:timestamp];
if (transactionDate) {
break;
}
}
// 使60
if (!transactionDate) {
transactionDate = [now dateByAddingTimeInterval:-60 * 24 * 60 * 60];
}
//
if ([now timeIntervalSinceDate:transactionDate] > cleanupDays * 24 * 60 * 60) {
NSString *tID = receipt[@"transactionId"];
NSString *oID = receipt[@"orderId"];
//
[self _logToBugly:tID oID:oID status:5]; // 5
//
[RechargeStorage delegateTransactionId:tID uid:[AccountInfoStorage instance].getUid];
//
[self removeRetryCountForTransaction:tID];
}
}
}
//
- (NSInteger)getRetryCountForTransaction:(NSString *)transactionId {
__block NSInteger count = 0;
dispatch_sync(self.retryCountQueue, ^{
NSNumber *countNumber = self.retryCountDict[transactionId];
count = countNumber ? [countNumber integerValue] : 0;
});
return count;
}
//
- (void)incrementRetryCountForTransaction:(NSString *)transactionId {
dispatch_barrier_async(self.retryCountQueue, ^{
NSInteger currentCount = [self.retryCountDict[transactionId] integerValue];
self.retryCountDict[transactionId] = @(currentCount + 1);
});
}
//
- (void)removeRetryCountForTransaction:(NSString *)transactionId {
dispatch_barrier_async(self.retryCountQueue, ^{
[self.retryCountDict removeObjectForKey:transactionId];
});
}
//
- (void)cleanAllRetryCount {
dispatch_barrier_async(self.retryCountQueue, ^{
[self.retryCountDict removeAllObjects];
});
}
2024-09-24 18:01:08 +08:00
@end