在应用程序购买代码测试期间崩溃 [英] In App Purchase Code Crashing during testing

查看:96
本文介绍了在应用程序购买代码测试期间崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将InApp Purchasing添加到我的应用中,但在尝试使用测试用户帐户完成测试事务时,应用程序会在以下代码中崩溃,说明无法识别的选择器已发送到实例。

I have added InApp Purchasing to my app but when trying to complete a test transaction using a Test User account, the app keeps crashing at the following code saying that Unrecognised Selector sent to Instance.

我已经阅读了这篇文章,并认为这可能与我使用Auto Renewal Subscription产品的事实有关。

I have read up about this and feel it may be something to do with the fact I am using Auto Renewal Subscription product.

似乎是代码与崩溃相关的是这一行:

The code that seems to be related to the crash is this line:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"TransCancel" object: self];

我已经提供了我的InAppPurchase代码,任何人都可以请它帮助我!

I have provided my InAppPurchase code incase anyone can please please help me with this!!

InAppPurchaseSS.h

#import <Foundation/Foundation.h>
#import  "StoreKit/StoreKit.h"

#define kProductPurchasedNotification       @"ProductPurchased"
#define kProductPurchaseFailedNotification  @"ProductPurchaseFailed"
#define kProductPurchaseCancelledNotification  @"ProductPurchaseCancelled"

@interface InAppPurchaseSS : NSObject <SKProductsRequestDelegate,SKPaymentTransactionObserver,UIAlertViewDelegate>
{
    SKProductsRequest*   productsRequest;
    SKProduct *proUpgradeProduct;
    UIAlertView* waitingAlert;
    BOOL isTransactionOngoing;
}

@property (retain) SKProductsRequest*   productsRequest;
@property (retain) NSArray * products;
@property (retain) SKProductsRequest *request;
@property (assign) BOOL isTransactionOngoing;

+ (InAppPurchaseSS *) sharedHelper;

-(id)init;
- (void)buyProductIdentifier:(NSString *)productIdentifier;
- (BOOL)canMakePurchases;
-(void)restoreInAppPurchase;
- (void)collectProducts;
@end

InAppPurchaseSS.m

#import "InAppPurchaseSS.h"
#import "Reachability.h"

@implementation InAppPurchaseSS

@synthesize products;
@synthesize request;
@synthesize productsRequest;
@synthesize isTransactionOngoing;

static InAppPurchaseSS * _sharedHelper;

+ (InAppPurchaseSS *) sharedHelper {

    if (_sharedHelper != nil) {
        return _sharedHelper;
    }
    _sharedHelper = [[InAppPurchaseSS alloc] init];

    return _sharedHelper;

}

-(id)init {

    if( (self=[super init]))
    {
        isTransactionOngoing=NO;
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

    }

    return self;

}

- (void)collectProducts
{
    self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"my.inappads"]];
    self.request.delegate = self;
    [self.request start];
}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSLog(@"Received products results...");
    self.products = response.products;
    self.request = nil;    
    NSLog(@"Number of product:%i : %@",[response.products count],response.products);
    NSArray *product = response.products;
    proUpgradeProduct = [product count] == 1 ? [[product firstObject] retain] : nil;
    if (proUpgradeProduct)
    {
        NSLog(@"Product title: %@" , proUpgradeProduct.localizedTitle);
        NSLog(@"Product description: %@" , proUpgradeProduct.localizedDescription);
        NSLog(@"Product price: %@" , proUpgradeProduct.price);
        NSLog(@"Product id: %@" , proUpgradeProduct.productIdentifier);
    }

    for (NSString *invalidProductId in response.invalidProductIdentifiers)
    {
        NSLog(@"Invalid product id: %@" , invalidProductId);
    }
}



-(void)restoreInAppPurchase
{
    Reachability *reach = [Reachability reachabilityForInternetConnection];
    NetworkStatus netStatus = [reach currentReachabilityStatus];    
    if (netStatus == NotReachable) {        
        NSLog(@"No internet connection!");   
        [[[UIAlertView alloc] initWithTitle:@"No Internet"  message:@"Sorry, no internet connection found"   delegate:nil  cancelButtonTitle:@"Ok" otherButtonTitles: nil] show];
        return;
    }
    waitingAlert = [[UIAlertView alloc] initWithTitle:@"Restoring..."  message:@"Please Wait...\n\n" delegate:nil cancelButtonTitle:nil otherButtonTitles: nil];
    [waitingAlert show];

    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}




