第二步:申請測試賬号,利用沙盒測試模拟AppStore購買道具流程!
回到itunesconnect首頁中,選擇“Manage Users”然後選擇“Test User”,然後出現的界面如下圖:
<a target="_blank" href="http://blog.51cto.com/attachment/201111/011238706.png"></a>
這裡Himi已經建立了兩個測試賬号了,點選界面中的 “Add New User”進行建立即可;記住賬号和密碼哈,記不住就删掉重建立 娃哈哈~(切記:不能用于真正的AppStore中使用此賬号,不僅不能用,而且一旦AppStore發現後果你懂得~)
第三步:在項目中申請購買産品代碼以及監聽;
這裡關于購買的代碼部分呢,我都有備注的,Himi這裡就不詳細講解了,Himi隻是在代碼後介紹幾點值得注意的地方:
這裡Himi是建立的一個Cocos2d的項目,然後給出HelloWorldLayer.h以及HelloWorldLayer.m的全部代碼,所有購買代碼也全在裡面也對應有Himi的注釋!
HelloWorldLayer.h
//
// HelloWorldLayer.h
// buytest
// Created by 華明 李 on 11-10-29.
// Copyright Himi 2011年. All rights reserved.
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
enum{
IAP0p99=10,
IAP1p99,
IAP4p99,
IAP9p99,
IAP24p99,
}buyCoinsTag;
@interface HelloWorldLayer : CCLayer<SKProductsRequestDelegate,SKPaymentTransactionObserver>
{
int buyType;
}
+(CCScene *) scene;
- (void) requestProUpgradeProductData;
-(void)RequestProductData;
-(bool)CanMakePay;
-(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
HelloWorldLayer.m
// IapLayer.m
// Created by Himi on 11-5-25.
// Copyright 2011年 李華明 . All rights reserved.
#import "HelloWorldLayer.h"
#define ProductID_IAP0p99 @"com.buytest.one"//$0.99
#define ProductID_IAP1p99 @"com.buytest.two" //$1.99
#define ProductID_IAP4p99 @"com.buytest.three" //$4.99
#define ProductID_IAP9p99 @"com.buytest.four" //$19.99
#define ProductID_IAP24p99 @"com.buytest.five" //$24.99
@implementation HelloWorldLayer
+(CCScene *) scene
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
-(id)init
if ((self = [super init])) {
CGSize size = [[CCDirector sharedDirector] winSize];
CCSprite *iap_bg = [CCSprite spriteWithFile:@"Icon.png"];
[iap_bg setPosition:ccp(size.width/2,size.height/2)];
[self addChild:iap_bg z:0];
//---------------------
//----監聽購買結果
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
//申請購買
/*
enum{
IAP0p99=10,
IAP1p99,
IAP4p99,
IAP9p99,
IAP24p99,
}buyCoinsTag;
*/
[self buy:IAP24p99];
}
return self;
-(void)buy:(int)type
{
buyType = type;
if ([SKPaymentQueue canMakePayments]) {
//[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
[self RequestProductData];
CCLOG(@"允許程式内付費購買");
else
{
CCLOG(@"不允許程式内付費購買");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"Alert"
message:@"You can‘t purchase in app store(Himi說你沒允許應用程式内購買)"
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close(關閉)",nil) otherButtonTitles:nil];
[alerView show];
[alerView release];
}
-(bool)CanMakePay
return [SKPaymentQueue canMakePayments];
-(void)RequestProductData
CCLOG(@"---------請求對應的産品資訊------------");
NSArray *product = nil;
switch (buyType) {
case IAP0p99:
product=[[NSArray alloc] initWithObjects:ProductID_IAP0p99,nil];
break;
case IAP1p99:
product=[[NSArray alloc] initWithObjects:ProductID_IAP1p99,nil];
case IAP4p99:
product=[[NSArray alloc] initWithObjects:ProductID_IAP4p99,nil];
case IAP9p99:
product=[[NSArray alloc] initWithObjects:ProductID_IAP9p99,nil];
case IAP24p99:
product=[[NSArray alloc] initWithObjects:ProductID_IAP24p99,nil];
default:
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
request.delegate=self;
[request start];
[product release];
//<SKProductsRequestDelegate> 請求協定
//收到的産品資訊
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSLog(@"-----------收到産品回報資訊--------------");
NSArray *myProduct = response.products;
NSLog(@"産品Product ID:%@",response.invalidProductIdentifiers);
NSLog(@"産品付費數量: %d", [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;
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP0p99]; //支付$0.99
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP1p99]; //支付$1.99
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP4p99]; //支付$9.99
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP9p99]; //支付$19.99
payment = [SKPayment paymentWithProductIdentifier:ProductID_IAP24p99]; //支付$29.99
CCLOG(@"---------發送購買請求------------");
[[SKPaymentQueue defaultQueue] addPayment:payment];
[request autorelease];
- (void)requestProUpgradeProductData
CCLOG(@"------請求更新資料---------");
NSSet *productIdentifiers = [NSSet setWithObject:@"com.productid"];
SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];
//彈出錯誤資訊
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
CCLOG(@"-------彈出錯誤資訊----------");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription]
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];
[alerView show];
[alerView release];
-(void) requestDidFinish:(SKRequest *)request
NSLog(@"----------回報資訊結束--------------");
-(void) PurchasedTransaction: (SKPaymentTransaction *)transaction{
CCLOG(@"-----PurchasedTransaction----");
NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
[self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
[transactions release];
}
//<SKPaymentTransactionObserver> 千萬不要忘記綁定,代碼如下:
//----監聽購買結果
//[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易結果
CCLOG(@"-----paymentQueue--------");
for (SKPaymentTransaction *transaction in transactions)
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased://交易完成
[self completeTransaction:transaction];
CCLOG(@"-----交易完成 --------");
CCLOG(@"不允許程式内付費購買");
UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"Alert"
message:@"Himi說你購買成功啦~娃哈哈"
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close(關閉)",nil) otherButtonTitles:nil];
[alerView show];
[alerView release];
break;
case SKPaymentTransactionStateFailed://交易失敗
[self failedTransaction:transaction];
CCLOG(@"-----交易失敗 --------");
UIAlertView *alerView2 = [[UIAlertView alloc] initWithTitle:@"Alert"
message:@"Himi說你購買失敗,請重新嘗試購買~"
[alerView2 show];
[alerView2 release];
case SKPaymentTransactionStateRestored://已經購買過該商品
[self restoreTransaction:transaction];
CCLOG(@"-----已經購買過該商品 --------");
case SKPaymentTransactionStatePurchasing: //商品添加進清單
CCLOG(@"-----商品添加進清單 --------");
break;
default:
}
- (void) completeTransaction: (SKPaymentTransaction *)transaction
CCLOG(@"-----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{
CCLOG(@"-----記錄交易--------");
//處理下載下傳内容
-(void)provideContent:(NSString *)product{
CCLOG(@"-----下載下傳--------");
- (void) failedTransaction: (SKPaymentTransaction *)transaction{
NSLog(@"失敗");
if (transaction.error.code != SKErrorPaymentCancelled)
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction{
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
NSLog(@" 交易恢複處理");
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{
CCLOG(@"-------paymentQueue----");
#pragma mark connection delegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
NSLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
switch([(NSHTTPURLResponse *)response statusCode]) {
case 200:
case 206:
case 304:
case 400:
break;
case 404:
case 416:
case 403:
case 401:
case 500:
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"test");
-(void)dealloc
[super dealloc];
代碼注釋的相當清楚了,沒有什麼可解釋的,這裡說幾點值得注意的地方:
2. 越獄機器無法沙盒測試!模拟器的話,Himi用4.3模拟器不可以,因為提示沒有開啟程式内付費- -(我都沒看到模拟器有store的選項,so~);但是使用iOS5的模拟器可以測試沙盒,但是執行的順序會有些問題,但是還沒真機的童鞋可以使用,建議一切以真機實測為準
3. 千萬不要忘記在iTunesConnect中建立App Bundle ID一定要跟你的項目中的info.plist中的Bundle ID保證一緻!!!!
4. 以上代碼中你需要修改的就是我在HelloWorldLayer.m類中的宏定義的Product ID(産品ID),例如Himi剛才建立了一個産品ID是“com.himi.wahaha"
然後我運作項目截圖如下以及運作控制台列印的資訊如下:
<a target="_blank" href="http://blog.51cto.com/attachment/201111/011342989.png"></a>
點選Buy之後運作截圖以及列印資訊:
<a target="_blank" href="http://blog.51cto.com/attachment/201111/011401918.png"></a>
輸入測試賬号密碼後以及列印資訊:
<a target="_blank" href="http://blog.51cto.com/attachment/201111/011415617.png"></a>
這裡Himi最後一張截圖是沒有購買成功,這裡Himi是故意截圖出來的,原因就是想告訴童鞋們:
如果你的産品資訊能夠正常得到,但是始終無法成功的話,不要着急,因為你的産品要進入iTunes Connect,并且Apple準備好沙箱環境需要一些時間。Himi之前遇到過,然後在一天後我沒有修改任何一行代碼,但産品ID變為有效并能成功購買。=。 =郁悶ing~~ 起始要使産品釋出到Apple的網絡系統是需要一段時間的!
好了,寫了這麼多了,咳咳、Himi繼續忙了,做iOS的童鞋們我想此篇将成為你必須收藏的一篇哦~嘿嘿!
本文轉自 xiaominghimi 51CTO部落格,原文連結:http://blog.51cto.com/xiaominghimi/706419,如需轉載請自行聯系原作者