购买应用内购买后保存更改

编程入门 行业动态 更新时间:2024-10-25 04:21:45
本文介绍了购买应用内购买后保存更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我的应用中有一个应用内购买项,用于删除广告横幅,当我成功购买并返回主视图控制器时,退出应用并重新打开时,广告并未被删除,但广告不见了,而且不见了.几乎就像它还记得我在下一次加载时购买了移除广告IAP,但不是在购买后立即购买.一个非常聪明的人告诉我,我需要这样做:

I have an In-App Purchase in my app for removing an ad banner and when I made a successful purchase and went back to my main view controller, the ad was not removed BUT when i quit the app and reopen it, the ad is gone and stays gone. Almost like it remembers that I've purchased the remove ads IAP on the next load, but not right after it is purchased. A very smart person told me i need to do this:

因此,现在您要做的就是调用位于在您返回VC之后,可以使用viewWillAppear/viewDidLoad方法购买IAP.您的操作方式取决于您.如果你需要帮助鉴于此,我建议您提出一个新问题线程变得很长.如果您支持我的回答,我将不胜感激并选择它作为正确的答案,因为我已经帮助了您工作.

So now all you have to do is call the code that is located in the viewWillAppear / viewDidLoad methods once you return to your VC after purchasing the IAP. How you do that is up to you. If you need help with that I would suggest asking a new question since this comment thread is getting very long. I'd appreciate if you upvote my answer and choose it as the correct answer since I've helped you get this working.

关于如何执行此操作的任何想法?

Any thoughts on how to do this?

谢谢!

这是我的Master View Controller的屏幕截图:

Here is a screenshot of my Master View Controller:

ViewController.h

ViewController.h

#import <UIKit/UIKit.h> #import <StoreKit/StoreKit.h> #import <CoreMotion/CoreMotion.h> #import <CoreLocation/CoreLocation.h> #import <MapKit/MapKit.h> @interface ViewController : UIViewController <UIWebViewDelegate, MKMapViewDelegate, CLLocationManagerDelegate> @property (strong, nonatomic) IBOutlet UIWebView *viewWeb; @property (nonatomic, strong) CLLocationManager *locationManager; @property (nonatomic, strong) CLLocation *currentLocation; @property (weak, nonatomic) IBOutlet UIImageView *PokeABowlAd; @end

ViewController.m:

ViewController.m:

#define SHOW_ADS_KEY @"Show Ads Key" #define k_Save @"Saveitem" #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewController () <UITextViewDelegate> @end @implementation ViewController @synthesize viewWeb; - (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; [self.navigationItem setBackBarButtonItem:backButtonItem]; NSString *fullURL = @"www.google"; NSURL *url = [NSURL URLWithString:fullURL]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; viewWeb.scalesPageToFit = YES; viewWeb.scrollView.bounces = NO; [viewWeb loadRequest:requestObj]; } #pragma mark - CLLocationManagerDelegate // Wait for location callbacks - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"%@", [locations lastObject]); } -(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (event.type == UIEventSubtypeMotionShake) { NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"iitc" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil]; [viewWeb stringByEvaluatingJavaScriptFromString:jsString]; } } - (NSUInteger)supportedInterfaceOrientations { if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { return UIInterfaceOrientationMaskAllButUpsideDown; } else { return UIInterfaceOrientationMaskAll; } } - (IBAction)PokeABowlAd:(id)sender { if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY] isEqualToString: @"No"]){ // NEW CODE // Code to show ads _PokeABowlAd.hidden = NO; [[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"www.pokeabowl/"]]; } else { _PokeABowlAd.hidden = YES; } NSLog(@"Shows ads?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]); } - (void)viewWillAppear { if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY] isEqualToString: @"No"]){ // NEW CODE // Code to show ads _PokeABowlAd.hidden = NO; } else { _PokeABowlAd.hidden = YES; } NSLog(@"Shows ads?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]); } @end

MasterViewController.m:

MasterViewController.m:

