2013-10-12 95 views
0

当我运行下面的代码的应用程序,我购买使用我的测试帐户的产品之一,我得到这个在我的控制台:在应用程序内购买 - 购买成功,则交易失败

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 

感谢

+0

是不是“破”; “案件”之间缺乏? –

+0

对不起,我不明白。你的意思是说这行代码没有意义吗? – Dylanthepiguy

+0

也许SKPaymentTransactionStateFailed在SKPaymentTransactionStatePurchased代码运行后总是执行,因为您不使用break;之后[[SKPaymentQueue defaultQueue] finishTransaction:transaction]; –

回答

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语言的常见问题。 语言。我们有时会忘记这一点。