User Cancels In App Purchase. How to end the transaction
I have a small issue with iAP. I have the code working for the most part. It's just when the user cancels the purchase, the device doesn't think its over and keeps it. Thus if you try to buy it again, you will buy 2 of the product...which is bad, since they only want one. I must be missing some code. I will attach a Console log so you can see whats going on.
2010-12-21 15:47:29.364[204:307] Parental-controls are disabled (I launch the iAP)
2010-12-21 15:47:33.816[204:307] Win (There are products)
2010-12-21 15:47:37.043[204:307] Buying... (I pressed buy)
2010-12-21 15:47:40.661[204:307] FailedTransaction (Essentially I canceled)
2010-12-21 15:47:40.674[204:307] DefaultAction (which is to dismiss the modal view)
2010-12-21 15:47:42.738[204:307] Parental-controls are disabled (reopen the iAP view)
2010-12-21 15:47:44.440[204:307] Win
2010-12-21 15:47:46.939[204:307] Buying...
2010-12-21 15:47:46.945[204:307] Buying...
2010-12-21 15:47:48.414[204:307] FailedTransaction
2010-12-21 15:47:48.427[204:307] DefaultAction
2010-12-21 15:47:48.437[204:307] FailedTransaction
2010-12-21 15:47:48.449[204:307] DefaultAction
2010-12-21 15:47:50.622[204:307] Parental-controls are disabled
2010-12-21 15:47:51.314[204:307] Win
2010-12-21 15:47:51.883[204:307] Buying...(see how it compounds?)
2010-12-21 15:47:51.889[204:307] Buying...
2010-12-21 15:47:51.896[204:307] Buying...
2010-12-21 15:48:10.764[204:307] Posted5
2010-12-21 15:48:10.782[204:307] Yipeee!
2010-12-21 15:48:10.810[204:307] Posted5 (It gave the users 15 credits!)
2010-12-21 15:48:10.869[204:307] Yipeee!
2010-12-21 15:48:10.897 204:307] Posted5
2010-12-21 15:48:10.912[204:307] Yipeee!
Here is the code I am running:
#import "PurchaserViewController.h"
@implementation PurchaserViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"yayadaadul.com/checkcredits.php"]]];
if ([SKPaymentQueue canMakePayments]) {
NSLog(@"Parental-controls are disabled");
SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"com.company.name.song"]];
productsRequest.delegate = self;
[productsRequest start];
} else {
NSLog(@"Parental-controls are enabled");
}
}
- (IBAction)purchase {
SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.changedwe.worksinxcode.song"];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (IBAction)stop {
[player stop];
}
- (IBAction)play {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file = [NSString stringWithFormat:@"%@/Song.mp3", documentsDirectory];
player = [[AVAudioPlayer alloc] initWithC开发者_C百科ontentsOfURL:[NSURL fileURLWithPath:file] error:nil];
[player play];
}
- (void)downloadFromURL:(NSURL *)url {
NSData *data = [NSData dataWithContentsOfURL:url];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *file = [NSString stringWithFormat:@"%@/Song.mp3", documentsDirectory];
[data writeToFile:file atomically:YES];
}
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
SKProduct *validProduct = nil;
int count = [response.products count];
if (count > 0) {
validProduct = [response.products objectAtIndex:0];
NSLog(@"Win");
} else if (!validProduct) {
NSLog(@"No products available");
}
}
-(IBAction)home {
[self dismissModalViewControllerAnimated:YES];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
NSLog(@"Buying...");
break;
break;
case SKPaymentTransactionStatePurchased:
[self downloadFromURL:[NSURL URLWithString:@""]];
NSString *post =[NSString stringWithFormat:@"username=lol&cval=5"];
NSString *hostStr = @"http://mysite.com/subdom/ccredit.php?";
hostStr = [hostStr stringByAppendingString:post];
NSLog(@"Posted5");
NSLog(@"Yipeee!");
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://Action to Post.php?"]]];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(@"Restored");
break;
case SKPaymentTransactionStateFailed:
NSLog(@"FailedTransaction");
// [self finishTransaction:transaction wasSuccessful:NO];
if (transaction.error.code != SKErrorPaymentCancelled) {
NSLog(@"An error encounterd");
}
//You need to clear their purchases here
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
NSLog(@"DefaultAction");
[self dismissModalViewControllerAnimated:YES];
break;
}
}
}
Yes. You need to implement the success and failure delegate methods of SKRequest. Please refer to the documentation. http://developer.apple.com/library/ios/#documentation/StoreKit/Reference/SKRequestDelegate/Reference/Reference.html#//apple_ref/doc/uid/TP40008416
- (void)requestDidFinish:(SKRequest *)request
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
It looks like you keep adding yourself as the transaction observer every time the purchase
action is performed. Press it once, everything works fine. Press it again and your observer delegate methods get called twice, both for the second transaction.
精彩评论