2012-02-08 90 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

相关问题