#import "MasterViewController.h" #import "DetailViewController.h" #import "RageIAPHelper.h" #import <StoreKit/StoreKit.h> @interface MasterViewController () { NSArray *_products; NSNumberFormatter * _priceFormatter; } @end @implementation MasterViewController - (void)viewDidLoad { [super viewDidLoad]; UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; [self.navigationItem setBackBarButtonItem:backButtonItem]; self.title = @"Settings"; self.refreshControl = [[UIRefreshControl alloc] init]; [self.refreshControl addTarget:self action:@selector(reload) forControlEvents:UIControlEventValueChanged]; [self reload]; [self.refreshControl beginRefreshing]; _priceFormatter = [[NSNumberFormatter alloc] init]; [_priceFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; [_priceFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Restore" style:UIBarButtonItemStylePlain target:self action:@selector(restoreTapped:)]; } - (void)restoreTapped:(id)sender { [[RageIAPHelper sharedInstance] restoreCompletedTransactions]; } - (void)viewWillAppear:(BOOL)animated { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:) name:IAPHelperProductPurchasedNotification object:nil]; } - (void)viewWillDisappear:(BOOL)animated { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)productPurchased:(NSNotification *)notification { NSString * productIdentifier = notification.object; [_products enumerateObjectsUsingBlock:^(SKProduct * product, NSUInteger idx, BOOL *stop) { if ([product.productIdentifier isEqualToString:productIdentifier]) { [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; *stop = YES; } }]; } - (void)reload { _products = nil; [self.tableView reloadData]; [[RageIAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) { if (success) { _products = products; [self.tableView reloadData]; } [self.refreshControl endRefreshing]; }]; } #pragma mark - Table View - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _products.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; SKProduct * product = (SKProduct *) _products[indexPath.row]; cell.textLabel.text = product.localizedTitle; [_priceFormatter setLocale:product.priceLocale]; cell.detailTextLabel.text = [_priceFormatter stringFromNumber:product.price]; if ([[RageIAPHelper sharedInstance] productPurchased:product.productIdentifier]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; cell.accessoryView = nil; } else { UIButton *buyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; buyButton.frame = CGRectMake(0, 0, 72, 37); [buyButton setTitle:@"Buy" forState:UIControlStateNormal]; buyButton.tag = indexPath.row; [buyButton addTarget:self action:@selector(buyButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; cell.accessoryType = UITableViewCellAccessoryNone; cell.accessoryView = buyButton; } return cell; } - (void)buyButtonTapped:(id)sender { UIButton *buyButton = (UIButton *)sender; SKProduct *product = _products[buyButton.tag]; NSLog(@"Buying %@...", product.productIdentifier); [[RageIAPHelper sharedInstance] buyProduct:product]; } @end

IAPHelper.h:

IAPHelper.h:

#import <StoreKit/StoreKit.h> UIKIT_EXTERN NSString *const IAPHelperProductPurchasedNotification; typedef void (^RequestProductsCompletionHandler)(BOOL success, NSArray * products); @interface IAPHelper : NSObject - (id)initWithProductIdentifiers:(NSSet *)productIdentifiers; - (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler; - (void)buyProduct:(SKProduct *)product; - (BOOL)productPurchased:(NSString *)productIdentifier; - (void)restoreCompletedTransactions; @property (weak, nonatomic) IBOutlet UIImageView *PokeABowlAd; @end

IAPHelper.m:

IAPHelper.m:

