We're developing an app which (ofcourse) uses in app purchases (IAP).
I've done everything in the guide to enable iap and everything works fine, untill I want to make purchase.
Some of the code:
MainViewController.m
-(void)viewDidLoad {
if ([SKPaymentQueue canMakePayments]) {
MyStoreObserver *observer = [[MyStoreObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObjects: @"com.company.app.product1", @"com.company.app.product1", nil]];
request.delegate = self;
[request start];
}
};
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
for (SKProduct *prod in response.products) {
NSLog(@"%@ (%@)", prod.localizedTitle, prod.price);
}
[request release];
};
-(IBAction)clickBuy:(UIButton *)__sender {
SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.company.app.product1"];
[[SKPaymentQueue defaultQueue] addPayment:payment];
};
MyStoreObserver.m
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
NSLog(@"SKPaymentTransactionStatePurchased");
break;
case SKPaymentTransactionStateFailed:
NSLog(@"SKPaymentTransactionStateFailed");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"SKPaymentTransactionStateRestored");
break;
case SKPaymentTransactionStatePurchasing:
NSLog(@"SKPaymentTransactionStatePurchasing");
default:
break;
}
}
};
The productRequest:
delegate method shows 2 products with their name / price. Like I entered in the iTunes connect site.
But once I click the 'buy' button, no dialog pops up or asks me for my credentials. Only "SKPaymentTransactionStatePurchasing" is logged.
And I:
- ... have logged out in the settings/store pane
- ... am using the right provisioning profiles
- ... am desperate
Anyone?
I encountered a similar problem, but mine was more of a boneheaded move on my part. I had 'refactored' the call to finishTransaction
so that it was being called for every state in transactionState
:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
// do stuff
break;
case SKPaymentTransactionStateFailed:
// do stuff
break;
case SKPaymentTransactionStateRestored:
// do stuff
break;
default:
break;
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
Turns out™, this will also call finishTransaction
on SKPaymentTransactionStatePurchasing
, which will cause a crash. Moving finishTransaction
back into each case of the switch statement fixed that.
After Pulling my hair out in frustration with a similar problem (instead of not being asked for my credentials it was automatically filling in the email address without the option to change it even when logged out of the store in the settings app). I discovered that I had a failed transaction stuck in the queue from development builds on the same device, I had to clear all of the transactions in the queue on the device and then try to test again.
NSArray *transactions = [[SKPaymentQueue defaultQueue] transactions];
for(id transaction in transactions){
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
I hooked this code upto an IBOutlet and after being run once my in app purchases worked.
I also had been pulling my hair out a bit with this. Turns out a simple reboot of the test device got everything working fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With