В приложении Покупка проблема с SKProduct () в Swift - PullRequest
0 голосов
/ 12 января 2020

Я пытаюсь внедрить покупки в приложении в приложение, которое я создаю, однако, когда я пытаюсь «получить» продукт, который у меня есть var products = [SKProducts](), однако это возвращает пустой массив, в результате чего приложение обрабатывает sh. Я проверил все налоговые соглашения и др. c. и когда я проверяю это в яблоках в проекте примера покупки приложения, IAP обнаруживаются.

Полный код проблемы возникает ниже.

class Model {

        var products = [SKProduct]()

        func getProduct(containing keyword: String) -> SKProduct? {
            // print("The array of SKProducts in Model getProduct is \(products)")
            // let test = products.filter { $0.productIdentifier.contains(keyword) }.first
            print("The products are: \(products)")
            print(products.filter { $0.productIdentifier.contains(keyword) }.first)
            return products.filter { $0.productIdentifier.contains(keyword) }.first
        }
    }

Операторы печати возвращают: «Продукты: []» и «nil»

Если это поможет, полный проект можно найти на GitHub здесь

Ответы [ 2 ]

0 голосов
/ 15 января 2020

Чтобы получить продукты, вы должны сделать SKProductsRequest и ждать ответа в SKProductsRequestDelegate методах.

Создать и запустить запрос:

let request = SKProductsRequest(productIdentifiers: ids)
request.delegate = self // self is delegate of SKProductsRequestDelegate, see below
request.start()

Где ids должен быть Set<String> из вас идентификаторами продукта.

Соответствует SKProductsRequestDelegate:

extension MyClass: SKProductsRequestDelegate {

    internal func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        print(response.products) // here is your [SKProduct] array
        print(response.invalidProductIdentifiers) // if you put wrong ids they would be here
    } 

    internal func request(_ request: SKRequest, didFailWithError error: Error) {
        print(error) // something wrong
    }
}
0 голосов
/ 12 января 2020

Ваша функция getProduct не делает ничего, кроме как напечатать пустой массив (products), отфильтровать этот пустой массив и извлечь первый элемент (который не существует).
Я предлагаю использовать помощник вот так (я откуда-то скопировал, не помню где):

import Foundation
import StoreKit

class IAPHelper: NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {

  typealias RequestProductsCompletionHandler = (_ success:Bool, _ products:[SKProduct]?) -> ()
  var completionHandler: RequestProductsCompletionHandler?
  var productsRequest: SKProductsRequest?
  var productIdentifiers: Set<String>
  var purchasedProductIdentifiers: Set<String>?

  // MARK: - Init  

  init(identifiers: Set<String>) {

    // Store product identifiers
    productIdentifiers = identifiers;

    // Check for previously purchased products
    purchasedProductIdentifiers = Set()
    for productIdentifier in productIdentifiers {
      let productPurchased = UserDefaults.standard.bool(forKey: productIdentifier)
      if productPurchased {
        purchasedProductIdentifiers?.insert(productIdentifier)
                print("Previously purchased: \(productIdentifier)");
      } else {
                print("Not purchased: \(productIdentifier)");
      }
    }
    super.init() // must be called after subclass init, but before "self" is used
    SKPaymentQueue.default().add(self)
  } // init

  func requestProductsWithCompletionHandler(_ completionHandler: @escaping RequestProductsCompletionHandler) {
    self.completionHandler = completionHandler

    productsRequest = SKProductsRequest.init(productIdentifiers: productIdentifiers)
    productsRequest!.delegate = self
    productsRequest!.start()
  }

  // MARK: - Products request delegate

  func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
    productsRequest = nil

    let skProducts = response.products
        for skProduct in skProducts {
            print("Found product: \(skProduct.productIdentifier), \(skProduct.localizedTitle), \(skProduct.price.floatValue)");
    }

    completionHandler!(true, skProducts)
    completionHandler = nil
  }

  func request(_ request: SKRequest, didFailWithError error: Error) {
        // NOTE: If this happens on the simulator, close the simulator window and re-run the app. This helps normally !!!
        print("Failed to load list of products. Error: \(error)")
    productsRequest = nil

    completionHandler!(false, nil)
    completionHandler = nil
  }

  // MARK: - Purchase

  func productPurchchased(_ productIdentifier:String) -> Bool {
    return purchasedProductIdentifiers!.contains(productIdentifier)
  }

  func buyProduct(_ product:SKProduct) {
        print("Buying \(product.productIdentifier)");

    let payment = SKPayment(product: product)
    SKPaymentQueue.default().add(payment)
  }

  func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
      switch transaction.transactionState {
      case SKPaymentTransactionState.purchased:
        self.completeTransaction(transaction)

      case SKPaymentTransactionState.failed:
        self.failedTransaction(transaction)

      case SKPaymentTransactionState.restored:
        self.restoreTransaction(transaction)

      default:
        print("Error: Unknown SKPaymentTransactionState")
      }
    }
  }

    func completeTransaction(_ transaction:SKPaymentTransaction) {
        print("completeTransaction...");

        self.provideContentForProductIdentifier(transaction.payment.productIdentifier)
        SKPaymentQueue.default().finishTransaction(transaction)
    }

    func restoreTransaction(_ transaction:SKPaymentTransaction) {
        print("restoreTransaction...");

        self.provideContentForProductIdentifier(transaction.original!.payment.productIdentifier)
        SKPaymentQueue.default().finishTransaction(transaction)
    }

    func failedTransaction(_ transaction:SKPaymentTransaction) {
        print("failedTransaction...");
        if let error = transaction.error as NSError?, error.code == SKError.paymentCancelled.rawValue {
                print("Transaction error:\(error.localizedDescription)");
        }

        SKPaymentQueue.default().finishTransaction(transaction)
    }

    func provideContentForProductIdentifier(_ productIdentifier:String) {

        purchasedProductIdentifiers?.insert(productIdentifier)
    UserDefaults.standard.set(true, forKey:productIdentifier)
    NotificationCenter.default.post(name: Notification.Name(rawValue: IAPHelperProductPurchasedNotification), object: productIdentifier, userInfo: nil)
  }

  func restoreCompletedTransactions() {
    SKPaymentQueue.default().restoreCompletedTransactions()
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...