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