一、最近公司很多的項目用到了內購,抽空整理下內購的詳細內容吧。
如對你有幫助,請不要吝惜打賞和喜歡,謝謝!
一....iOS開發內購全套圖文教程
======================第一部分協議===============
CNAPS CODE 查詢地址
https://e.czbank.com/CORPORBANK/query_unionBank_index.jsp
2016/11/18號更新
沒顯示的都是可以不填的,主要是打鉤 title 和最後面的Self
=============第二部分創建內購項目============
===========第三部分貼加內購項目測試賬號==========
=============第四部分主要實現代碼==========
首先導入StoreKit.framework
庫
.h文件
#import <StoreKit/StoreKit.h>
enum{
IAP0p20=20,
IAP1p100,
IAP4p600,
IAP9p1000,
IAP24p6000,
}buyCoinsTag;
//代理
@interface RechargeVC : UIViewController <SKPaymentTransactionObserver,SKProductsRequestDelegate >
{
int buyType;
}
- (void) requestProUpgradeProductData;
-(void)RequestProductData;
-(void)buy:(int)type;
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
-(void) PurchasedTransaction: (SKPaymentTransaction *)transaction;
- (void) completeTransaction: (SKPaymentTransaction *)transaction;
- (void) failedTransaction: (SKPaymentTransaction *)transaction;
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction;
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error;
- (void) restoreTransaction: (SKPaymentTransaction *)transaction;
-(void)provideContent:(NSString *)product;
-(void)recordTransaction:(NSString *)product;
@end
.m文件
#import "RechargeVC.h"
//在內購項目中創的商品單號
#define ProductID_IAP0p20 @"Nada.JPYF01"//20
#define ProductID_IAP1p100 @"Nada.JPYF02" //100
#define ProductID_IAP4p600 @"Nada.JPYF03" //600
#define ProductID_IAP9p1000 @"Nada.JPYF04" //1000
#define ProductID_IAP24p6000 @"Nada.JPYF05" //6000
@interface RechargeVC ()
@end
@implementation RechargeVC
- (void)viewDidLoad {
[super viewDidLoad];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[self buy:IAP0p20];
}
-(void)buy:(int)type
{
buyType = type;
if ([SKPaymentQueue canMakePayments]) {
[self RequestProductData];
NSLog(@"允許程序內付費購買");
}
else
{
NSLog(@"不允許程序內付費購買");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"您的手機沒有打開程序內付費購買"
delegate:nil cancelButtonTitle:NSLocalizedString(@"關閉",nil) otherButtonTitles:nil];
[alerView show];
}
}
-(void)RequestProductData
{
NSLog(@"---------請求對應的產品信息------------");
NSArray *product = nil;
switch (buyType) {
case IAP0p20:
product=[[NSArray alloc] initWithObjects:ProductID_IAP0p20,nil];
break;
case IAP1p100:
product=[[NSArray alloc] initWithObjects:ProductID_IAP1p100,nil];
break;
case IAP4p600:
product=[[NSArray alloc] initWithObjects:ProductID_IAP4p600,nil];
break;
case IAP9p1000:
product=[[NSArray alloc] initWithObjects:ProductID_IAP9p1000,nil];
break;
case IAP24p6000:
product=[[NSArray alloc] initWithObjects:ProductID_IAP24p6000,nil];
break;
default:
break;
}
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 = nil;
switch (buyType) {
case IAP0p20:
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP0p20]; //支付25
break;
case IAP1p100:
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP1p100]; //支付108
break;
case IAP4p600:
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP4p600]; //支付618
break;
case IAP9p1000:
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP9p1000]; //支付1048
break;
case IAP24p6000:
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP24p6000]; //支付5898
break;
default:
break;
}
NSLog(@"---------發送購買請求------------");
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void)requestProUpgradeProductData
{
NSLog(@"------請求升級數據---------");
NSSet *productIdentifiers = [NSSet setWithObject:@"com.productid"];
SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
}
//彈出錯誤信息
- (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];
}
-(void) requestDidFinish:(SKRequest *)request
{
NSLog(@"----------反饋信息結束--------------");
}
-(void) PurchasedTransaction: (SKPaymentTransaction *)transaction{
NSLog(@"-----PurchasedTransaction----");
NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
[self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
}
//<SKPaymentTransactionObserver> 千萬不要忘記綁定,代碼如下:
//----監聽購買結果
//[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易結果
{
NSLog(@"-----paymentQueue--------");
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:{//交易完成
[self completeTransaction:transaction];
NSLog(@"-----交易完成 --------");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@""
message:@"購買成功"
delegate:nil cancelButtonTitle:NSLocalizedString(@"關閉",nil) otherButtonTitles:nil];
[alerView show];
} break;
case SKPaymentTransactionStateFailed://交易失敗
{ [self failedTransaction:transaction];
NSLog(@"-----交易失敗 --------");
UIAlertView *alerView2 = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"購買失敗,請重新嘗試購買"
delegate:nil cancelButtonTitle:NSLocalizedString(@"關閉",nil) otherButtonTitles:nil];
[alerView2 show];
}break;
case SKPaymentTransactionStateRestored://已經購買過該商品
[self restoreTransaction:transaction];
NSLog(@"-----已經購買過該商品 --------");
case SKPaymentTransactionStatePurchasing: //商品添加進列表
NSLog(@"-----商品添加進列表 --------");
break;
default:
break;
}
}
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@"-----completeTransaction--------");
// Your application should implement these two methods.
NSString *product = transaction.payment.productIdentifier;
if ([product length] > 0) {
NSArray *tt = [product componentsSeparatedByString:@"."];
NSString *bookid = [tt lastObject];
if ([bookid length] > 0) {
[self recordTransaction:bookid];
[self provideContent:bookid];
}
}
// Remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
//記錄交易
-(void)recordTransaction:(NSString *)product{
NSLog(@"-----記錄交易--------");
}
//處理下載內容
-(void)provideContent:(NSString *)product{
NSLog(@"-----下載--------");
}
- (void) failedTransaction: (SKPaymentTransaction *)transaction{
NSLog(@"失敗");
if (transaction.error.code != SKErrorPaymentCancelled)
{
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction{
}
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
{
NSLog(@" 交易恢復處理");
}
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{
NSLog(@"-------paymentQueue----");
}
#pragma mark connection delegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
switch([(NSHTTPURLResponse *)response statusCode]) {
case 200:
case 206:
break;
case 304:
break;
case 400:
break;
case 404:
break;
case 416:
break;
case 403:
break;
case 401:
case 500:
break;
default:
break;
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"test");
}
-(void)dealloc
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];//解除監聽
}
@end
1、先從內購的iTunesConnect裏配置說起吧,我們先進入蘋果的iTunesConnect鏈接https://itunesconnect.apple.com,然後進入入下界面。
填寫好銀行卡信息和公司地址等信息以後,第一步算完成了。
2、進入iTunesConnect選擇我的APP模塊,創建新的APP,綁定好你在蘋果開發者中心創建的apple IDS還有bundle id,那麼就創建成功了一個新的APP應用。如下圖:
3、進入新創建的APP應用,點擊如圖所示功能按鈕:
4、進入功能以後我們就可以創建我們想要的內購產品的ID了,一般都會存在如下幾個選擇項:
5、我們公司的項目由於都是直播類型的課程購買,所以用的是消耗型的項目,選擇好然後就進入創建界面裏去創建產品了。
6、填寫好這幾項,一個新的內購產品就創建成功了,我們需要記錄下每個產品的內購ID,也就是唯一ID,爲以後購買產品做準備。
7、我們需要在工程裏配置好證書,測試證書是必須的因爲我們內購需要連接到蘋果的App Store的,需要正式的測試證書才能測試,同時把下圖工程中的這一配置打開:
二、講完上面基本的配置以後,我們進入我們最重要的部分,那就是我們的代碼部分。
1、要使用蘋果的內購功能,我們需要引入蘋果的頭件“#import<StoreKit/StoreKit.h>”,引入進來以後,我們就需要引入"SKProductsRequestDelegate,SKPaymentTransactionObserver"這兩個代理,我們需要在內購的那個頁面viewDidLoad方法裏直接調用方法,如下圖:
然後接下來就是幾個最重要的代理方法了,如果正常的內購能夠走通,那麼這幾個代理方法就會很流暢的運行過去,並且返回你所購買的商品的信息。讓我們一步步來分析:
2、進過我這一堆的代碼組合,是否已經明白了內購的方式了呢,只要把我列舉的這幾個方法,統統的導入進你的工程,那麼就基本上可以了。
三、常見內購錯誤,自己做內購總結的幾個常見錯誤。
1、請求不到內購的產品信息。
解決辦法:(1)、先看看bundle id,和測試證書之類的東西配置的都對不對,然後看看產品的唯一ID和iTunesConnect裏的能不能對應上。如果都沒有問題,那麼看下面的。
(2)、去看看iTunesConnect裏的協議裏面的公司的地址信息和銀行卡信息是否填寫正確,只要沒有報錯,報紅就可以。基本上上面這幾點弄好了也就能請求到商品了。
2、手機提示無法連接到itunesStore
解決辦法:把手機的Apple ID先註銷掉,然後購買的時候重新填寫Apple ID。