2013-08-19 4 views
0

Я добавил IAP в cocos2d следующего лучевые учебников (но изменил несколько вещей, чтобы соответствовать cocos2d), но после того, как я делаю транзакцию журнал консоль говорит 2013-08-19 16:32:12.626 Game[2483:907] Buying *product* ... 2013-08-19 16:32:13.208 Game[2483:907] cocos2d: animation stopped 2013-08-19 16:32:16.690 Game[2483:907] completeTransaction... 2013-08-19 16:32:16.725 Game[2483:907] User defaults for *product* are YESCocos2d анимация резюме

Так что я знаю, что сделка работает, но игра никогда не возобновляется, она просто зависает. Есть ли способ возобновить игру после транзакции? [[CCDirector sharedDirector]resume] не работает, поэтому я думаю, что это может иметь отношение к UIAlert View. Любая помощь? Вот мой iAPHelper.mm:

#import "IAPHelper.h" 
#import <StoreKit/StoreKit.h> 

NSString *const IAPHelperProductPurchasedNotification 
@"IAPHelperProductPurchasedNotification"; 

@interface IAPHelper() <SKProductsRequestDelegate, SKPaymentTransactionObserver> 
@end 

@implementation IAPHelper { 

SKProductsRequest * _productsRequest; 

RequestProductsCompletionHandler _completionHandler; 
NSSet * _productIdentifiers; 
NSMutableSet * _purchasedProductIdentifiers; 

} 

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers { 

if ((self = [super init])) { 

    // Store product identifiers 
    _productIdentifiers = productIdentifiers; 
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 

    // Check for previously purchased products 
    _purchasedProductIdentifiers = [NSMutableSet set]; 
    for (NSString * productIdentifier in _productIdentifiers) { 
     BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier]; 
     if (productPurchased) { 
      [_purchasedProductIdentifiers addObject:productIdentifier]; 
      NSLog(@"Previously purchased: %@", productIdentifier); 
     } else { 
      NSLog(@"Not purchased: %@", productIdentifier); 
     } 
    } 

} 
return self; 
} 

- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler { 

_completionHandler = [completionHandler copy]; 

_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers]; 
_productsRequest.delegate = self; 
[_productsRequest start]; 

} 

#pragma mark - SKProductsRequestDelegate 

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { 

NSLog(@"Loaded list of products..."); 
_productsRequest = nil; 

NSArray * skProducts = response.products; 
for (SKProduct * skProduct in skProducts) { 
    NSLog(@"Found product: %@ %@ %0.2f", 
      skProduct.productIdentifier, 
      skProduct.localizedTitle, 
      skProduct.price.floatValue); 
} 

_completionHandler(YES, skProducts); 
_completionHandler = nil; 

} 

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error { 

NSLog(@"Failed to load list of products."); 
_productsRequest = nil; 

_completionHandler(NO, nil); 
_completionHandler = nil; 

} 

- (BOOL)productPurchased:(NSString *)productIdentifier { 
return [_purchasedProductIdentifiers containsObject:productIdentifier]; 
} 

- (void)buyProduct:(SKProduct *)product { 

NSLog(@"Buying %@...", product.productIdentifier); 

SKPayment * payment = [SKPayment paymentWithProduct:product]; 
[[SKPaymentQueue defaultQueue] addPayment:payment]; 

} 

- (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)completeTransaction:(SKPaymentTransaction *)transaction { 
NSLog(@"completeTransaction..."); 

[self provideContentForProductIdentifier:transaction.payment.productIdentifier]; 
[[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
} 

- (void)restoreTransaction:(SKPaymentTransaction *)transaction { 
NSLog(@"restoreTransaction..."); 

[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier]; 
[[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
} 

- (void)failedTransaction:(SKPaymentTransaction *)transaction { 

NSLog(@"failedTransaction..."); 
if (transaction.error.code != SKErrorPaymentCancelled) 
{ 
    NSLog(@"Transaction error: %@", transaction.error.localizedDescription); 
} 

[[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 
} 

- (void)provideContentForProductIdentifier:(NSString *)productIdentifier { 

[_purchasedProductIdentifiers addObject:productIdentifier]; 
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier]; 
[[NSUserDefaults standardUserDefaults] synchronize]; 
[[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil]; 
NSLog(@"User defaults for %@ are YES", productIdentifier); 
} 

- (void)restoreCompletedTransactions { 
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; 
} 

@end 

ответ

1

Перед тем, как всплывать ваше предупреждение вида попробуйте запустить ...

[[CCDirector sharedDirector] stopAnimation]; 

Когда вы получите ответ от пользователя в alertview обратного вызова или завершение транзакции запуска. ..

[[CCDirector sharedDirector] startAnimation]; 

Cocos не часто играет хорошо UIKit/какао функцию обратного вызова, так что вам нужно, чтобы приостановить оказание в то время как они делают свое дело. У нас подобное поведение для того, когда приложение переходит в фон/план в приложение делегата ...

-(void) applicationDidEnterBackground:(UIApplication*)application { 
    [[CCDirector sharedDirector] stopAnimation]; 
} 

-(void) applicationWillEnterForeground:(UIApplication *)application { 
    [[CCDirector sharedDirector] startAnimation]; 
} 

-(void)applicationDidBecomeActive:(UIApplication *)application { 
    [[CCDirector sharedDirector] resume]; 
} 

Кажется мы используем резюме внутри applicationDidBecomeActive. Не могу вспомнить полную логику, но, похоже, это работает для кучи наших проектов.