关于苹果内购的一些东西,废话不多 贴代码
//首先引入相关的头文件
#import <StoreKit/StoreKit.h>
#import "SSKeychainC.h"
//然后遵循两个代理
<SKPaymentTransactionObserver,SKProductsRequestDelegate>
//开始的时候设置
// <SKPaymentTransactionObserver> 千万不要忘记绑定,代码如下:
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
//点击付费购买的时候
- (void)buyClick{
if ([SKPaymentQueue canMakePayments]) {
//如果允许购买
[self RequestProductData];
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
NSLog(@"允许程序内付费购买");
}
else
{
NSLog(@"不允许程序内付费购买");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"您的手机没有打开程序内付费购买"
delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
[alerView show];
}
}
-(void)RequestProductData
{
NSLog(@"---------请求对应的产品信息------------");
NSArray *product = nil;
product=[[NSArray alloc] initWithObjects:productID,nil];
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
request.delegate=self;
[request start];
}
// <SKProductsRequestDelegate> 请求协议
//收到的产品信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSLog(@"-----------收到产品反馈信息--------------");
NSArray *myProduct = response.products;
NSLog(@"产品Product ID:%@",response.invalidProductIdentifiers);
NSLog(@"产品付费数量: %d", (int)[myProduct count]);
// populate UI
for(SKProduct *product in myProduct){
NSLog(@"product info");
NSLog(@"SKProduct 描述信息%@", [product description]);
NSLog(@"产品标题 %@" , product.localizedTitle);
NSLog(@"产品描述信息: %@" , product.localizedDescription);
NSLog(@"价格: %@" , product.price);
NSLog(@"Product id: %@" , product.productIdentifier);
}
SKPayment *payment = payment = [SKPayment paymentWithProduct:myProduct[0]];
NSLog(@"---------发送购买请求------------");
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
//弹出错误信息
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
NSLog(@"-------弹出错误信息----------");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription]
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];
[alerView show];
[MBProgressHUD hideHUDForView:self.view animated:YES];
}
-(void) requestDidFinish:(SKRequest *)request
{
NSLog(@"----------反馈信息结束--------------");
}
//当用户购买的操作有结果的时候,就会触发下面的回调函数
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易结果
{
NSLog(@"-----paymentQueue--------");
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:{//交易完成
//交易完成后要把苹果返回的购买凭证提交到后台去苹果验证购买凭证
[self completeTransaction:transaction];
NSLog(@"-----交易完成 --------");
} break;
case SKPaymentTransactionStateFailed://交易失败
{
// [self failedTransaction:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
NSLog(@"-----交易失败 --------");
UIAlertView *alerView2 = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"购买失败,请重新尝试购买"
delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
[alerView2 show];
}break;
case SKPaymentTransactionStateRestored://已经购买过该商品
NSLog(@"-----已经购买过该商品 --------");
break;
case SKPaymentTransactionStatePurchasing: //商品添加进列表
NSLog(@"-----商品添加进列表 --------");
break;
default:
break;
}
}
}
//交易完成后的操作
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
NSLog(@"-----completeTransaction--------");
// Your application should implement these two methods.
NSString *product = transaction.payment.productIdentifier;
if ([product length] > 0) {
//向服务器验证购买凭证
NSString *transactionReceiptString= nil;
NSURLRequest*appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];
NSError *error = nil;
NSData *receiptData = transaction.transactionReceipt;
// NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequest returningResponse:nil error:&error];
transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
//发送验证凭证到自己的服务器去验证
//把订单发给后台(也就是把transactionReceiptString 这个东西发给后台就行)
// 发送网络POST请求,对购买凭据进行验证(下边注释的部分是前端自己验证购买凭证代码 一般不用 这些都是后台做的事情 只需要吧苹果返回的购买凭证发送给后台 后台去校验)
// NSString *isSandbox_applePay = [[NSUserDefaults standardUserDefaults] objectForKey:@"isSandbox_applePay"];
// NSURL *url;
// if (isSandbox_applePay) {//前端自己校验的代码( 没什么用) 一般都是用后台校验
// url = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"]; 沙盒环境校验网址
// }else{
// url = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];//正式环境校验网址
// }
// // 国内访问苹果服务器比较慢,timeoutInterval需要长一点
// NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0f];
// request.HTTPMethod = @"POST";
// NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", transactionReceiptString];
// NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];
// request.HTTPBody = payloadData;
// // 提交验证请求,并获得官方的验证JSON结果
// NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
// // 官方验证结果为空
// if (result == nil) {
// NSLog(@"验证失败");
// return;
// }
//
// NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];
//
// if (dict != nil) {
// // 比对字典中以下信息基本上可以保证数据安全
// // bundle_id&application_version&product_id&transaction_id
//
// if (![productID isEqualToString:dict[@"receipt"][@"product_id"]]) {
// UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@""
// message:@"校验失败"
// delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
//
// [alerView show];
// return;
// }
}
// Remove the transaction from the payment queue.移除购买操作
}
//最后每当页面出现的时候检测是否有未完成的订单
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.tabBarController.tabBar setHidden:YES];
NSArray* transactions = [SKPaymentQueue defaultQueue].transactions;
if (transactions.count > 0) {
//检测是否有未完成的交易
SKPaymentTransaction* transaction = [transactions firstObject];
if (transaction.transactionState == SKPaymentTransactionStatePurchased) {
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
return;
}
}
}
//苹果内购 上架的时候再iTunes connect上还要设置产品 沙盒测试账号什么的 这个搜一下网上有很多