2014-09-08 5 views
0

인앱 구매를 통해 내 앱에서 광고를 삭제하는 소모품이 없습니다. 가끔은 잘 돌아가고, 앱을 닫고 다시 열면 PRO 버전을 구입 한 경우 NSDefaults에서 탐지하는 코드가 정상적으로 작동합니다. 구입할 때 탭 바에서 "PRO로 업그레이드"버튼을 제거하려고하는데이 코드는 앱을 충돌시킵니다. 다음과 같은 오류와 함께, doRemoveAds 방법의ios 인앱 구매 관련 충돌

#import "RemoveAdsViewController.h" 
#import <StoreKit/StoreKit.h> 
#import "Flurry.h" 
#define kRemoveAdsProductIdentifier @"AiutoPro" 

@interface RemoveAdsViewController() 

@end 

@implementation RemoveAdsViewController 

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

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.navigationItem.title = NSLocalizedStringFromTable(@"aiutopro", @"i18n", @""); 
    self.buyLabel.text = NSLocalizedStringFromTable(@"buyText", @"i18n", @""); 
    self.recoverLabel.text = NSLocalizedStringFromTable(@"recoverText", @"i18n", @""); 
} 

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

#pragma Actions 
- (IBAction)buyNow:(id)sender { 
    NSLog(@"User requests to remove ads"); 

    if ([SKPaymentQueue canMakePayments]) { 
     NSLog(@"User can make payments"); 

     SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:kRemoveAdsProductIdentifier]]; 
     productsRequest.delegate = self; 
     [productsRequest start]; 
    } 
    else { 
     NSLog(@"User cannot make payments due to parental controls"); 
    } 
} 

- (IBAction)alreadyBought:(id)sender { 
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; 
} 

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { 
    SKProduct *validProduct = nil; 
    NSUInteger count = [response.products count]; 

    if ([response.invalidProductIdentifiers count] > 0) { 
     NSLog(@"Invalid Product Identifier"); 
    } 

    if (count > 0) { 
     validProduct = [response.products objectAtIndex:0]; 
     NSLog(@"Products Available!"); 
     [self purchase:validProduct]; 
    } 
    else { 
     NSLog(@"The product id was valid, but it has no products available"); 
    } 
} 

- (void)purchase:(SKProduct *)product { 
    SKPayment *payment = [SKPayment paymentWithProduct:product]; 
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    [[SKPaymentQueue defaultQueue] addPayment:payment]; 
} 

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue { 
    NSLog(@"received restored transactions: %lu", (unsigned long)queue.transactions.count); 
    for (SKPaymentTransaction *transaction in queue.transactions) { 
     if (SKPaymentTransactionStateRestored) { 
      NSLog(@"Transaction state -> Restored"); 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      [self doRemoveAds]; 
      break; 
     } 
    } 
} 

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { 
    for (SKPaymentTransaction *transaction in transactions) { 
     switch (transaction.transactionState) { 
      case SKPaymentTransactionStatePurchasing: 
       NSLog(@"Transaction state -> Purchasing"); 
       break; 

      case SKPaymentTransactionStatePurchased: 
       [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
       [self doRemoveAds]; 
       [Flurry logEvent:@"Purchase"]; 
       NSLog(@"Transaction state -> Purchased"); 
       break; 

      case SKPaymentTransactionStateRestored: 
       [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
       NSLog(@"Transaction state -> Restored"); 
       [self doRemoveAds]; 
       [Flurry logEvent:@"Restore"]; 
       break; 

      case SKPaymentTransactionStateFailed: 
       if (transaction.error.code != SKErrorPaymentCancelled) { 
        NSLog(@"Transaction state -> Cancelled"); 
       } 
       [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
       break; 
     } 
    } 
} 

- (void)doRemoveAds { 
    // Persist to UserDefaults 
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"areAdsRemoved"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

    // Remove upgrade tabbar button 
    NSMutableArray* newArray = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers]; 
    [newArray removeLastObject]; 

    [self.tabBarController setViewControllers:newArray animated:YES]; 
} 

@end 

마지막 3 행은 응용 프로그램을 충돌하는 것들이다 :

Thread 0 Crashed: 
0 libobjc.A.dylib     0x000000019489c1d0 objc_msgSend + 16 
1 CoreFoundation     0x00000001882815dc CFArrayApplyFunction + 64 
2 StoreKit      0x000000018b2b9474 -[SKPaymentQueue _notifyObserversAboutRemovals:] + 152 
3 StoreKit      0x000000018b2ba314 -[SKPaymentQueue _removePaymentsForMessage:] + 680 
4 StoreKit      0x000000018b2b8f28 __44-[SKPaymentQueue _handleMessage:connection:]_block_invoke + 156 
5 libdispatch.dylib    0x0000000194e64010 _dispatch_call_block_and_release + 20 
6 libdispatch.dylib    0x0000000194e63fd0 _dispatch_client_callout + 12 
7 libdispatch.dylib    0x0000000194e671d8 _dispatch_main_queue_callback_4CF + 332 
8 CoreFoundation     0x0000000188342c28 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8 
9 CoreFoundation     0x0000000188340f68 __CFRunLoopRun + 1448 
10 CoreFoundation     0x0000000188281c1c CFRunLoopRunSpecific + 448 
11 GraphicsServices    0x000000018df69c08 GSEventRunModal + 164 
12 UIKit       0x000000018b3b2fd8 UIApplicationMain + 1152 
13 Aiuto       0x000000010004f4d8 main (main.m:15) 
14 libdyld.dylib     0x0000000194e7fa9c start + 0 

아이디어 여기에 - 응용 프로그램 구매 처리하는 컨트롤러입니까?

답변

1

당신은의 dealloc 방법에

[[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 

을 넣어해야합니다. 이것은 SKIPaymentQueue에게 RemoveAdsViewController가 할당 해제 된 후에 어떤 트랜잭션도 수신하지 않음을 알립니다.

+0

환상적입니다. 감사합니다. –

+0

@Raymond 내 코드에 답변을 추가했지만 앱이 계속 충돌합니다. 제발 조언. – Atrash