Ios 应用内购买正确的实现

Ios 应用内购买正确的实现,ios,in-app-purchase,in-app,Ios,In App Purchase,In App,我在移动应用程序中实现应用内购买时遇到问题 基本上,有时用户会收取两次费用。 此外,当用户在应用程序中被中断时,就像他们被重定向回itunes以完成付款,然后返回到应用程序,他们会看到错误“发生了错误…” 我是否正确实施了应用内购买 这是我的密码: 我做错了什么 - (void) myLeftAction { [self performSegueWithIdentifier: @"login" sender: self]; } - (void)viewDidLoad { [su

我在移动应用程序中实现应用内购买时遇到问题

基本上,有时用户会收取两次费用。 此外,当用户在应用程序中被中断时,就像他们被重定向回itunes以完成付款,然后返回到应用程序,他们会看到错误“发生了错误…”

我是否正确实施了应用内购买

这是我的密码:

我做错了什么

- (void) myLeftAction {
    [self performSegueWithIdentifier: @"login" sender: self];
}

- (void)viewDidLoad {
    [super viewDidLoad];


    UISwipeGestureRecognizer * recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(myLeftAction)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
    [self.view addGestureRecognizer:recognizer];


    done = NO;
    paymentProcessing = NO;

    shownProducts = [NSArray arrayWithObjects: @"com.example.a", @"com.example.b", @"com.example.c", @"com.example.d", nil];

    hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    hud.labelText = @"Loading";

    [self fetchAvailableProducts];
}

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

-(void)fetchAvailableProducts {
    if ([SKPaymentQueue canMakePayments])
    {
        NSSet *productIdentifiers = [NSSet setWithObjects: @"com.example.a", @"com.example.b", @"com.example.c", @"com.example.d",nil];
        productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
        productsRequest.delegate = self;
        [productsRequest start];
    }
    else {
        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
                                  @"Purchases are disabled in your device. Please enable in-app purchases before continuing." message:nil delegate:
                                  self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alertView show];
    }
}

- (BOOL)canMakePurchases {
    return [SKPaymentQueue canMakePayments];
}

- (void)purchaseMyProduct:(SKProduct*)product {
    if ([self canMakePurchases]) {
        SKPayment *payment = [SKPayment paymentWithProduct:product];
        [[SKPaymentQueue defaultQueue] addTransactionObserver: self];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
    else{
        paymentProcessing = NO;

        UIAlertView *alertView = [[UIAlertView alloc]initWithTitle: @"Purchases are disabled on your device. Please enable in-app purchases before continuing." message:nil delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
        [alertView show];
    }
}

-(IBAction)purchase:(id)sender
{
    if(done && !paymentProcessing) {
        paymentProcessing = YES;
        chosenProduct = [validProducts objectAtIndex: [sender tag]];
        [self purchaseMyProduct: chosenProduct];
    }
}

#pragma mark StoreKit Delegate

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions) {
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
                [self occuringTransaction: transaction];
                break;
            case SKPaymentTransactionStatePurchased:
                [self completeTransaction: transaction];
                break;
            case SKPaymentTransactionStateRestored:
                [self restoreTransaction: transaction];
                break;
            case SKPaymentTransactionStateFailed:
                [self failedTransaction: transaction];
                break;
            default:
                break;
        }
    }
}

- (void) occuringTransaction:(SKPaymentTransaction *)transaction
{
    [hud show: YES];
    NSLog(@"Purchasing");
}