- (void)buyProductIdentifier:(NSString *)productIdentifier {

    if ([productIdentifier isEqual: @"my.inappads"]) {
        NSLog(@"No IAP Product ID specified");
        return;
    }

    Reachability *reach = [Reachability reachabilityForInternetConnection]; 
    NetworkStatus netStatus = [reach currentReachabilityStatus];    
    if (netStatus == NotReachable) {        
        NSLog(@"No internet connection!");   

        [[[UIAlertView alloc] initWithTitle:@"No Internet" message:@"Sorry, no internet connection found"  delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil] show];
        return;
    } 
     isTransactionOngoing=YES;

    waitingAlert = [[UIAlertView alloc] initWithTitle:@"Purchasing..." message:@"Please Wait...\n\n" delegate:nil cancelButtonTitle:nil otherButtonTitles: nil];
    [waitingAlert show];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) {
        SKMutablePayment *payment = [[SKMutablePayment alloc] init];
        payment.productIdentifier = productIdentifier;
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
    else {
        SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
        [[SKPaymentQueue defaultQueue] addPayment:payment];
    }
}



-(void)enableFeature
{
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"PurchaseSuccess"];
    [[NSUserDefaults standardUserDefaults] synchronize];

}


- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{

    [waitingAlert dismissWithClickedButtonIndex:0 animated:YES];
    NSLog(@"Restore completed transaction failed");

}

- (BOOL)canMakePurchases
{
    return [SKPaymentQueue canMakePayments];
}

//
- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
    isTransactionOngoing=NO;
    [waitingAlert dismissWithClickedButtonIndex:0 animated:YES];

    // remove the transaction from the payment queue.
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

    if (wasSuccessful)
    {
        [self enableFeature];

        [[[UIAlertView alloc] initWithTitle:@"Congratulations!!" message:@"You have succesfully Purchases." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil] show];

        [[NSNotificationCenter defaultCenter] postNotificationName:@"successbuy" object:self];
    }
    else
    {
      [[[UIAlertView alloc] initWithTitle:@"Error!" message:transaction.error.localizedDescription  delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show];

        [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"TransCancel" object: self];
    }
}


- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"succesfull transaction");
    [self finishTransaction:transaction wasSuccessful:YES];
}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction
{
    NSLog(@"transaction is restored");
    [self finishTransaction:transaction wasSuccessful:YES];
}


// called when a transaction has failed
- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
    isTransactionOngoing=NO;

    NSLog(@"failed transaction called");

    if (transaction.error.code != SKErrorPaymentCancelled)
    {
        NSLog(@"Transaction failed called");
        NSLog(@"Transaction error: %@", transaction.error.localizedDescription);

        [self finishTransaction:transaction wasSuccessful:NO];
    }
    else
    {
        [waitingAlert dismissWithClickedButtonIndex:0 animated:YES];
        NSLog(@"user cancel transaction");
        // this is fine, the user just cancelled, so don’t notify
        [[NSNotificationCenter defaultCenter] postNotificationName:@"TransCancel" object: self];
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
    }
}



#pragma mark -
#pragma mark SKPaymentTransactionObserver methods

// called when the transaction status is updated
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    NSLog(@"transaction status updated");
    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];
                break;
            default:
                break;
        }
    }
} 

- (void) dealloc
{
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
    [super dealloc];
}


@end

我是在用户进行购买的视图中使用@TransCancel,代码如下:

I am using the @TransCancel in the view that the user makes the purchase in, the code is like this:

//购买

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

[center addObserver: self  selector: @selector(TransactionCancel)  name:@"TransCancel" object: nil];
[center addObserver: self selector: @selector(TransactionComplete)  name:@"successbuy" object: nil];
NSLog(@"%d",[[NSUserDefaults standardUserDefaults] boolForKey:@"PurchaseSuccess"]);
if([[NSUserDefaults standardUserDefaults] boolForKey:@"PurchaseSuccess"])
    btn.hidden=YES;
else
    btn.hidden=NO;

错误记录

2014-01-06 00:25:40.694 MyApp[2764:60b] transaction status updated
2014-01-06 00:25:40.695 MyApp[2764:60b] failed transaction called
2014-01-06 00:25:40.696 MyApp[2764:60b] Transaction failed called
2014-01-06 00:25:40.696 MyApp[2764:60b] Transaction error: Cannot connect to iTunes Store
2014-01-06 00:25:40.730 MyApp[2764:60b] -[MyViewController TransactionCancel]: unrecognized selector sent to instance 0x1666a350

