StoreKit 오류 처리

오류 상태는 5가지 UI 상태 중 하나입니다. 사용자의 경험과 만족을 위해 매우 중요합니다. 오류를 처리하지 않으면 사용자가 통제력을 상실하고 결과적으로 유지율이 감소하거나 앱이 삭제되는 주된 이유가 됩니다.

특히 StoreKit과 같은 라이브러리로 작업할 때 종속성을 사용하여 작업할 때 오류 처리가 더 중요합니다. 일반적으로 StoreKit은 무슨 일이든 일어날 수 있는 블랙박스입니다. 이 짧은 기사에서는 실패한 거래를 처리하는 방법과 피드백으로 사용자에게 적절한 오류 메시지를 제공하는 방법을 살펴봅니다.

NSError 개요



NSError가 어떻게 작동하는지 상기시켜 드리고 싶습니다. 아래에 필요합니다. iOS에서 발생하는 모든 오류에는 오류 도메인, 도메인별 오류 코드 및 응용 프로그램에 특정한 추가 정보가 포함됩니다. 따라서 우리에게 가장 중요한 분야는 다음과 같습니다.
  • 도메인
  • 코드
  • 사용자 정보

  • 다양한 오류



    결제, 매장 상품, 클라우드 서비스와 관련된 오류는 도메인 모델SKErrorDomain 및 오류 코드SKError.Code로 발생합니다. 전체 오류 목록에는 15개 이상의 옵션이 포함되어 있으며 이 설명서에서 찾을 수 있습니다. SKErrorDomain 오류 외에도 NSURLErrorDomain 모델에서 발생하는 네트워크 문제가 있을 수 있습니다. 모두 처리합시다.

    StoreKit 오류 처리



    오류 처리를 위해 SKRequestDelegate 대리자의 두 메서드를 구현해야 합니다.

    optional func request(_ request: SKRequest, didFailWithError error: Error)
    


    이것은 SKRequest에서 오류를 수신하는 선택적 방법입니다. 이러한 오류가 발생하면 (void) requestDidFinish: (SKRequest *) request가 호출되지 않는다는 점을 명심해야 합니다.

    두 번째 실패 지점은 트랜잭션 처리입니다. 여기에서 오류는 매우 다양하며 예를 들어 사용자가 작업을 취소했다는 사실과 자녀 보호 하의 권한 제한과 관련될 수 있습니다. 트랜잭션 작업 시 오류를 수신하려면 트랜잭션 상태SKPaymentTransactionStateFailed를 별도로 처리해야 합니다.

    - (void)paymentQueue:(nonnull SKPaymentQueue *)queue
     updatedTransactions:(nonnull NSArray<SKPaymentTransaction *> *)transactions {
      for (SKPaymentTransaction *transaction in transactions) {
          switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchasing:
              break;
            case SKPaymentTransactionStatePurchased:
              // implement handling purchased state
              // [self handlePurchasedTransaction:transaction];
              break;
            case SKPaymentTransactionStateFailed:
              [self handleFailedTransaction:transaction];
              break;
            case SKPaymentTransactionStateRestored:
              // implement handling restored state
              // [self handlePurchasedTransaction:transaction];
              break;
            default:
              break;
          }
      }
    }
    


    방법handleFailedTransaction:

    - (void)handleFailedTransaction:(SKPaymentTransaction *)transaction {
      NSError *error = transaction.error;
    
      if (error && [[error domain] isEqualToString:SKErrorDomain]) {    
          switch (error.code) {
            case SKErrorUnknown:
              // Error code indicating that an unknown or unexpected error occurred.
              break;
            case SKErrorClientInvalid:
              // Error code indicating that the client is not allowed to perform the attempted action.
              break;
            case SKErrorPaymentCancelled:
              // Error code indicating that the user canceled a payment request.
              break;
            case SKErrorStoreProductNotAvailable:
              // Error code indicating that the requested product is not available in the store.
              break;
            case SKErrorPaymentNotAllowed:
              // Error code indicating that the user is not allowed to authorize payments.
              break;
            case SKErrorPaymentInvalid:
              // Error code indicating that one of the payment parameters was not recognized by the App Store.
              break;
            // Belowe codes available on different iOS
            case 6:
              // SKErrorCloudServicePermissionDenied
              // Error code indicating that the user has not allowed access to Cloud service information.
              break;
            case 7:
              // SKErrorCloudServiceNetworkConnectionFailed
              // Error code indicating that the device could not connect to the network.
              break;
            case 8:
              // SKErrorCloudServiceRevoked
              // Error code indicating that the user has revoked permission to use this cloud service.
              break;
            case 9:
              // SKErrorPrivacyAcknowledgementRequired
              // Error code indicating that the user has not yet acknowledged Apple’s privacy policy for Apple Music.
              break;
            case 10:
              // SKErrorUnauthorizedRequestData
              // Error code indicating that the app is attempting to use a property for which it does not have the required entitlement.
              break;
            case 11:
              // SKErrorInvalidOfferIdentifier
              // The specified subscription offer identifier is not valid
            case 12:
              // SKErrorInvalidSignature
              // The cryptographic signature provided is not valid
              break;
            case 13:
              // SKErrorMissingOfferParams
              // One or more parameters from SKPaymentDiscount is missing
              break;
            case 14:
              // SKErrorInvalidOfferPrice
              // The price of the selected offer is not valid (e.g. lower than the current base subscription price)
              break;
          }
      } else if (error && [[error domain] isEqualToString:NSURLErrorDomain]) {
        switch (error.code) {
          case NSURLErrorNotConnectedToInternet:
            // A network resource was requested, but an internet connection has not been established and can’t be established automatically.
            break;
          default:
           // Handle other network errors here
          break;
        }
      }
    
    }
    


    그것에 대해 무엇을해야합니까?



    많은 유형의 오류가 있으므로 오류를 여러 그룹으로 나누는 것이 좋습니다.
  • 어떤 식으로든 영향을 받을 수 없는 외부(예: 네트워크 문제)
  • 잘못된 제품 ID와 같은 요청 오류
  • 작업 취소 또는 확인되지 않은 계정과 같은 사용자 측 오류

  • 외부 오류



    이러한 오류의 경우 오류 자체에 대한 경고와 구매를 다시 시작하기 위한 반복 버튼으로 충분합니다. 예를 들어 인터넷이 안되거나 앱스토어 접속 시 오류가 발생하는 경우입니다.

    요청 오류


    SKErrorStoreProductNotAvailable 또는 SKErrorInvalidOfferPrice와 같이 시스템 문제이므로 제품 변환에 가장 큰 피해를 줄 수 있는 오류 그룹입니다. 이 그룹의 오류는 서버에서 원격으로 오류를 포착하고 수정할 수 있는 기능과 함께 추가 로깅으로 처리되어야 합니다.

    사용자 측 오류
    이 오류 그룹은 사용자의 상태와 직접 관련이 있습니다(예: SKErrorPrivacyAcknowledgmentRequired ).

    응용 프로그램 내에서 올바른 오류 처리는 사용자 경험에서 매우 중요한 부분입니다. 우선, 오류를 구현하고 (확실하지는 않지만 둘 다 동시에 발생해야 하므로 "로딩 상태에서 오류 구현"이라고 말하겠습니까?) 로드 상태를 구현한 다음 기본(콘텐츠) 상태 구현을 시작하는 것이 좋습니다.

    좋은 웹페이지 즐겨찾기