2012-02-08 89 views
5

我嘗試在應用程序中購買我的應用程序。但是當我嘗試在設備上運行它時我沒有結果。在應用程序購買不能在設備上工作

我的代碼如下:

這是對象需要獲得有關產品的信息,併購買它。

.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。

感謝您的時間和謝謝你的回答!

+0

它適用於模擬器? InApp購買應始終在設備上進行測試。即使在那裏,您也應該註銷您的iTunes帳戶,並在應用程序中使用測試帳戶(專門用於在AppStore中測試)。 – 2012-02-08 13:06:58

+0

是的,這是正確的,但這次我需要創建按鈕,只有當我得到服務器的響應,我有產品。如果我收到了產品,我會通過此對象發送通知,並且當收到消息時,我會使用計數響應產品創建按鈕。這僅僅是測試示例。但它只能在模擬器上工作。 – 2012-02-08 13:20:42

+0

我想說取決於設備或模擬器 - 委託方法 - (void)productsRequest:(SKProductsRequest *)請求didReceiveResponse:(SKProductsResponse)響應或返回產品或不返回。這是我的問題。 – 2012-02-08 13:24:04

回答

5

爲了解決這個問題,我重置了我的設備並重新運行了應用程序。

這對我有幫助。

+0

硬重置代理方法productsRequest後正常工作。 – 2012-02-08 16:15:14

+0

經過漫長的搜索非解決方案的工作,但這工作正常..謝謝alot – Adel 2012-09-30 13:18:27

+0

如何「重置委託方法productsRequest」? – Jacky 2013-07-21 11:24:43

相關問題