#define SHOW_ADS_KEY @"Show Ads Key" // 1 #import "IAPHelper.h" #import <StoreKit/StoreKit.h> NSString *const IAPHelperProductPurchasedNotification = @"IAPHelperProductPurchasedNotification"; // 2 @interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver> @end // 3 @implementation IAPHelper { SKProductsRequest * _productsRequest; RequestProductsCompletionHandler _completionHandler; NSSet * _productIdentifiers; NSMutableSet * _purchasedProductIdentifiers; } - (id)initWithProductIdentifiers:(NSSet *)productIdentifiers { if ((self = [super init])) { // Store product identifiers _productIdentifiers = productIdentifiers; // Check for previously purchased products _purchasedProductIdentifiers = [NSMutableSet set]; for (NSString * productIdentifier in _productIdentifiers) { BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier]; if (productPurchased) { [_purchasedProductIdentifiers addObject:productIdentifier]; NSLog(@"Previously purchased: %@", productIdentifier); // NEW CODE if ([productIdentifier isEqualToString:@"Ads"]){ [[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:SHOW_ADS_KEY]; [[NSUserDefaults standardUserDefaults] synchronize]; } // NEW CODE ^^ } else { NSLog(@"Not purchased: %@", productIdentifier); } } // Add self as transaction observer [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; } return self; } - (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler { // 1 _completionHandler = [completionHandler copy]; // 2 _productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers]; _productsRequest.delegate = self; [_productsRequest start]; } - (BOOL)productPurchased:(NSString *)productIdentifier { return [_purchasedProductIdentifiers containsObject:productIdentifier]; } - (void)buyProduct:(SKProduct *)product { NSLog(@"Buying %@...", product.productIdentifier); SKPayment * payment = [SKPayment paymentWithProduct:product]; [[SKPaymentQueue defaultQueue] addPayment:payment]; } #pragma mark - SKProductsRequestDelegate - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSLog(@"Loaded list of products..."); _productsRequest = nil; NSArray * skProducts = response.products; for (SKProduct * skProduct in skProducts) { NSLog(@"Found product: %@ %@ %0.2f", skProduct.productIdentifier, skProduct.localizedTitle, skProduct.price.floatValue); } _completionHandler(YES, skProducts); _completionHandler = nil; } - (void)request:(SKRequest *)request didFailWithError:(NSError *)error { NSLog(@"Failed to load list of products."); _productsRequest = nil; _completionHandler(NO, nil); _completionHandler = nil; } #pragma mark SKPaymentTransactionOBserver - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction * transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: [self completeTransaction:transaction]; break; case SKPaymentTransactionStateFailed: [self failedTransaction:transaction]; break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; default: break; } }; } - (void)completeTransaction:(SKPaymentTransaction *)transaction { NSLog(@"completeTransaction..."); [self provideContentForProductIdentifier:transaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } - (void)restoreTransaction:(SKPaymentTransaction *)transaction { NSLog(@"restoreTransaction..."); [self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; } - (void)failedTransaction:(SKPaymentTransaction *)transaction { NSLog(@"failedTransaction..."); if (transaction.error.code != SKErrorPaymentCancelled) { NSLog(@"Transaction error: %@", transaction.error.localizedDescription); } [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; } - (void)provideContentForProductIdentifier:(NSString *)productIdentifier { [_purchasedProductIdentifiers addObject:productIdentifier]; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier]; [[NSUserDefaults standardUserDefaults] synchronize]; [[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil]; } - (void)restoreCompletedTransactions { [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; } @end

RageIAPHelper.h

RageIAPHelper.h

#import "IAPHelper.h" @interface RageIAPHelper : IAPHelper + (RageIAPHelper *)sharedInstance; @end

RageIAPHelper.m

RageIAPHelper.m

#import "RageIAPHelper.h" #import "ViewController.h" @implementation RageIAPHelper + (RageIAPHelper *)sharedInstance { static dispatch_once_t once; static RageIAPHelper * sharedInstance; dispatch_once(&once, ^{ NSSet * productIdentifiers = [NSSet setWithObjects: @"com.GPS.iapra", @"com.GPS.iapb", nil]; sharedInstance = [[self alloc] initWithProductIdentifiers:productIdentifiers]; }); return sharedInstance; } @end

推荐答案

因此,我认为正在发生的事情是在IAP.m中的 initWithProductIdentifers 方法被调用之前,它无法识别您的购买行为(只会在您加载应用程序时发生).

So I think what's happening is that it isn't recognizing your purchase until the initWithProductIdentifers method in IAP.m is being called (which only happens when you load the application).

因此,请在IAP.m中尝试修改:

So in IAP.m try modifying:

- (void)completeTransaction:(SKPaymentTransaction *)transaction { NSLog(@"completeTransaction..."); [self provideContentForProductIdentifier:transaction.payment.productIdentifier]; [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; }

收件人:

- (void)completeTransaction:(SKPaymentTransaction *)transaction { NSLog(@"completeTransaction..."); [self provideContentForProductIdentifier:transaction.payment.productIdentifier]; // NEW CODE if ([transaction.payment.productIdentifier isEqualToString:@"Ads"]){ [[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:SHOW_ADS_KEY]; [[NSUserDefaults standardUserDefaults] synchronize]; } // NEW CODE ^^ [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; }

此外,我认为未调用viewWillAppear的原因是,它看起来好像您的情节提要中有两个NavigationControllers.尝试删除第二个(VC和MasterVC之间的一个).如果您同时执行这两项操作,那么它应该可以正常工作.

Also, I think the reason your viewWillAppear isn't getting called is because it looks like you have two NavigationControllers in your storyboard. Try deleting the second one (the one between VC and MasterVC). If you do both of these that should make it work.

更多推荐

购买应用内购买后保存更改

本文发布于:2023-10-30 23:43:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1544356.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!