2015-02-01 2 views
0

기다리십시오. 인앱 구매를 설정 한 것은 이번이 처음이며 최대한 많은 정보를 제공하려고 노력합니다. 다른 사람의 코드로 인터넷을 정리하는 대신, 앱에서 비 갱신 구독을 추가하는 방법에 대해 무한 기술로 수업을 구매하는 것으로 끝 맺었습니다. 그들의 수업은 시대에 뒤떨어져 있으며, "따라 가기"프로젝트 파일이 다운로드되지 않았다는 것을 알게되었습니다. 그래서 많은 연구를했고 이것이 내가 생각 해낸 것입니다 :"앱내 구매를 테스트 할 때"lldb "오류가 발생했습니다.

내가 아이튠즈에서 응용 프로그램 내 구입을 만들어
  1. 는 인앱 식별자 내하는 .m 코딩의 ID를 일치합니다.

  2. 새로운 프로비저닝 프로필을 만들고 인앱 구매를 사용하고 icloud를 사용하여 구매 백엔드를 관리했습니다. 앱으로 돌아 왔을 때 icloud를 사용 설정하고 프로젝트 타겟에서 인앱 구매가 사용 설정되었는지 확인했습니다.

  3. 버튼을 추가하고 SKStoreProductViewController를 사용하는 하위 클래스를 만들었습니다. 해당보기 컨트롤러는 다음과 같습니다. in-app View Controller

  4. 나는 storekit 및 SK 대리자를 가져 왔습니다.

내 홈 뷰에서 Tabbar 버튼을 누르면 인앱보기 컨트롤러로 이동하면 충돌이 발생합니다. error

마지막으로 코딩 : 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 

이 내 처음이 노력을 양해 해 주시기 바랍니다. 어리석은 것처럼 보일지 모르지만 여전히 나를위한 학습 단계입니다. 고맙습니다!

+0

CUICatalog 란 무엇입니까? 그것이 오류 메시지의 소스입니다. – matt

+0

그 아이가 찾을 수없는 이미지는 어딘가에서 두통을 일으켰습니다. 저는 언젠가는 고칠 수 없었던 오류였습니다. 응용 프로그램은 디버거에서 표시되는 tho에도 잘 작동합니다. 인앱 런타임 오류에는 영향을주지 않습니다. –

+0

하지만 그것이 유일한 문제입니다. 그게 문제가 아니라면 어떤 문제가 있습니까? 스크린 샷에 다른 "런타임 오류"가 표시되지 않습니다. – matt

답변

2

이 이야기에는 런타임 오류가 없습니다. 예외 상황을 만들었습니다. 이제 당신은 그것에 멈추고 있습니다. 실행을 다시 시작하기 만하면됩니다. 문제가 발생하면 Exceptions 중단 점을 비활성화하십시오.

+0

당신은 정확 합니다만, 지금 그것을 실행하려고하면 'InAppViewController는 모달 뷰 컨트롤러에서 사용되어야합니다'라는 오류가 발생하고 잡히지 않은 NSException으로 종료됩니다 ... –

+0

신경 쓰지 마라. 알아 냈어! 고맙습니다! –

+0

"이제 실행하려고 할 때 오류가 발생합니다."맞지만, 지금 당신이 알고 있다고 확신 할 때, 그것이 핵심입니다. 예외가 _ 생한 것을 알아 내기 위해 중단 점을 지나야합니다! – matt

관련 문제