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

#iphone #ios #ipad #storekit

#iPhone #iOS #iPad #storekit

Вопрос:

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

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

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

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

Есть идеи о том, почему код store kit, который работает на 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 вы можете сделать это в разделе цель -> Этапы сборки -> Скомпилировать исходные коды.

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

Комментарии:

1. Спасибо, я попробую это! Merci.