我嘗試在應用程序中購買我的應用程序。但是當我嘗試在設備上運行它時我沒有結果。在應用程序購買不能在設備上工作
我的代碼如下:
這是對象需要獲得有關產品的信息,併購買它。
.H
#import <Foundation/Foundation.h>
#import "StoreKit/StoreKit.h"
#define kProductsLoadedNotification @"ProductsLoaded"
#define kProductPurchasedNotification @"ProductPurchased"
#define kProductPurchaseFailedNotification @"ProductPurchaseFailed"
@interface StoreManager : NSObject <SKProductsRequestDelegate, SKPaymentTransactionObserver>
@property (strong, nonatomic) NSMutableSet * _purchasedProducts;
@property (strong, nonatomic) NSArray *products;
@property (strong, nonatomic) NSSet *_productIdentifiers;
@property (strong, nonatomic) SKProductsRequest *request;
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers;
- (void)requestProducts;
- (void)buyProduct:(SKProduct *)product;
- (void)completeTransaction:(SKPaymentTransaction *)transaction;
- (void)restoreTransaction:(SKPaymentTransaction *)transaction;
- (void)failedTransaction:(SKPaymentTransaction *)transaction;
- (void)provideContent:(NSString *)productIdentifier;
- (void)recordTransaction:(SKPaymentTransaction *)transaction;
@end
的.m
#import "StoreManager.h"
@implementation StoreManager
@synthesize _purchasedProducts;
@synthesize products;
@synthesize _productIdentifiers;
@synthesize request;
// Initializes the request object with the set of product identifiers.
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers{
self = [super init];
if(self){
self._productIdentifiers = productIdentifiers;
NSMutableSet *purchased = [NSMutableSet set];
for(NSString * productId in self._productIdentifiers){
BOOL flag = [[NSUserDefaults standardUserDefaults] boolForKey:productId];
if(flag){
[purchased addObject:productId];
NSLog(@"Previously purchased: %@", productId);
}
NSLog(@"Not purchased: %@", productId);
}
self._purchasedProducts = purchased;
}
return self;
}
// Request info for the product.
- (void)requestProducts{
self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:self._productIdentifiers];
self.request.delegate = self;
[self.request start];
}
// Request fail.
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
NSLog(@"Fail request! Error: %@", error);
}
// Delegate method - did receive responce.
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
self.products = response.products;
self.request = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:self.products];
}
// Buy product.
- (void)buyProduct:(SKProduct *)product{
SKPayment *payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
// Payment transactions
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
}
}
- (void)recordTransaction:(SKPaymentTransaction *)transaction {
// TODO: Record the transaction on the server side...
}
- (void)completeTransaction:(SKPaymentTransaction *)transaction{
[self recordTransaction: transaction];
[self provideContent: transaction.payment.productIdentifier];
NSLog(@"completeTransaction...");
}
- (void)provideContent:(NSString *)productIdentifier {
NSLog(@"Toggling flag for: %@", productIdentifier);
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
[self._purchasedProducts addObject:productIdentifier];
[[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"restoreTransaction...");
[self recordTransaction: transaction];
[self provideContent: transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
if (transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(@"Transaction error: %@", transaction.error.localizedDescription);
}
[[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction];
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
@end
Singleton對象
.H
#import <Foundation/Foundation.h>
#import "StoreManager.h"
@interface StoreWrapper : StoreManager
+ (StoreWrapper *)sharedInstance;
@end
.M
#import "StoreWrapper.h"
@implementation StoreWrapper
static StoreWrapper *gInstance = NULL;
- (id)init{
NSSet *productId = [NSSet setWithObjects:@"com.company.sb.pack1", @"com.company.sb.pack5", nil];
self = [super initWithProductIdentifiers:productId];
if(self){
}
return self;
}
+ (StoreWrapper *)sharedInstance{
if(gInstance == NULL){
gInstance = [[self alloc] init];
}
return gInstance;
}
@end
在我的視圖控制器我下面:
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productsLoaded:) name:kProductsLoadedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:) name:kProductPurchasedNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object: nil];
Reachability *reach = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [reach currentReachabilityStatus];
if (netStatus == NotReachable) {
NSLog(@"No internet connection!");
} else {
NSLog(@"Internet connection available!");
// Request product
[[StoreWrapper sharedInstance] requestProducts];
[activIndicator startAnimating];
}
[super viewWillAppear:animated];
}
對於這一點,我送了獲取產品信息的請求,從服務器與我的產品ID
接下來,如果產品已加載,我的班級會收到有關此通知的信息(並調用以下方法)。
- (void)productsLoaded:(NSNotification *)notification{
[activIndicator stopAnimating];
[activIndicator setHidden:YES];
NSArray *arr = [notification object];
for(int i = 0; i < [arr count]; i++){
SKProduct *product = [[StoreWrapper sharedInstance].products objectAtIndex:i];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(0, i*55, 100, 50)];
[btn setTitle:product.localizedTitle forState:UIControlStateNormal];
[btn setTag:i];
[btn addTarget:self action:@selector(buyProduct:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
}
對於按鈕i加選擇buyProduct(如上圖所示)
- (void)buyProduct:(id)sender{
NSLog(@"sender tag %d", [sender tag]);
int tag = [sender tag];
SKProduct *product = [[StoreWrapper sharedInstance].products objectAtIndex:tag];
[[StoreWrapper sharedInstance] buyProduct:product];
}
對於iPhone模擬器這項工作美好的,但在設備上我不具有任何按鈕,因爲response.products無法下載。
所有方法調用,但委託方法* - (空)productsRequest:(SKProductsRequest *)要求didReceiveResponse:(SKProductsResponse )響應沒有返回response.products。
感謝您的時間和謝謝你的回答!
它適用於模擬器? InApp購買應始終在設備上進行測試。即使在那裏,您也應該註銷您的iTunes帳戶,並在應用程序中使用測試帳戶(專門用於在AppStore中測試)。 – 2012-02-08 13:06:58
是的,這是正確的,但這次我需要創建按鈕,只有當我得到服務器的響應,我有產品。如果我收到了產品,我會通過此對象發送通知,並且當收到消息時,我會使用計數響應產品創建按鈕。這僅僅是測試示例。但它只能在模擬器上工作。 – 2012-02-08 13:20:42
我想說取決於設備或模擬器 - 委託方法 - (void)productsRequest:(SKProductsRequest *)請求didReceiveResponse:(SKProductsResponse)響應或返回產品或不返回。這是我的問題。 – 2012-02-08 13:24:04