之前做过游戏SDK,所以当时写了一个内购的类,觉得还可以吧。直接看代码
#import#import#import "FishApiDelegate.h"@interface CApiAppleStore : NSObject/*! 单例 */+(CApiAppleStore *) sharedInstance;/*! @method @abstract 设置支付代理 */-(void) setDelegate:(id) delegate;
/*!
@method
@abstract SDK启动的时候,将未完成的订单通知服务器
*/
-(void)restoreUnfinishPayment;
/*!
@method
@abstract 成功登入之后 初始化商品列表
*/
-(void)initProducts;
/*!
@method
@abstract 返回SDK服务器保存的商品ID列表
@return 字符串数组
*/
-(NSArray *)getProductIds;
/*!
@method
@abstract 获取有效的商品
@return SKProduct数组
*/
-(NSArray *)getProducts;
/*!
@method
@abstract 获取有效商品数量
@return 数量
*/
-(NSInteger)getProductNum;
/*!
@method
@abstract 购买
@param getProducts列表中的index
*/
-(void)buy:(NSInteger)productIndex info:(NSString *)info;
-(void)didRequestCompleted:(NSDictionary *)data;
@end
#import "CApiAppleStore.h"#import "FishApi.h"#import "CApiRequest.h"#import "CApiRequestData.h"#import "CEncrypt.h"#import "AppsFlyerTracker.h"#import "CApiResponse.h"@interface CApiAppleStore(){@private iddelegate;@private NSArray * productIds; NSArray * products; NSDictionary * productDic; NSString * extraInfo; NSMutableArray * cacheReceipts; //缓存收据 直接跟文件数据对应的}@end@implementation CApiAppleStore//初始化单例+ (CApiAppleStore *)sharedInstance { static dispatch_once_t pred; static CApiAppleStore *instance = nil; dispatch_once(&pred, ^{instance = [[self alloc] init];}); return instance;}//请求初始化-(id)init{ if (self = [super init]) { [self initParams]; [self setDelegate:self]; } return self;}//初始化参数-(void)initParams{ [[SKPaymentQueue defaultQueue] addTransactionObserver:self];}/*! @method @abstract 设置支付代理 */-(void) setDelegate:(id) de
{
delegate = de;
}
/*!
@method
@abstract SDK启动的时候,将未完成的订单通知服务器
*/
-(void)restoreUnfinishPayment
{
[self loadCacheReceipts];
if (cacheReceipts == nil || cacheReceipts.count == 0) {
return;
}
//NSLog(@"%@ restoreUnfinishPayment ready", [NSThread currentThread]);
NSArray * receipts = [cacheReceipts copy];
[NSThread detachNewThreadSelector:@selector(restoreUnfinishPaymentThreadFun:) toTarget:self withObject:receipts];
}
/*!
@method
@abstract 线程操作
*/
-(void)restoreUnfinishPaymentThreadFun:(id)param
{
[NSThread sleepForTimeInterval:1]; //延迟1秒执行
NSLog(@"%@ restoreUnfinishPaymentThread started", [NSThread currentThread]);
NSArray * receipts = (NSArray *)param;
if (receipts && receipts.count > 0){
for (NSDictionary * data in receipts) {
[self repaid:data];
}
}
}
/*!
@method
@abstract 成功登入之后 初始化商品列表
*/
-(void)initProducts
{
CApiRequestData *data = [[CApiRequestData alloc]init];
NSDictionary *params = [data withParams:nil];
[CApiRequest post:params to:@"index" attach:@"appleproducts"];
// [self restoreUnfinishPayment];
}
/*!
@method
@abstract 返回SDK服务器保存的商品ID列表
@return 字符串数组
*/
-(NSArray *)getProductIds
{
return productIds;
}
/*!
@method
@abstract 获取有效的商品
@return SKProduct数组
*/
-(NSArray *)getProducts
{
if (products.count == 0) {
NSSet * set = [NSSet setWithArray:productIds];
SKProductsRequest * request = [[SKProductsRequest alloc]initWithProductIdentifiers:set];
request.delegate = self;
[request start];
}
return products;
}
/*!
@method
@abstract 获取有效商品数量
@return 数量
*/
-(NSInteger)getProductNum
{
if (products == nil){
return 0;
}
return products.count;
}
/*!
@method
@abstract 购买
@param getProducts列表中的index
@param info附加信息
*/
-(void)buy:(NSInteger)productIndex info:(NSString *)info
{
if(products == nil){
return;
}
if(productIndex >= products.count){
return;
}
[delegate transactionStart];
extraInfo = [info copy];//这里一定要copy一份,因为内购需要的时间比较长,传进来的可能已经被释放
NSLog(@"extraInfo is :%@",extraInfo);
SKProduct * p = products[productIndex];
SKPayment * payment = [SKPayment paymentWithProduct:p];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
#pragma mark SKProductsRequestDelegate代理方法
-(void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSLog(@"valid products count %lu", (unsigned long)response.products.count);
NSLog(@"无效商品:%@",response.invalidProductIdentifiers);
NSMutableDictionary * dic = [[NSMutableDictionary alloc] init];
for (SKProduct * p in response.products) {
[dic setObject:p forKey:p.productIdentifier];
}
NSMutableArray * plist = [[NSMutableArray alloc]init];
id obj;
for (NSString * pid in productIds){
obj = [dic objectForKey:pid];
if (obj != nil){
[plist addObject:obj];
}
}
productDic = dic;
products = plist;
}
#pragma mark SKPaymentTransactionObserver代理方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
[self transactionSuccess:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"failed %@ %@ %@", transaction.transactionIdentifier, transaction.error.description, transaction.error.debugDescription);
[self transactionFailed:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
NSLog(@"restored %@", transaction.transactionIdentifier);
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
//NSLog(@"purchasing %@", transaction.transactionIdentifier);
break;
default:
break;
}
}
}
-(void)transactionSuccess:(SKPaymentTransaction *)transaction
{
//这里拿到收据,可以自己验证也可以传给后台验证
}
-(void)transactionFailed:(SKPaymentTransaction *)transaction
{
NSLog(@"transactionFailed %@ %@", transaction.transactionIdentifier, transaction.error.description);
[delegate transactionFinish:NO msg:transaction.error.localizedDescription];
}
-(void)didRequestCompleted:(NSDictionary *)data
{
NSInteger code = [[data objectForKey:@"code"]intValue];
NSLog(@"code:%ld",(long)code);
NSDictionary * paydata;
NSString * receiptId;
switch (code) {
case FishReqProductsOK:
productIds = [[data objectForKey:@"data"] copy];
NSSet * set = [NSSet setWithArray:productIds];
SKProductsRequest * request = [[SKProductsRequest alloc]initWithProductIdentifiers:set];
request.delegate = self;
[request start];
break;
case FishError_ReqProducts:
NSLog(@"code:%ld",(long)code);
break;
case FishPayOK:
case FishError_Pay:
paydata = [data objectForKey:@"data"];
if (paydata){
receiptId = [paydata objectForKey:@"id"];
if (receiptId){
[self delCacheReceipt:receiptId];
}
}
[delegate paymentFinish:(code == FishPayOK)?YES:NO];
break;
default:
break;
}
}
/*!
@method repaid
@abstract 重新通知服务器
*/
-(void)repaid:(NSDictionary *)params
{
CApiRequestData *data = [[CApiRequestData alloc]init];
params = [data withParams:params];
[CApiRequest post:params to:@"index" attach:@"applepay"];
}
/*!
@method
@abstract 开始购买
*/
-(void) transactionStart
{
}
/*!
@method
@abstract 结束购买
*/
-(void) transactionFinish:(Boolean)result msg:(NSString*)msg;
{
}
/*!
@method
@abstract SDK通知服务器结束
@param result 成功或者失败
*/
-(void) paymentFinish:(Boolean)result
{
}
/*!
@method
@abstract 获取订单保存路径
*/
-(NSString *) getCachePath
{
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *doucumentsDirectory=[paths objectAtIndex:0];
return [doucumentsDirectory stringByAppendingPathComponent:@"iap7725.plist"];
}
/*!
@method
@abstract 删除cache中的订单
*/
-(BOOL)delCacheReceipt:(NSString *)key
{
if(cacheReceipts == nil){
return NO;
}
BOOL redBool = NO;
NSString *file = [self getCachePath];
for (NSDictionary *objc in cacheReceipts) {
NSString *name = [objc objectForKey:@"id"];
if ([name isEqualToString:key]) {
[cacheReceipts removeObject:name];
[cacheReceipts writeToFile:file atomically:YES];
redBool = YES;
break;
}
}
return redBool;
}
/*!
@method
@abstract 从文件中加载所有
*/
-(void)loadCacheReceipts
{
NSString *file = [self getCachePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:file]) {
cacheReceipts =[[NSMutableArray alloc]initWithContentsOfFile:file];
}else{
cacheReceipts = [[NSMutableArray alloc]init];
}
}
/*!
@method
@abstract 保存数据到文件
*/
-(void) addCacheReceipt:(NSDictionary *)data
{
NSString * key = [data objectForKey:@"id"];
for (NSDictionary * objc in cacheReceipts){
NSString * name = [objc objectForKey:@"id"];
if ([name isEqualToString:key]){
return;
}
}
NSString *file = [self getCachePath];
[cacheReceipts addObject:data];
[cacheReceipts writeToFile:file atomically:YES];
}
- (void)dealloc
{
[super dealloc];
NSLog(@"购买队列被释放");
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
网友评论