如何在iOS中使用应用内购买检查产品是否已购买?

时间:2013-06-11 13:01:01

标签: iphone objective-c

我有一个应用程序集成在其中的应用程序。在我的应用程序中,我有两个付费应用程序购买和订阅按钮。当用户点击购买时,检查苹果验证和购买产品。

这样可以正常工作,但是当购买产品时,我的购买按钮应该更改为“已完成”,当应用程序下次运行时,购买按钮不应该对该特定产品可见。而应显示“完成”按钮。我的问题是,当购买产品时,显示购买按钮而不是完成按钮。

这是我的代码:

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

//Then this delegate Function Will be fired
- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
    NSLog(@"received restored transactions: %i", queue.transactions.count);
    for (SKPaymentTransaction *transaction in queue.transactions)
    {
        NSString *productID = transaction.payment.productIdentifier;
        NSLog(@"%@",productID);
    }

}

// called when a transaction has failed
- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        // error!
        [self finishTransaction:transaction wasSuccessful:NO];
        if (transaction.error.code == SKErrorClientInvalid) {
            //[self showAlert:@"In-App Purchase" withMessage:INVALID_CLIENT];
        }
        else if (transaction.error.code == SKErrorPaymentInvalid) {
            //[self showAlert:@"In-App Purchase" withMessage:PAYMENT_INVALID];
        }
        else if (transaction.error.code == SKErrorPaymentNotAllowed) {
            //[self showAlert:@"In-App Purchase" withMessage:PAYMENT_NOT_ALLOWED];
        }
        else if (transaction.error.code == SKErrorPaymentCancelled) {
            // [self showAlert:@"In-App Purchase" withMessage:@"This device is not allowed to make the payment."];
            NSLog(@"User Cancellation.");
        }
        else {
            // SKErrorUnknown
            NSLog(@"Unknown Reason.");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Transaction Status" message:@"Transaction Failed due to unknown reason" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alert show];

        }
    }
    else {
        // this is fine, the user just cancelled, so don’t notify
        //        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Transaction Status" message:@"Transaction failed due to some reason" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        //        [alert show];
        //        return;
        //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }
}

- (void)provideContent:(NSString *)productId
{
    if ([productId isEqualToString:kMyFeatureIdentifier4])
    {
        // enable the pro features
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isStorePurchased"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    else if([productId isEqualToString:kMyFeatureIdentifier3])
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"isStoreSubscribed"];
        [[NSUserDefaults standardUserDefaults]synchronize];

    }
}



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

    NSData *receiptData = [NSData dataWithData:transaction.transactionReceipt];

    transactionreceipt = [Base64 encode:receiptData];
    NSLog(@"encoded String :%@",transactionreceipt);
    if ([transaction.payment.productIdentifier isEqualToString:kMyFeatureIdentifier4])
    {
        // save the transaction receipt to disk
        [[NSUserDefaults standardUserDefaults] setValue:transactionreceipt forKey:@"proUpgradeTransactionReceipt"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
    if ([transaction.payment.productIdentifier isEqualToString:kMyFeatureIdentifier3])
    {
        [[NSUserDefaults standardUserDefaults] setValue:transactionreceipt forKey:@"proUpgradeTransactionReceipt"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
    NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults];
    transactionreceipt = [userdefaults valueForKey:@"proUpgradeTransactionReceipt"];
    NSLog(@"%@",transactionreceipt);
    // remove the transaction from the payment queue.
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
    if (wasSuccessful)
    {
        // send out a notification that we’ve finished the transaction
        [self sendRequest];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PurchaseSuccess" object:self userInfo:userInfo];

        [easytblView reloadData];
    }
    else
    {
        // send out a notification for the failed transaction
        // [[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerTransactionFailedNotification object:self userInfo:userInfo];
    }
}

- (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];
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"Purchasing...");
                break;
            default:
                break;
        }
    }
}

// called when a transaction has been restored and and successfully completed
- (void)restoreTransaction:(SKPaymentTransaction *)transaction
{
    [self recordTransaction:transaction.originalTransaction];
    [self provideContent:transaction.originalTransaction.payment.productIdentifier];
    [self finishTransaction:transaction wasSuccessful:YES];
}


// called when the transaction was successful
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    [self recordTransaction:transaction];
    [self provideContent:transaction.payment.productIdentifier];
    [self finishTransaction:transaction wasSuccessful:YES];
}
    -(void)buyProduct
    {
        if (arrPurchaseProducts.count>0)
        {
            SKProduct *selectedProduct = [arrPurchaseProducts objectAtIndex:0];
            SKPayment *payment = [SKPayment paymentWithProduct:selectedProduct];
            [[SKPaymentQueue defaultQueue] addPayment:payment];
            //selectedProduct = nil;
            // payment = nil;
        }

    }

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSLog(@"IN-APP:productsRequest");
    arrPurchaseProducts = [[NSArray alloc]initWithArray:response.products];
    if ([arrPurchaseProducts count] == 1)
    {
        SKProduct *selectedProduct = [arrPurchaseProducts objectAtIndex:0];
        SKPayment *payment = [SKPayment paymentWithProduct:selectedProduct];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
        //responseStatus = 1;
        //        if ([purchaseButton.title isEqualToString:@"   "])
        //        {
        NSLog(@"Purchase had been attempted already.");

        // }
    }

    if ([arrPurchaseProducts count]>0)
    {
        product = [arrPurchaseProducts objectAtIndex:0];
        NSLog(@"Price: %.2f",product.price.floatValue);
        NSLog(@"Price Locale: %@",product.priceLocale.localeIdentifier);
        NSLog(@"Product Identifier: %@",product.productIdentifier);
        NSLog(@"IN-APP:array count: %i", [arrPurchaseProducts count]);
        [request autorelease];
        NSLog(@"IN-APP:productsRequest END");
    }
    //[arrPurchaseProducts release];
    // arrPurchaseProducts = nil;
}

- (void)requestProductData
{

    NSLog(@"IN-APP:requestProductData");
    SKProductsRequest *request;
    if (isSubscribe==YES)
    {
        request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kMyFeatureIdentifier3]];
    }
    else{
        request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kMyFeatureIdentifier3]];
    }
    request.delegate = self;
    [request start];
    NSLog(@"IN-APP:requestProductData END");
}

-(IBAction)buynow:(id)sender
{
    isSubscribe=NO;
    isviewloadedforfirsttime=NO;
        if([SKPaymentQueue canMakePayments])
        {
//            if (![[NSUserDefaults standardUserDefaults] valueForKey:@"isStorePurchased"])
//            {
                [self requestProductData];

            //}
            NSLog(@"IN-APP:can make payments");
        }
        else {
            NSLog(@"IN-APP:can't make payments");
    }

       [self performSelector:@selector(buyProduct) withObject:nil afterDelay:2.0];


}

2 个答案:

答案 0 :(得分:6)

- (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];
                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"Purchasing...");
                break;
            default:
                break;
        }
    }
}

你自己在代码中有SKPaymentTransactionStateRestored的情况,它告诉我们什么时候正在恢复产品。

答案 1 :(得分:3)

您需要添加执行restoreCompletedTransactions方法的代码...

在App的初始启动中添加[self checkPurchasedItems];,例如根视图控制器的viewDidLoad方法,以显示购买按钮逻辑..

保持buttons.enabled = NO ...这样按钮只有在返回方法到达时才会启用,告诉我们已购买的内容...您应该将这些布尔值存储为离线模式。

当事务恢复时,将按钮标记为已启用和/或已正确隐藏。

祝你好运!