应用内购买 - 购买成功然后交易失败

时间:2013-10-12 01:22:24

标签: ios in-app-purchase

当我使用下面的代码运行应用程序时,我使用我的测试帐户购买其中一个产品,并在控制台中获取此信息:

queue
queue
unlocked:
  buy20
Transaction Failed

以某种方式,购买成功地在- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions方法中成功,然后立即失败。你看到下面的代码有什么问题,或者你之前听说过这个问题吗?

#import "BuyWindowViewController.h"

@interface BuyWindowViewController ()

@end

@implementation BuyWindowViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [_closeButton setTitle:@"Close" forState:UIControlStateNormal];
    [_closeButton.titleLabel setFont:[UIFont fontWithName:@"Helvetica" size:16.0f]];
    [_titleBar setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"Button 400x50 Yellow.png"]]];

    _productIDs = [iAPBundleIDs returnAllIDs];
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    [self getProductID];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)closeButtonPressed:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewDidUnload {
    [self setTitleBar:nil];
    [super viewDidUnload];

}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotate {
    return YES;
}

- (IBAction)infoButtonPressed:(UIButton *)sender {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Serpentine!" message:@"" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
    if (sender.tag == 1) {
        //buy 20
        alert.title = @"Instantly get 20 Upgrade Points to spend in the Shop!";
    } else if (sender.tag == 2) {
        //buy 45
        alert.title = @"Instantly get 45 Upgrade Points to spend in the Shop!";
    } else if (sender.tag == 3) {
        //buy 100
        alert.title = @"Instantly get 100 Upgrade Points to spend in the Shop!";
    } else if (sender.tag == 4) {
        //double
        alert.title = @"Permanently double the upgrade points you receive at the end of each game!";
    } else if (sender.tag == 5) {
        //remove ads + 20
        alert.title = @"Remove those annoying iAds and get 20 upgrade points with one purchase!";
    }
    [alert show];
}

- (IBAction)purchaseButtonPressed:(UIButton *)sender {
    _whichProduct = 0;
    if (sender.tag == 1) {
        //buy 20
        _whichProduct = 1;
    } else if (sender.tag == 2) {
        //buy 45
        _whichProduct = 2;
    } else if (sender.tag == 3) {
        //buy 100
        _whichProduct = 0;
    } else if (sender.tag == 4) {
        //double
        _whichProduct = 3;
    } else if (sender.tag == 5) {
        //remove ads + 20
        _whichProduct = 4;
    }

    SKPayment *payment = [SKPayment paymentWithProduct:_products[_whichProduct]];
    [[SKPaymentQueue defaultQueue] addPayment:payment];

    [self showLoadingWithText:@"Purchasing item..."];
}

#pragma mark - Loading Stuff

- (void)couldNotConnectToStoreWithText:(NSString *)text {
    [_spinner removeFromSuperview];
    [_spinner startAnimating];
    [_spinnerLabel setText:text];
}

- (void)hideLoading {
    [UIView animateWithDuration:0.5f animations:^{
        _spinnerBackground.alpha = 0;
    } completion:^(BOOL finished) {
        [_spinner removeFromSuperview];
        [_spinnerLabel removeFromSuperview];
        [_spinnerBackground removeFromSuperview];
    }];
}

- (void)showLoadingWithText:(NSString *)text {
    [_spinnerBackground addSubview:_spinner];
    [_spinnerBackground addSubview:_spinnerLabel];
    _spinnerLabel.text = text;

    [self.view addSubview:_spinnerBackground];
    [self.view bringSubviewToFront:_spinnerBackground];

    [UIView animateWithDuration:0.5f animations:^{
        _spinnerBackground.alpha = 0;
    }];
}


#pragma mark - iAP

- (void)getProductID {
    if ([SKPaymentQueue canMakePayments]) {
        SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIDs];
        request.delegate = self;

        [request start];
    } else {
        [self couldNotConnectToStoreWithText:@"Error: Could not connect to store. Try enabling in-app-purchases in settings"];
    }

}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    NSArray *products = response.products;
    if (products.count != 0) {
        _products = products;

        [self hideLoading];
    } else {
        [self couldNotConnectToStoreWithText:@"Error: Could not connect to iTunes"];
    }

    products = response.invalidProductIdentifiers;

    for (SKProduct *product in products) {
        NSLog(@"Product not found: %@", product);
    }
}

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

            case SKPaymentTransactionStateFailed:NSLog(@"Transaction Failed");//[[[UIAlertView alloc] initWithTitle:@"Serpentine" message:@"Error: Transaction Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

            default:break;
        }
    }
}

- (void)unlockPurchase {
    NSLog(@"unlocked:");
    if (_whichProduct == 1) {
        //buy 20
        NSLog(@"  buy20");
    } else if (_whichProduct == 2) {
        //buy 45
        NSLog(@"  buy45");
    } else if (_whichProduct == 0) {
        //buy 100
        NSLog(@"  buy100");
    } else if (_whichProduct == 3) {
        //double
        NSLog(@"  buydouble");
    } else if (_whichProduct == 4) {
        //remove ads + 20
        NSLog(@"  buyads");
    }

    [[[UIAlertView alloc] initWithTitle:@"Serpentine" message:@"Purchase successful!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
    [self hideLoading];
}

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
    [self unlockPurchase];
    NSLog(@"restore");
}

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

@end

由于

1 个答案:

答案 0 :(得分:1)

在您的代码中:

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

            case SKPaymentTransactionStateFailed:NSLog(@"Transaction Failed");//[[[UIAlertView alloc] initWithTitle:@"Serpentine" message:@"Error: Transaction Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

            default:break;
        }
    }
}

请添加休息;声明如下

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
    NSLog(@"queue");
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchased:[self unlockPurchase];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                // we want skip next case
                break; // skipping next "case"
            case SKPaymentTransactionStateFailed:NSLog(@"Transaction Failed");//[[[UIAlertView alloc] initWithTitle:@"Serpentine" message:@"Error: Transaction Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil] show];
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

            default:break;
        }
    }
}

问题是下一个案例首先执行。应明确跳过它。这是c语言中的常见问题。 语言。我们有时会忘记这一点。