진·iOS 내 구매 전체 절차

6899 단어

iOS의 내부 구매 절차는 다음과 같다.

  • 제품 ID를 통해 제품 정보 목록을 얻습니다
  • 감청 추가
  • 제품을 SKPayment(지불)로 포장하여 애플 서버에 보냅니다
  • 애플 서버가 구매에 성공하면 감청 방법을 리셋하여 애플 서버의 반환 정보에 따라 구매 성공 여부를 판단합니다..
  • 구매에 실패하거나 이미 이 상품을 구매한 적이 있으면 거래를 취소한다.구매에 성공하면 이때 자신의 서버에 구매 성공 메시지를 보내고 백그라운드를 통해 애플 서버에 검증을 보낸 후 거래를 취소할 수 있습니다

  • 일반적으로 이것은 iOS 내부 구매의 기본 과정으로 간단해 보이지만 실제 조작은 비교적 번거롭다. 왜냐하면 각종 의외의 상황을 고려해야 하기 때문이다.

    다음은 iOS 내 구매의 구체적인 과정을 설명합니다.


    1. 제품 정보 목록 얻기
    if ([SKPaymentQueue canMakePayments]) {
        NSSet *IDSet = [NSSet setWithArray:proID];
        SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:IDSet];
        productsRequest.delegate = self;
        [productsRequest start];
    } else {
        NSLog(@" ");
    }
    

    위 코드의 proID는 개발자 백그라운드에서 제품을 구입할 때 입력한 제품 ID를 포함하는 NSArray입니다.delegate란 SKProducts Request Delegate가 먼저 사용자의 요금 지불 금지 여부를 판단하고 요금 지불 금지가 없으면 애플 서버에서 제품 정보를 요청하고자 하는 것을 말한다.요청한 정보는 SKProductsRequestDelegate 메서드에서 반환됩니다.
    - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
    {
        NSLog(@"%i", response.products.count);
        NSArray *myProducts = response.products;
        if (0 == myProducts.count) {
            NSLog(@" ");
        } else {
            self.products = [myProducts sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
                SKProduct *pro1 = (SKProduct *)obj1;
                SKProduct *pro2 = (SKProduct *)obj2;
                return pro1.price.integerValue < pro2.price.integerValue ? NSOrderedAscending : NSOrderedDescending;
            }];;
            for (SKProduct *pro in myProducts) {
                NSLog(@"%@", [pro localizedTitle]);
                NSLog(@"%@", [pro localizedDescription]);
                NSLog(@"%@", [pro price]);
                NSLog(@"%@", [pro.priceLocale objectForKey:NSLocaleCurrencySymbol]);
                NSLog(@"%@", [pro.priceLocale objectForKey:NSLocaleCurrencyCode]);
                NSLog(@"%@", [pro productIdentifier]);
            }
        }
    }
    

    제품 정보를 받은 후에 정렬 처리를 할 수 있습니다. 요청할 때 발송된 제품 ID는 NSSet에 설치되어 있기 때문에 되돌아오는 제품 정보도 난서입니다. 여기서 주의해야 합니다.
    2. 내부 구매 모니터링
    제품 정보를 얻은 후에는 감청을 설정해야 한다. 구매와 구매를 클릭하면 애플 서버가 감청 방법을 통해 앱을 통지하기 때문이다.
    - (void)startObserver {
        if (!self.isObserver) {
            [[SKPaymentQueue defaultQueue] addTransactionObserver:self];
            NSLog(@"  ------  ");
            self.isObserver = YES;
        }
    }
    
    - (void)stopObserver {
        if (self.isObserver) {
            [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
            NSLog(@"  ------  ");
            self.isObserver = NO;
        }
    }
    

    감청 방법은 감청을 제거하는 방법과 함께 보내집니다. isObserver는 이미 감청했는지 아닌지를 판단하는 BOOL 데이터입니다.내 제안은 AppDelegate에서 감청 방법과 감청 제거 방법을 모두 실행하는 것입니다.앱이 시작되면 (- (BOOL) application: (UIApplication *) application did Finish Launching With Options: (NS Dictionary *) launch Options) 감청이 시작되고, 앱이 꺼지면 (- (void) application Will Terminate: (UIApplication *) application) 감청이 제거됩니다.원인에 대해서는 뒤에서 언급할 것이다.

    3. 감청 방법 구현

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
    {
        NSLog(@" ?");
        SKPaymentTransaction *transaction = transactions.lastObject;
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchased: {
                NSLog(@" ,  ---- %@", transaction.payment.applicationUsername);
                NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
                NSString *receipt = [data base64EncodedStringWithOptions:0];
                [self buySuccessWithReceipt:receipt transaction:transaction];
            }
                break;
            case SKPaymentTransactionStateFailed: {
                NSLog(@" ");
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }
                break;
            case SKPaymentTransactionStateRestored: {
                NSLog(@" ");
                [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
            }
                break;
            case SKPaymentTransactionStatePurchasing: {
                NSLog(@" ");
            }
                break;
            default: {
                NSLog(@" ?");
            }
                break;
        }
    }
    

    finishTransaction: 로그아웃 방법입니다. 로그아웃하지 않으면 오류 보고와 애플 서버의 끊임없는 알림 감청 방법 등이 발생합니다.한마디로 거래를 취소해야 한다는 것을 명심해라.어떤 학우들은 의심할 수도 있다,transaction.payment.applicationUsername에 있는 이 applicationUsername 속성은 무엇입니까? 우선 서두르지 마십시오. 이 속성에 관해서는 우리가 뒤에서 언급할 것입니다. 지금 이 점을 기억하면 됩니다.
    NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]]; 
    NSString *receipt = [data base64EncodedStringWithOptions:0];
    [self buySuccessWithReceipt:receipt transaction:transaction];
    

    이 세 마디에 관해서receipt는 방금 거래한 명세서입니다. 만약에 백그라운드에서 2차 검증을 해야 한다면 이 데이터를 사용해야 합니다.마지막 문장은 구매에 성공한 후 자신의 서버에 보내는 요청이다.

    내부 구매 요청 보내기


    위의 코드를 완성하면 내구 요청 부분을 발송할 수 있습니다
    SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
    payment.applicationUsername = [AppManager sharedInstance].userId.stringValue;
    [[SKPaymentQueue defaultQueue] addPayment:payment];
    

    내부 구매 요청은 간단합니다. 바로 요청된 제품 정보인 SKProduct로 내부 구매 결제 SKPayment를 만들고 결제 대기열에 추가하는 것입니다.

    이상은 iOS에서 구입한 모든 핵심 코드입니다.다음에 이야기할 것은 내부 구매에서 나타날 수 있는 구덩이와 어떻게 이 구덩이를 뛰어넘는가이다.


    세심한 학우들은 내구 요청을 보내는 코드 부분에서 응용 프로그램 Username이라는 속성을 다시 한 번 보았고 사용자의 id를 부여한 것을 발견했을 것이다. 그러면 이것은 무엇에 쓰이는 것입니까?답은: 어떤 극단적인 상황에서는 내구 요청을 보낸 사용자와 내구가 성공한 후에 자신의 백그라운드에 통지한 사용자가 같은 사용자가 아닐 수도 있다는 상황이 나타날 수 있다(정말 이상한 사용자...하지만 어쩔 수 없다. 사용자는 하느님이다...)이런 경우payment에 appUsername을 연결하면 이번payment에 고정된 발기자가 생길 수 있다. 그러면 이번payment가 애플 백그라운드에서 결제에 성공한 후에 우리는 감청의 리셋을 통해 이 발기자의 유일한 표지부를 자신의 백스테이지에 업로드하여 이번 구매에서 적당한 주인을 찾을 수 있다.사용자가 구매 과정에서 계정을 전환하거나 탈퇴하더라도 이번 충전 검증에 성공할 수 있다.
    극단적인 상황을 언급했으니 더 나아가 극단적인 상황을 만드는 것이 낫다. 구매 요청이 발송된 후 애플 백그라운드에 구매가 성공할 때까지 프로그램이 붕괴된다면!혹은 프로그램이 사용자에게 닫혔습니다!어떡해?!이런 상황에서 우리 앱은 자연히 감청의 리셋을 할 수 없고 구매가 성공했다는 소식을 자신의 백그라운드에 보낼 수 없으며 사용자도 자신의 충전을 받을 수 없다.상황이 매우 나쁘지만!걱정하지 마라, 우리는 해결할 방법이 있다.위에서 언급한 거래를 취소하는 방법을 기억하십니까?맞아요.
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction]
    

    애플 백그라운드에서 구매에 성공했을 때 앱이 이 방법을 사용하지 않았다면 애플은 이번 거래가 철저히 성공했다고 생각하지 않을 것이다. 앱이 다시 시작되고 내장된 감청 방법이 설정되었을 때 감청 방법-(void)paymentQueue:(SKPaymentQueue*)queue updatedTransactions:(NSArray*)transactions가 호출되어 위의 방법을 호출하여 이번 거래를 취소할 때까지애플이야말로 이번 교역이 철저히 끝났다고 생각할 것이다.이 특성을 이용하여 우리는 구매를 완료한 후 취소하는 방법을 우리가 자신의 백그라운드에 거래를 성공적으로 보낸 후에 호출할 수 있다.여기까지 말씀드리자면 내부 구매에 관한 큰 구덩이는 제가 현재 만났던 것은 모두 해결되었습니다. 물론 당신이 실제로 조작을 한다면 여러 가지 작은 구덩이를 만날 수 있지만 괜찮습니다. 저는 당신이 스스로 해결할 수 있다고 믿습니다...그래서 말 안 할게요.구덩이에 오를 준비를 해라!소년!

    좋은 웹페이지 즐겨찾기