In App purchase not work on device

Я пытаюсь сделать покупку в приложении в моем приложении. Но у меня нет результата, когда я пытаюсь запустить его на устройстве.

Мой код выглядит следующим образом:

Это объект, необходимый для получения информации о товарах и их покупки.

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

.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

В контроллере представления я вызываю next:

- (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];        
    }    
}

Для кнопки я добавляю селектор 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 Simulator это работает замечательно, но на устройстве у меня нет никакой кнопки, потому что response.products не загружается.

Все методы вызываются, но метод делегата *- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse )response не возвращает response.products.

Спасибо за ваше время и спасибо за ответ!

5
задан Matrosov Alexander 8 February 2012 в 12:59
поделиться