samedi 31 janvier 2015

"lldb" Error When Testing In-App Purchase

Please be patient. This is my first time setting up an in-app purchase and I will try and provide as much information as I can. Instead of grooming the internet for someone else's code I ended up purchasing a class from infinite skills specifically on how to add a non-renewing subscription in-app purchase to my app. Their class was outdated, and come to find out, the "follow along" project files did not download. So I did a lot of research and this is what I came up with:




  1. I created an in-app purchase in itunes, the in-app identifier matches the identifier in my .m coding.




  2. I created a new provisioning profile and enabled in-app purchases and the icloud to manage the backend for the purchase. When I returned to the app i enabled icloud and made sure in-app purchases was turned on in the project target.




  3. I created a view controller, added buttons and for the subclass I used SKStoreProductViewController. That View Controller looks like this: in-app View Controller




  4. I imported the storekit and the SK delegates.




It crashes when I hit the tabbarbutton from my home view to bring me to the in-app view controller. error


Finally the coding: 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


Please understand this is my first time trying this. What may seem stupid is still the learning phase for me. Thank you!


Aucun commentaire:

Enregistrer un commentaire