• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

[复制链接]
菜鸟教程小白 发表于 2022-12-13 09:50:52 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我在我的应用程序中有一个应用程序内购买用于删除广告横幅,当我成功购买并返回到我的主 View Controller 时,广告没有删除但是当我退出应用程序并重新打开它时,广告消失了并保持消失。几乎就像它记得我在下一次加载时购买了删除广告 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.



关于如何做到这一点的任何想法?

谢谢!

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

View Controller .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

View Controller .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 = @"https://www.google.com";
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)locationManagerCLLocationManager *)manager didUpdateLocationsNSArray *)locations
{
NSLog(@"%@", [locations lastObject]);
}

-(void)motionBeganUIEventSubtype)motion withEventUIEvent *)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)PokeABowlAdid)sender {
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_ADS_KEY]  isEqualToString: @"No"]){ // NEW CODE
    // Code to show ads
    _PokeABowlAd.hidden = NO;

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString: @"http://www.pokeabowl.com/"]];
} 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:
    #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 actionselector(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 actionselector(restoreTapped];

}

- (void)restoreTappedid)sender {
[[RageIAPHelper sharedInstance] restoreCompletedTransactions];
}

- (void)viewWillAppearBOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self selectorselector(productPurchased name:IAPHelperProductPurchasedNotification object:nil];
}

- (void)viewWillDisappearBOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)productPurchasedNSNotification *)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)numberOfSectionsInTableViewUITableView *)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:
    #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:
    #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(@"reviously 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
    #import "IAPHelper.h"

@interface RageIAPHelper : IAPHelper

+ (RageIAPHelper *)sharedInstance;

@end

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



Best Answer-推荐答案


所以我认为正在发生的事情是它直到initWithProductIdentifers 才识别您的购买。正在调用 IAP.m 中的方法(仅在加载应用程序时发生)。

所以在 IAP.m 中尝试修改:

- (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 没有被调用的原因是因为您的 Storyboard中似乎有两个 NavigationController。尝试删除第二个(VC 和 MasterVC 之间的那个)。如果您同时执行这两项操作,则应该可以正常工作。

关于ios - 购买应用内购买后保存更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31975790/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap