"lldb" 测试应用内购买时出错
"lldb" Error When Testing In-App Purchase
请耐心等待。这是我第一次设置应用内购买,我会尝试提供尽可能多的信息。我没有为别人的代码整理互联网,而是从无限技能中购买了 class,专门关于如何将非续订订阅应用内购买添加到我的应用程序。他们的class已经过时了,来看看,"follow along"工程文件没有下载。所以我做了很多研究,这就是我想出的:
我在 iTunes 中创建了应用内购买,应用内标识符与我的 .m 编码中的标识符匹配。
我创建了一个新的配置文件并启用了应用内购买和 icloud 来管理购买的后端。当我返回应用程序时,我启用了 icloud 并确保在项目目标中打开了应用程序内购买。
我创建了一个视图控制器,添加了按钮,对于子class我使用了 SKStoreProductViewController。该视图控制器看起来像这样:
我导入了 storekit 和 SK 代表。
当我从主视图点击 tabbar 按钮将我带到应用程序内视图控制器时,它崩溃了。
最后是编码:
InAppViewController.h:
#import <StoreKit/StoreKit.h>
@interface InAppViewController : SKStoreProductViewController
@end
InAppViewController.m:
//
// InAppViewController.m
// Contractor Rich
//
// Created by Joshua Hart on 2/1/15.
// Copyright (c) 2015 Code By Hart. All rights reserved.
//
#import "InAppViewController.h"
#import <StoreKit/StoreKit.h>
@interface InAppViewController ()<SKProductsRequestDelegate, SKPaymentTransactionObserver>
@property (weak, nonatomic) IBOutlet UIButton *btnBuyAccess;
@property (weak, nonatomic) IBOutlet UIButton *btnPremiumFeature;
@property (weak, nonatomic) IBOutlet UILabel *lblStatus;
@property (strong, nonatomic) SKProduct *product;
@property (strong, nonatomic) NSUbiquitousKeyValueStore *keyStore;
@property (strong, nonatomic) NSDate *expirationDate;
- (IBAction)btnBuyAccessTouched: (id)sender;
-(void)getProductInfo;
@end
@implementation InAppViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_btnBuyAccess.userInteractionEnabled = NO;
_keyStore = [[NSUbiquitousKeyValueStore alloc] init];
_expirationDate = [_keyStore objectForKey:@"expirationDate"];
NSDate *today = [NSDate date];
if (_expirationDate == nil)
_expirationDate = today;
if (_expirationDate > today) {
_btnPremiumFeature.userInteractionEnabled = YES;
}
else {
_btnBuyAccess.userInteractionEnabled = YES;
[self getProductInfo];
}
}
-(void) getProductInfo{
if ([SKPaymentQueue canMakePayments])
{
NSMutableArray *productIdentifierList = [[NSMutableArray alloc] init];
[productIdentifierList addObject:[NSString stringWithFormat:@"com.joshua.contractorrich.inapp"]];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithArray:productIdentifierList]];
request.delegate = self;
[request start];
}
}
-(void) productsRequest: (SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray *products = response.products;
if (products.count != 0)
{
_product = products[0];
_btnBuyAccess.userInteractionEnabled = YES;
_lblStatus.text = @"Ready for Purchase!";
}else{
_lblStatus.text = @"Product was not Found!";
}
products = response.invalidProductIdentifiers;
for (SKProduct *product in products)
{
NSLog(@"Product not found: %@", product);
}
}
- (IBAction)btnBuyAccessTouched: (id)sender {
SKPayment *payment = [SKPayment paymentWithProduct:_product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
_btnPremiumFeature.userInteractionEnabled = YES;
_lblStatus.text = @"Purchase Completed!";
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed: NSLog(@"Transaction Failed!");
_lblStatus.text = @"Purchase Failed!";
[[SKPaymentQueue defaultQueue]
finishTransaction:transaction];
default:
break;
}
}
}
-(void) setExpirationDate {
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setMonth:3];
NSDate *expirationDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:[NSDate date] options:0];
[_keyStore setObject:expirationDate forKey:@"expirationDate"];
[_keyStore synchronize];
}
-(void) initializeStore {
[_keyStore setObject:nil forKey:@"expirationDate"];
[_keyStore synchronize];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
请理解这是我第一次尝试这个。看起来很愚蠢的东西对我来说仍然是学习阶段。谢谢!
这个故事中没有运行时错误。所发生的只是您创建了一个异常断点。现在你停下来了。只需恢复 运行。如果这很麻烦,请禁用异常断点。
请耐心等待。这是我第一次设置应用内购买,我会尝试提供尽可能多的信息。我没有为别人的代码整理互联网,而是从无限技能中购买了 class,专门关于如何将非续订订阅应用内购买添加到我的应用程序。他们的class已经过时了,来看看,"follow along"工程文件没有下载。所以我做了很多研究,这就是我想出的:
我在 iTunes 中创建了应用内购买,应用内标识符与我的 .m 编码中的标识符匹配。
我创建了一个新的配置文件并启用了应用内购买和 icloud 来管理购买的后端。当我返回应用程序时,我启用了 icloud 并确保在项目目标中打开了应用程序内购买。
我创建了一个视图控制器,添加了按钮,对于子class我使用了 SKStoreProductViewController。该视图控制器看起来像这样:
我导入了 storekit 和 SK 代表。
当我从主视图点击 tabbar 按钮将我带到应用程序内视图控制器时,它崩溃了。
最后是编码: InAppViewController.h:
#import <StoreKit/StoreKit.h>
@interface InAppViewController : SKStoreProductViewController
@end
InAppViewController.m:
//
// InAppViewController.m
// Contractor Rich
//
// Created by Joshua Hart on 2/1/15.
// Copyright (c) 2015 Code By Hart. All rights reserved.
//
#import "InAppViewController.h"
#import <StoreKit/StoreKit.h>
@interface InAppViewController ()<SKProductsRequestDelegate, SKPaymentTransactionObserver>
@property (weak, nonatomic) IBOutlet UIButton *btnBuyAccess;
@property (weak, nonatomic) IBOutlet UIButton *btnPremiumFeature;
@property (weak, nonatomic) IBOutlet UILabel *lblStatus;
@property (strong, nonatomic) SKProduct *product;
@property (strong, nonatomic) NSUbiquitousKeyValueStore *keyStore;
@property (strong, nonatomic) NSDate *expirationDate;
- (IBAction)btnBuyAccessTouched: (id)sender;
-(void)getProductInfo;
@end
@implementation InAppViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_btnBuyAccess.userInteractionEnabled = NO;
_keyStore = [[NSUbiquitousKeyValueStore alloc] init];
_expirationDate = [_keyStore objectForKey:@"expirationDate"];
NSDate *today = [NSDate date];
if (_expirationDate == nil)
_expirationDate = today;
if (_expirationDate > today) {
_btnPremiumFeature.userInteractionEnabled = YES;
}
else {
_btnBuyAccess.userInteractionEnabled = YES;
[self getProductInfo];
}
}
-(void) getProductInfo{
if ([SKPaymentQueue canMakePayments])
{
NSMutableArray *productIdentifierList = [[NSMutableArray alloc] init];
[productIdentifierList addObject:[NSString stringWithFormat:@"com.joshua.contractorrich.inapp"]];
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithArray:productIdentifierList]];
request.delegate = self;
[request start];
}
}
-(void) productsRequest: (SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray *products = response.products;
if (products.count != 0)
{
_product = products[0];
_btnBuyAccess.userInteractionEnabled = YES;
_lblStatus.text = @"Ready for Purchase!";
}else{
_lblStatus.text = @"Product was not Found!";
}
products = response.invalidProductIdentifiers;
for (SKProduct *product in products)
{
NSLog(@"Product not found: %@", product);
}
}
- (IBAction)btnBuyAccessTouched: (id)sender {
SKPayment *payment = [SKPayment paymentWithProduct:_product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
_btnPremiumFeature.userInteractionEnabled = YES;
_lblStatus.text = @"Purchase Completed!";
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed: NSLog(@"Transaction Failed!");
_lblStatus.text = @"Purchase Failed!";
[[SKPaymentQueue defaultQueue]
finishTransaction:transaction];
default:
break;
}
}
}
-(void) setExpirationDate {
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setMonth:3];
NSDate *expirationDate = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:[NSDate date] options:0];
[_keyStore setObject:expirationDate forKey:@"expirationDate"];
[_keyStore synchronize];
}
-(void) initializeStore {
[_keyStore setObject:nil forKey:@"expirationDate"];
[_keyStore synchronize];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
请理解这是我第一次尝试这个。看起来很愚蠢的东西对我来说仍然是学习阶段。谢谢!
这个故事中没有运行时错误。所发生的只是您创建了一个异常断点。现在你停下来了。只需恢复 运行。如果这很麻烦,请禁用异常断点。