- (void) processPurchase: (SKPaymentTransaction *)transaction
{
    id<FBGraphUser> fb = [[Auth sharedInstance] user];

    NSString * firstName = fb.first_name;
    NSString * lastName = fb.last_name;
    NSString * email = [fb objectForKey: @"email"];
    NSString * facebook_id = fb.id;

    PFObject * result = [PFObject objectWithClassName:@"payments"];
    result[@"firstName"] = firstName;
    result[@"lastName"] = lastName;
    result[@"email"] = email;
    result[@"facebookId"] = facebook_id;
    result[@"package"] = transaction.payment.productIdentifier;
    result[@"transactionId"] = transaction.transactionIdentifier;
    result[@"transactionError"] = transaction.error.localizedDescription;

    NSString *dateString = [NSDateFormatter localizedStringFromDate: transaction.transactionDate
                                                          dateStyle:NSDateFormatterShortStyle
                                                          timeStyle:NSDateFormatterFullStyle];

    result[@"transactionDate"] = dateString;
    result[@"transactionState"] = [NSString stringWithFormat: @"%ld", transaction.transactionState];

    [result saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
     {
         [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

         UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:
                                   @"Purchase is completed successfully. You can now choose the hashtags you want shown in your review on lulu." message:nil delegate:
                                   self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
         [alertView show];

         NSString * category = @"";

         if(
            [transaction.payment.productIdentifier isEqualToString: @"com.fakemylulu.player_1"] ||
            [transaction.payment.productIdentifier isEqualToString: @"com.fakemylulu.player_3"]
            ) {
             category = @"a";
         }
         else {
             category = @"b";
         }

         paymentProcessing = NO;

         [hud hide:YES];

         //push view manually
         UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
         fmHashtagsViewController *ivc = [storyboard instantiateViewControllerWithIdentifier:@"hashtags"];
         ivc.category = transaction.payment.productIdentifier;
         [self.navigationController pushViewController:ivc animated:NO];
     }];

}

-(void)completeTransaction:(SKPaymentTransaction *)transaction {
    NSLog(@"Completed transaction");

    if([transaction.payment.productIdentifier isEqualToString: chosenProduct.productIdentifier]) {
        [self processPurchase: transaction];
    }
}

-(void)restoreTransaction:(SKPaymentTransaction *)transaction {
    NSLog(@"Restored transaction");
    [self processPurchase: transaction];
}

-(void)failedTransaction:(SKPaymentTransaction *)transaction
{
    [hud hide: YES];
    paymentProcessing = NO;

    if(transaction.error.code != SKErrorPaymentCancelled)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"An error occured! We could not process your payment. Please try again."
                                                        message:[transaction.error localizedDescription]
                                                       delegate:nil
                                              cancelButtonTitle:nil
                                              otherButtonTitles:@"OK", nil];
        [alert show];
    }

    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}

-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSInteger count = [response.products count];

    if (count>0)
    {
        validProducts = response.products;

        NSUInteger index = 0;

        for (SKProduct * x in validProducts)
        {
            NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
            [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
            [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
            [numberFormatter setLocale: x.priceLocale];
            NSString *formattedPrice = [numberFormatter stringFromNumber: x.price];

            if([x.productIdentifier isEqualToString: @"com.fakemylulu.romantic_1"]) {
                [self.a setTitle: [NSString stringWithFormat: @"%@", formattedPrice] forState:UIControlStateNormal];
                self.a.tag = index;
            }
            else if([x.productIdentifier isEqualToString: @"com.fakemylulu.romantic_3"])
            {
                [self.b setTitle: [NSString stringWithFormat: @"%@", formattedPrice] forState:UIControlStateNormal];
                self.b.tag = index;
            }
            else if([x.productIdentifier isEqualToString: @"com.fakemylulu.player_1"])
            {
                [self.c setTitle: [NSString stringWithFormat: @"%@", formattedPrice] forState:UIControlStateNormal];
                self.c.tag = index;
            }
            else if([x.productIdentifier isEqualToString: @"com.fakemylulu.player_3"])
            {
                [self.d setTitle: [NSString stringWithFormat: @"%@", formattedPrice] forState:UIControlStateNormal];
                self.d.tag = index;
            }

            index += 1;
        }
        done = YES;
    } else {
        UIAlertView *tmp = [[UIAlertView alloc]
                            initWithTitle:@"Not Available"
                            message:@"No products available for purchase"
                            delegate:self
                            cancelButtonTitle:nil
                            otherButtonTitles:@"Ok", nil];
        [tmp show];
    }

    [hud hide:YES];
}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    NSLog(@"Failed to load list of products. %@", error);

    UIAlertView *tmp = [[UIAlertView alloc]
                        initWithTitle:@"Oops"
                        message:@"There was an error retrieving the list of products. Please try this app again later."
                        delegate:self
                        cancelButtonTitle:nil
                        otherButtonTitles:@"Ok", nil];
    [tmp show];
}