MyViewController

#import "UpgradeViewController.h"
#import "ECSlidingViewController.h"
#import "MenuViewController.h"

#import "InAppPurchaseSS.h"

#define ProductIdentifier @"<my.inappads>"

@interface UpgradeViewController ()
@property (retain, nonatomic) IBOutlet JSAnimatedImagesView *animatedImagesView;
@property (weak, nonatomic) IBOutlet UIButton *installFullAppButton;
@end

@implementation UpgradeViewController
@synthesize menuBtn, animatedImagesView = _animatedImagesView, scrolly, bannerView, labelPrice;




- (NSString *)publisherIdForAdSdkBannerView:(AdSdkBannerView *)banner {
    return @"e0616d4190bff65279ed5c20de1b5653";
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Price
    SKProduct *product = [[[InAppPurchaseSS sharedHelper] products] lastObject];
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [numberFormatter setLocale:product.priceLocale];
    NSString *formattedString = [numberFormatter stringFromNumber:product.price];
//    [self.installFullAppButton setTitle:formattedString forState:UIControlStateNormal];
    labelPrice.text = formattedString;

    // Purchase

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

    [center addObserver: self  selector: @selector(TransactionCancel)  name:@"TransactionCancel" object: nil];
    [center addObserver: self selector: @selector(TransactionComplete)  name:@"successbuy" object: nil];
    NSLog(@"%d",[[NSUserDefaults standardUserDefaults] boolForKey:@"PurchaseSuccess"]);
    if([[NSUserDefaults standardUserDefaults] boolForKey:@"PurchaseSuccess"])
        btn.hidden=YES;
    else
        btn.hidden=NO;



    // Do any additional setup after loading the view.




    //UIScrollView

    self.scrolly.contentSize = CGSizeMake(320, 600);

    //Image Transition

//    self.animatedImagesView.delegate = self;


    self.view.layer.shadowOpacity = 0.75f;
    self.view.layer.shadowRadius = 10.0f;
    self.view.layer.shadowColor = [UIColor blackColor].CGColor;


    if (![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]]) {
        self.slidingViewController.underLeftViewController  = [self.storyboard instantiateViewControllerWithIdentifier:@"Menu"];
    }


    [self.view addGestureRecognizer:self.slidingViewController.panGesture];

    self.menuBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    menuBtn.frame = CGRectMake(8, 30, 34, 24);
[menuBtn setBackgroundImage:[UIImage imageNamed:@"menuButton.png"] forState:UIControlStateNormal];
    [menuBtn addTarget:self action:@selector(revealMenu:) forControlEvents:UIControlEventTouchUpInside];


    [self.view addSubview:self.menuBtn];


    myWebView.opaque = NO;
    myWebView.backgroundColor = [UIColor clearColor];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)revealMenu:(id)sender
{
    [self.slidingViewController anchorTopViewTo:ECRight];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.screenName = @"Upgrade";
}


#pragma mark - Memory Management

- (void)viewDidUnload
{
//    [self setAnimatedImagesView:nil];
    [self setScrolly:nil];
//    [self setAnimatedImagesView:nil];
    [super viewDidUnload];
     [self setBannerView:nil];

    [super viewDidUnload];
}


- (void)dealloc
{
    bannerView.delegate = nil;

}



-(IBAction)but:(id)sender
{
    [[InAppPurchaseSS sharedHelper] buyProductIdentifier:ProductIdentifier];
}

-(IBAction)restore:(id)sender
{
    [[InAppPurchaseSS sharedHelper] restoreInAppPurchase];
}

- (IBAction)dismissView:(id)sender {

     [self dismissViewControllerAnimated:YES completion:NULL];
}

-(void)TransactionComplete
{
    btn.hidden=YES;
}
-(void)TransactionCancel
{
    btn.hidden=NO;
}


推荐答案

你有这一行: / p>

You have this line:

[center addObserver: self  selector: @selector(TransactionCancel)  name:@"TransCancel" object: nil];

这意味着 self 必须实现 TransactionCancel 方法。该错误表明该方法在 MyViewController 类中不存在。

Which means that self must implement the TransactionCancel method. The error indicates that the method doesn't exist on the MyViewController class.

解决方案是添加 TransactionCancel MyViewController 类的方法。

The solution is to add the TransactionCancel method to the MyViewController class.

这篇关于在应用程序购买代码测试期间崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