1

SKProductsRequest start でストア キット クラスがクラッシュする アプリ購入の概念に慣れていない 私のクラスは、iOS 5 SDK ではなく iOS 4.3 SDK で完全に動作します。コンソールでエラーが発生せず、SKProductsRequest の開始前にアプリケーションがクラッシュしました。この問題を修正する方法を教えてください。私のコードは次のとおりです。

#import "StorePurchase.h"

@implementation StorePurchase
@synthesize request = _request;

- (void)loadStore {

    if ([SKPaymentQueue canMakePayments]) {
        NSLog(@"Parental-controls are disabled");
        self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"com.mycompany.app"]];
        self.request.delegate = self;
        [self.request start];
    }
    else {
        NSLog(@"Parental-controls are enabled");
    }

}
static bool hasAddObserver=NO;

- (void)purchase {
    if (!hasAddObserver) {//flag to fix this bug
        /*=====================================*/
        [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
        hasAddObserver=YES;
    }
    SKMutablePayment *payment = [[SKMutablePayment alloc] init] ;
    payment.productIdentifier = @"com.mycompany.app";
    payment.quantity = 1;
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    SKProduct *validProduct = nil;
    int count = [response.products count];
    if (count > 0) 
    {
        validProduct = [response.products objectAtIndex:0];
        NSLog(@"Products found,Magic Box!");
        [[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:@"Product Found..!"];

    } else if (!validProduct) 
    {
        NSLog(@"No products available");
        [[NSNotificationCenter defaultCenter] postNotificationName:kProductsLoadedNotification object:@"Product Not Found..!"];

    } 
}

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

    NSLog(@"Toggling flag for: %@", productIdentifier);
    [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:productIdentifier];
    [[NSUserDefaults standardUserDefaults] synchronize];
    //[_purchasedProducts addObject:productIdentifier];

    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchasedNotification object:productIdentifier];

}

- (void)completeTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"completeTransaction...");

    //[self recordTransaction: transaction];
    [self provideContent: transaction.payment.productIdentifier];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

- (void)restoreTransaction:(SKPaymentTransaction *)transaction {

    NSLog(@"restoreTransaction...");

    //[self recordTransaction: transaction];
    [self provideContent: transaction.originalTransaction.payment.productIdentifier];
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

}

- (void)failedTransaction:(SKPaymentTransaction *)transaction {

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

    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseFailedNotification object:transaction];
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
    NSLog(@"<><Canceled!><>");
    [[NSNotificationCenter defaultCenter] postNotificationName:kProductPurchaseCanceledNotification object:error];


}

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {


    for (SKPaymentTransaction *transaction in transactions) {

        switch (transaction.transactionState) {

            case SKPaymentTransactionStatePurchasing:
                // [self completeTransaction:transaction];
                break;

            case SKPaymentTransactionStatePurchased:
                NSLog(@"Purchased");
                [self completeTransaction:transaction];
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

                break;

            case SKPaymentTransactionStateRestored:
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                NSLog(@"Restored");
                [self restoreTransaction:transaction];

                break;

            case SKPaymentTransactionStateFailed:
                if (transaction.error.code != SKErrorPaymentCancelled) {
                    NSLog(@"An error encounterd");
                }
                else {
                    NSLog(@"Cancelled!");
                }
                //[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

                [self failedTransaction:transaction];

                break;

        }

    }


}

loadStoreエラーが発生した後にメソッドを呼び出しています

アプリがクラッシュする前に、SKProductsRequest が - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response メソッドを呼び出さない!

私のコードのどこが間違っているのかを修正する方法! 前もって感謝します!

4

2 に答える 2

1

このコードを使用してアプリケーションで購入しないためのコードを実行しましたが、問題は発生しません

- (void)loadStore
{
// restarts any purchases if they were interrupted last time the app was open
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

// get the product description (defined in early sections)
[self requestProUpgradeProductData];
}

- (void)requestProUpgradeProductData
{
NSSet *productIdentifiers = [NSSet setWithObject:kInAppPurchaseProUpgradeProductId];
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate = self;
[productsRequest start];

// we will release the request object in the delegate callback
}

この後、このメソッドを呼び出します

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray *products = response.products;
proUpgradeProduct = [products count] == 1 ? [[products objectAtIndex:0] retain] : nil;
if (proUpgradeProduct)
{
    NSLog(@"Product title: %@" , proUpgradeProduct.localizedTitle);
    NSLog(@"Product description: %@" , proUpgradeProduct.localizedDescription);
    NSLog(@"Product price: %@" , proUpgradeProduct.price);
    NSLog(@"Product id: %@" , proUpgradeProduct.productIdentifier);
    if ([self canMakePurchases]) {
        if ([self respondsToSelector:@selector(purchaseProUpgrade)]) {
            [self purchaseProUpgrade];
        }
    }
    else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[self languageSelectedStringForKey:@"Error"] message:@"Cannot connect to Store.\n Please Enable the Buying in settings" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alert show];
        [alert release];
    }
}

for (NSString *invalidProductId in response.invalidProductIdentifiers)
{
    [SVProgressHUD dismiss];
    [cancelButton setEnabled:YES];
    [buyNowButton setEnabled:YES];
    [restoreButton setEnabled:YES];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"Error occured" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
    [alert show];
    [alert release];
    NSLog(@"Invalid product id: %@" , invalidProductId);
}

// finally release the reqest we alloc/init’ed in requestProUpgradeProductData
[productsRequest release];
[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil];
}
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
[self recordTransaction:transaction];
[self provideContent:transaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
- (void)purchaseProUpgrade
{
[SVProgressHUD showInView:self.view status:[self languageSelectedStringForKey:@"Connecting Store"] networkIndicator:YES];
SKPayment *payment = [SKPayment paymentWithProductIdentifier:kInAppPurchaseProUpgradeProductId];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void)recordTransaction:(SKPaymentTransaction *)transaction
{
if ([transaction.payment.productIdentifier isEqualToString:kInAppPurchaseProUpgradeProductId])
{
    // save the transaction receipt to disk
    [[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"proUpgradeTransactionReceipt" ];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
}

最後にこの方法

- (void)finishTransaction:(SKPaymentTransaction *)transaction wasSuccessful:(BOOL)wasSuccessful
{
// remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:transaction, @"transaction" , nil];
if (wasSuccessful)
{
//Write your transaction complete statement required for your project
}
于 2012-06-28T11:45:44.167 に答える
0

次の 2 つのチュートリアルのいずれかに従います。

アプリ内購入のチュートリアル

または RMStore Verification に従ってください:こちら。

于 2014-09-01T12:15:33.233 に答える