- (void)dealloc {
    if ([SKPaymentQueue canMakePayments]) {
        [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    }
}
-(无效)我的引用{
[self-PerformsgueWithIdentifier:@“登录”发件人:self];
}
-(无效)viewDidLoad{
[超级视图下载];
UISweepGestureRecognizer*recognizer=[[UISweepGestureRecognizer alloc]initWithTarget:self action:@selector(myLeftAction)];
[识别器设置方向:(UISwipegestureRecognitizerDirectionRight)];
[self.view addgesturecognizer:recognizer];
完成=否;
paymentProcessing=否;
shownProducts=[NSArray数组,其对象为:@“com.example.a”@“com.example.b”@“com.example.c”@“com.example.d”,无];
hud=[MBProgressHUD ShowHUD AddedTo:self.view动画:是];
hud.labelText=@“加载”;
[自取可用产品];
}
-(无效)未收到记忆警告{
[超级记忆警告];
//处置所有可以重新创建的资源。
}
-(无效)获取可用产品{
如果([SKPaymentQueue canMakePayments])
{
NSSet*productIdentifiers=[NSSet setWithObjects:@“com.example.a”、@“com.example.b”、@“com.example.c”、@“com.example.d”、nil];
productsRequest=[[SKProductsRequest alloc]initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate=self;
[产品需求启动];
}
否则{
UIAlertView*alertView=[[UIAlertView alloc]initWithTitle:
@“在您的设备中已禁用购买。请在继续之前启用应用内购买。”消息:无委托:
自取消按钮提示:@“Ok”其他按钮提示:无];
[警报视图显示];
}
}
-(BOOL)可以进行购买{
return[SKPaymentQueue canMakePayments];
}
-(无效)purchaseMyProduct:(SKProduct*)产品{
如果([self-canMakePurchases]){
SKPayment*payment=[SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue]addTransactionObserver:self];
[[SKPaymentQueue defaultQueue]addPayment:payment];
}
否则{
paymentProcessing=否;
UIAlertView*alertView=[[UIAlertView alloc]initWithTitle:@“在您的设备上禁用购买。请在继续之前启用应用内购买。”消息:无委托:自取消按钮提示:@“确定”其他按钮提示:无];
[警报视图显示];
}
}
-(iAction)购买:(id)发件人
{
如果(完成&&!付款处理){
paymentProcessing=是;
chosenProduct=[validProducts objectAtIndex:[sender tag]];
[自购MyProduct:chosenProduct];
}
}
#pragma-mark-StoreKit委托
-(void)paymentQueue:(SKPaymentQueue*)队列更新事务:(NSArray*)事务
{
用于(SKPaymentTransaction*交易中的交易){
开关(transaction.transactionState){
案例SKPaymentTransactionStatePurchasing:
[自发生交易:交易];
打破
案例SKPaymentTransactionStatesPurchased:
[自完成交易:交易];
打破
案例SKPaymentTransactionStateRestored:
[自恢复交易:交易];
打破
案例SKPaymentTransactionState失败:
[自失效交易:交易];
打破
违约:
打破
}
}
}
-(作废)发生交易:(SKPaymentTransaction*)交易
{
[抬头显示器显示:是];
NSLog(“采购”);
}
-(作废)processPurchase:(SKPaymentTransaction*)交易
{
id fb=[[Auth sharedInstance]用户];
NSString*firstName=fb.first\u name;
NSString*lastName=fb.last_name;
NSString*email=[fb objectForKey:@“email”];
NSString*facebook_id=fb.id;
PFObject*result=[pfobjectobjectwithclassname:@“payments”];
结果[@“firstName”]=firstName;
结果[@“lastName”]=lastName;
结果[@“电子邮件”]=电子邮件;
结果[@“facebookId”]=facebook_id;
结果[@“package”]=transaction.payment.productIdentifier;
结果[@“transactionId”]=transaction.transactionIdentifier;
结果[@“transactionError”]=transaction.error.localizedDescription;
NSString*dateString=[NSDateFormatter localizedStringFromDate:transaction.transactionDate
dateStyle:NSDateFormatterShortStyle
时间样式:NSDateFormatterFullStyle];
结果[@“transactionDate”]=dateString;
结果[@“transactionState”]=[NSString stringWithFormat:@“%ld”,transaction.transactionState];
[结果saveInBackgroundWithBlock:^(布尔成功,N错误*错误)
{
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
UIAlertView*alertView=[[UIAlertView alloc]initWithTitle:
@“购买已成功完成。您现在可以选择要在您对lulu的评论中显示的标签。”消息:无代表:
自取消按钮提示:@“Ok”其他按钮提示:无];
[警报视图显示];
NSString*类别=@“”;
如果(
[transaction.payment.productIdentifier IsequalString:@“com.fakemylu.player_1”]||
[transaction.payment.productIdentifier IsequalString:@“com.fakemyluu.player_3”]
) {
类别=@“a”;
}
否则{
类别=@“b”;
}
paymentProcessing=否;
[抬头显示器隐藏:是];
//手动推送视图
UIStoryboard*情节提要=[UIStoryboard storyboard with name