6

アプリ内統合を含むアプリケーションがあります。私のアプリには、有料アプリの購入と購読用の 2 つのボタンがあります。ユーザーが購入をクリックすると、アップルの検証がチェックされ、製品が購入されます。

これは正常に機能しますが、製品を購入すると購入ボタンが「完了」に変わり、次にアプリケーションを実行すると、その特定の製品の購入ボタンが表示されなくなります。代わりに「完了」ボタンを表示する必要があります。私の問題は、製品を購入すると、完了ボタンではなく購入ボタンが表示されることです。

これは私のコードです:

-(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];


}
4

2 に答える 2

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製品がいつ復元されるかを示すコードの中にあなた自身がいます 。

于 2013-06-11T13:25:02.940 に答える
3

You need to add code that executes the restoreCompletedTransactions method...

add the [self checkPurchasedItems]; in the App's initial launch somewhere like the root view controller's viewDidLoad method to get the purchase button logic to show up..

keep the buttons.enabled = NO... this way the buttons are only enabled when the return methods arrive telling us what we already purchased... you should store those booleans for offline mode.

when the transactions are restored mark the buttons as enabled and/or hidden appropriately.

good luck!

于 2013-11-15T03:16:25.983 に答える