应用内购买后,viewWillAppear 会多次加载购买的商品

Posted

技术标签:

【中文标题】应用内购买后,viewWillAppear 会多次加载购买的商品【英文标题】:After In-App Purchase, viewWillAppear Loads The Purchased Item Multiple Times 【发布时间】:2015-08-13 21:31:54 【问题描述】:

我的应用内购买有问题。离开 MasterViewController(列出并购买 IAP 项目)后,我来到 ViewController,它在 viewDidLoad 中检查购买的项目,但我也有一个 viewWillAppear 检查购买的项目并在加载 ViewController 时解锁这些购买的项目.

问题是,每次 ViewController 重新加载或刷新、离开然后返回时,viewWillAppear 都会检查购买的物品并再次解锁物品,在我的情况下,购买的物品来自 javascript 文件,这恰好发生在多次加载 JS,一遍又一遍地用相同的 IAP 项使应用程序混乱。

例如,如果您购买了“书签”,则每次重新加载 ViewController 时,您都会一遍又一遍地获得另一个“书签”工具。

我如何获得它以使 IAP 只加载一次?

我的 viewWillAppear 看起来像这样:

- (void)viewWillAppear:(BOOL)animated 
// Check To See If The Uniques IAP Has Been Paid For
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_UNIQUES_KEY] isEqualToString: @"YES"]) // NEW CODE
    // Code to show bookmarks

 else 
    NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Uniques" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    [viewWeb stringByEvaluatingJavaScriptFromString:jsString];    
NSLog(@"Shows uniques?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_UNIQUES_KEY]);

// Check To See If The PL Numbers IAP Has Been Paid For
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_PORTAL_LEVEL_KEY] isEqualToString: @"YES"]) // NEW CODE
    // Code to show bookmarks

 else 
    NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"PortalLevel" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    [viewWeb stringByEvaluatingJavaScriptFromString:jsString];    
NSLog(@"Shows portal levels?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_PORTAL_LEVEL_KEY]);

// Check To See If The PN IAP Has Been Paid For
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_PORTALS_KEY] isEqualToString: @"YES"]) // NEW CODE
    // Code to show bookmarks

 else 
    NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"PortalNames" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    [viewWeb stringByEvaluatingJavaScriptFromString:jsString];    
NSLog(@"Shows portal names?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_PORTALS_KEY]);

// Check To See If The Bookmarks IAP Has Been Paid For
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_BOOKMARKS_KEY] isEqualToString: @"YES"]) // NEW CODE
    // Code to show bookmarks

 else 
    NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"bookmarks" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    [viewWeb stringByEvaluatingJavaScriptFromString:jsString];    
NSLog(@"Shows bookmarks?: %@", [[NSUserDefaults standardUserDefaults] objectForKey:SHOW_BOOKMARKS_KEY]);

// Check To See If The Poke A Bowl Ad Has Been Paid For
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]);

【问题讨论】:

您的代码是否显示书签(未显示)添加子视图 - 类似于:[self.view addSubview: something]? 我正在尝试解锁一个 JavaScript 文件。 JavaScript 文件是书签工具。唯一的问题是,每次加载或调用视图控制器时,都会再次调用 JavaScript 文件。它不断在我的视图控制器上加载多个书签工具。 表示 URLforResource 书签的 nss 字符串是 JS 文件。 从 MasterViewController 切换回 ViewController 时,我如何调用已保存的 IAP,而不是使用 ViewWillAppear,因为 ViewWillAppear 会调用超出需要的代码。 或者更好的问题是,如何在购买后立即解锁 IAP? :) 【参考方案1】:

我认为你应该做的是让每个人最多调用一次。您应该使用 NSUserDefaults 来完成此操作。做这样的事情:

把它放在你的 AppDelegate.m 中:

//One new key for each IAP - put at the top of the AppDelegate.m and VC.m
#define IAP_FIRST_USED @"IAP 1 Used"
...
#define IAP_LAST_USED @"IAP X Used"

// In applicationDidFinishLaunchingWithOptions, should be the first method listed

[[NSUserDefaults standardUserDefaults] setObject: @"No" forKey: IAP_FIRST_USED];
...
[[NSUserDefaults standardUserDefaults] setObject: @"No" forKey: IAP_LAST_USED];
[[NSUserDefaults standardUserDefaults] synchronize];

然后在 VC.m 中将 viewWillAppear 修改为这样(这是第一个 IAP 的示例):

// Check To See If The PL Numbers IAP Has Been Paid For
if (![[[NSUserDefaults standardUserDefaults] objectForKey:SHOW_PORTAL_LEVEL_KEY] isEqualToString: @"YES"]) // NEW CODE


   // NEW CODE BEGINS HERE

   if ([[[NSUserDefaults standardUserDefaults] objectForKey:IAP_FIRST_USED] isEqualToString: @"No"])
   [[NSUserDefaults standardUserDefaults] setObject: @"Yes" forKey: IAP_FIRST_USED];
   [[NSUserDefaults standardUserDefaults] synchronize];  
   // Code to show bookmarks



   // End of code to show bookmarks
   // NEW CODE ENDS HERE

   
 else 
    NSString *jsString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"PortalLevel" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil];
    [viewWeb stringByEvaluatingJavaScriptFromString:jsString];    

还记得在 VC.m 中包含定义语句

【讨论】:

您是否尝试过将哪些代码切换到我放入的新代码中?看起来它可能是调用 javascript 的 else 语句中的代码,而不是 //Code to show bookmarks 之后的部分 删除!在第一个 if 语句中 它们实际上可以是任何东西,只要它们与另一个定义语句不同。您可能应该为第一个做 SHOW_PORTAL_USED_KEY KEY 等于后面的 NSString。您实际上并不需要 define 语句,这只是一种很好的做法,因为它提高了可读性。 不要删除 !从那个 if 语句

以上是关于应用内购买后,viewWillAppear 会多次加载购买的商品的主要内容,如果未能解决你的问题,请参考以下文章

SKProductsResponse 没有回应应用内购买

应用内购买后无法在设备上运行应用程序

应用内购买后启用按钮

Google 应用内购买始终会获得退款

SKPaymentTransactionStatePurchased 多次调用错误

如何在应用内购买中恢复购买?