Обновленные транзакции не удалось отозвать после iOS 4.2

У нас была сложная проблема с магазинным комплектом. Мы пытаемся правильно внедрить процесс возобновляемых подписок на покупки в приложении в приложение, которое уже находится в магазине приложений со стандартной настройкой покупки в приложении (непотребляемые товары).

До сих пор, потратив 2 месяца на борьбу со странным поведением в песочнице, мы создали рабочее решение на тестовом iPad с iOS4.2.

Неприятный сюрприз, который мы получили при тестировании этого кода на iPad с 4.3 или 5.0, он не имеет такого поведения.

Мы сузили это до простого факта: - iOS4.2: обратный вызов updatedTransactions работает правильно - iOS4.3 и выше: обратный вызов updatedTransactions никогда не вызывается песочницей.

Любые идеи о том, почему код набора магазина, который работает на iOS4.2, не будет работать на следующих версиях iOS? Я не видел ничего осуждаемого в этом.

Вот код нашего обновленного кода транзакций:

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
    NSLog(@"Add payment queue");
    for(SKPaymentTransaction *transaction in transactions)  {
        NSLog(@"Transaction state: %d, %d, %d, %d", transaction.transactionState, SKPaymentTransactionStatePurchased, SKPaymentTransactionStateFailed, SKPaymentTransactionStateRestored);
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchased:

                if([transaction.payment.productIdentifier isEqualToString:FM_PRODUCT_IDENTIFIER_SUBSCRIPTION]){
                    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
                    [userDefaults setObject:transaction.transactionReceipt forKey:@"TransactionReceiptOfTransaction"];
                }

                [self completeTransaction:transaction];
                [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 

                break;

            case SKPaymentTransactionStateFailed:
                NSLog(@"%@", transaction.error);

                [self failedTransaction:transaction];
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"") 
                                                                message:NSLocalizedString(@"Your subscription has expired.", @"")
                                                               delegate:self 
                                                      cancelButtonTitle:@"OK" 
                                                      otherButtonTitles: nil];
                [alert show];
                SAFE_RELEASE(alert);

                [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

                if([transaction.error code] != SKErrorPaymentCancelled) {
                    if([transaction.payment.productIdentifier isEqualToString:FM_PRODUCT_IDENTIFIER_SUBSCRIPTION]){
                        NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
                        [userDefaults setObject:transaction.transactionReceipt forKey:@"TransactionReceiptOfTransaction"];
                    }
                }
                break;

            case SKPaymentTransactionStateRestored:

                if([transaction.payment.productIdentifier isEqualToString:FM_PRODUCT_IDENTIFIER_SUBSCRIPTION]){
                    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
                    [userDefaults setObject:transaction.transactionReceipt forKey:@"TransactionReceiptOfTransaction"];
                }

                [self restoreTransaction:transaction];
                [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

            default:
                    NSLog(@"Other");
                break;
        }
    }
}

Спасибо Стефан

1 ответ

У меня была точно такая же проблема, и чтобы решить ее, я переключил исходный файл, который содержитaddTransactionObserver позвонить ARC = none,

//  StoreKit
CustomStoreObserver *observer = [[CustomStoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];

Кажется, что ARC или StoreKit Framework не могут хорошо работать вместе. Чтобы переключить исходный файл с ARC = none, я установил флаг -fno-objc-arc, как сказал Джош Касвелл в вопросе "Отключить автоматический подсчет ссылок для некоторых файлов".

Ответ заключается в добавлении -fno-objc-arc к флагам компилятора для файлов, которые вы не хотите ARC. В Xcode 4 вы можете сделать это под вашей целью -> Build Phases -> Compile Sources.

Обновление: Мое объяснение такого поведения состоит в том, что ARC хочет управлять самой памятью, но это не очень хорошо для Storekit. ARC слишком рано выпускает объект "наблюдатель". Это вызывает сбой, когда модуль InAppPurchase (сторона Apple) хочет сообщить ваш метод "updatedTransactions". И для меня, чтобы засунуть объект "наблюдатель" в память во время жизни моего приложения. Я решил дать ему сохранить свойство в моем файле.h.

Другие вопросы по тегам