在关闭商店视图后,应用程序购买崩溃

时间:2012-11-05 11:58:40

标签: objective-c ios in-app-purchase storekit

我注意到如果你在我的应用程序中输入我的商店视图(向苹果询问产品),然后在从苹果加载所有产品之前关闭商店视图,它就会崩溃。

2012-11-05 12:32:08.420 Bellman[71368:c07] Dealloc inAppManager
2012-11-05 12:32:13.788 Bellman[71368:c07] *** -[InAppPurchaseManager respondsToSelector:]: message sent to deallocated instance 0x8e85a50

正如您在我的代码中看到的那样,当调用dealloc时,我正在调用removeTransactionObserver:。正如您在上面的日志中所看到的,dealloc在应用程序崩溃前5秒被调用。根据我的理解,默认队列试图调用productsRequest: didReceiveResponse:,即使我已经将自己作为观察者移除了?

- (void)requestProUpgradeProductData:(NSSet*)productIdentifiers
{
    self.productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    self.productsRequest.delegate = self;
    [self.productsRequest start];

}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *products = response.products;
    NSLog(@"%@",products);

    for (NSString *invalidProductId in response.invalidProductIdentifiers)
    {
        NSLog(@"Invalid product id: %@" , invalidProductId);
    }

    [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
    [[self delegate] didLoadStore:response.products];
}

- (void)loadStore:(NSSet*)productIdentifiers
{
    // restarts any purchases if they were interrupted last time the app was open
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    // get the product description (defined in early sections)
    [self requestProUpgradeProductData:productIdentifiers];
    NSLog(@"Unfinished Transactions: [%i]", [[SKPaymentQueue defaultQueue].transactions count]);
}

- (BOOL)canMakePurchases
{
    return [SKPaymentQueue canMakePayments];
}

- (void)purchase:(SKProduct*)product {
    SKPayment *payment = [SKPayment paymentWithProduct:product];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}


- (void)recordTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"Subscription bought");
}


- (void)provideContent:(SKPaymentTransaction *)transaction
{
    NSLog(@"Asking user to register Database");
    [[self delegate] provideContent:transaction];
}

- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
    // remove the transaction from the payment queue.
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    NSLog(@"Removeing recipt");
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
    if (wasSuccessful)
    {
        [[self delegate] didMakePurchase:transaction.payment.productIdentifier];
        // send out a notification that we’ve finished the transaction
        [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionSucceededNotification object:self userInfo:userInfo];
    }
    else
    {
        // send out a notification for the failed transaction
        [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
    }
}

- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    [self recordTransaction:transaction];
    [self provideContent:transaction];
}

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

}

- (void)completePurches:(SKPaymentTransaction *)transaction {
    NSLog(@"EVERYTHING IS DONE!");
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"unfinishedReceipt"];
    [self finishTransaction:transaction wasSuccessful:YES];
}

- (void) failedTransaction: (SKPaymentTransaction *)transaction {
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        [[self delegate] didReciveAppStoreError:transaction.error.localizedDescription];
        // Optionally, display an error here.
    }
    [[self delegate] didCancelPurches];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}


- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"Completed transcation");
                [self completeTransaction:transaction];

                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"Failed transcation: %@",transaction.error);
                [self failedTransaction:transaction];
                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"Restore transcation: %@",transaction.payment.productIdentifier);
                [self restoreTransaction:transaction];
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"ID: %@",transaction.transactionIdentifier);
                break;
            default:
                break;
        }
    }
}

-(void)didVerifyNewRecipt:(SKPaymentTransaction *)recipt wasNewRecipit:(BOOL)status {
    if (status) {
        NSLog(@"Was new recipt showing interface");
        [self completeTransaction:recipt];
    } else {
        NSLog(@"Was old Receipt");
        [self completePurches:recipt];
        [[self delegate] didFindOldReceipt];
    }
}

-(void)didReciveError:(NSString *)error {
    NSLog(@"ERROR! %@",error);
}

-(void)dealloc {
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    NSLog(@"Dealloc inAppManager");
}

1 个答案:

答案 0 :(得分:2)

当我即将点击“提问”时,它只是想出来了。由于我没有在互联网上找到答案,我将分享我的解决方案。

由于SKProductsRequest不是SKPaymentQueue的一部分而SKProductsRequest实现了自己的委托,因此您需要删除您在SKProductsRequest上设置的委托。

-(void)dealloc {
   [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
   self.productsRequest.delegate = nil; // <----- Solution
   NSLog(@"Dealloc inAppManager");
}