2017-07-14 8 views
1

AppleのStoreKitで作業する方法を学ぶためのサンプルプロジェクトがありますので、自動更新サービスを自分のアプリとアプリ内サービスに一般的に適用する方法を学ぶことができます。StoreKit:Swift 1.2からSwift 3への変換でエラーが発生しました

サンプルプロジェクトがSwift 1.2に入っていて、それをSwift 3に変換するといくつかのエラーが発生しましたが、2つの警告と2つのエラーが発生しました。うまくいけば誰かが私を助けることができます。

また、コードをSwift 3に変換すると、コードはまだ動作しますか?それは古いですから?アプリの購入が大幅に変化しましたか?

警告とエラーストアキットのコードの

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

    var products = response.products 

    if (products.count != 0) { 
     for i in 0 ..< products.count 
     { 
      self.product = products[i] as? SKProduct 
      self.productsArray.append(product!) 
     } 
     self.tableView.reloadData() 
    } else { 
     print("No products found") 
    } 

    products = response.invalidProductIdentifiers 

    for product in products 
    { 
     print("Product not found: \(product)") 
    } 
} 

func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { 
    print("Transactions Restored") 

    var purchasedItemIDS = [] 
    for transaction:SKPaymentTransaction in queue.transactions { 

     if transaction.payment.productIdentifier == "com.brianjcoleman.testiap1" 
     { 
      print("Consumable Product Purchased") 
      // Unlock Feature 
     } 
     else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap2" 
     { 
      print("Non-Consumable Product Purchased") 
      // Unlock Feature 
     } 
     else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap3" 
     { 
      print("Auto-Renewable Subscription Product Purchased") 
      // Unlock Feature 
     } 
     else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap4" 
     { 
      print("Free Subscription Product Purchased") 
      // Unlock Feature 
     } 
     else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap5" 
     { 
      print("Non-Renewing Subscription Product Purchased") 
      // Unlock Feature 
     } 
    } 

    let alert = UIAlertView(title: "Thank You", message: "Your purchase(s) were restored.", delegate: nil, cancelButtonTitle: "OK") 
    alert.show() 
} 

second error

first error

休憩

var tableView = UITableView() 
let productIdentifiers = Set(["com.brianjcoleman.testiap1", "com.brianjcoleman.testiap2", "com.brianjcoleman.testiap3", "com.brianjcoleman.testiap4", "com.brianjcoleman.testiap5"]) 
var product: SKProduct? 
var productsArray = Array<SKProduct>() 

func requestProductData() 
{ 
    if SKPaymentQueue.canMakePayments() { 
     let request = SKProductsRequest(productIdentifiers: 
      self.productIdentifiers as Set<String>) 
     request.delegate = self 
     request.start() 
    } else { 
     let alert = UIAlertController(title: "In-App Purchases Not Enabled", message: "Please enable In App Purchase in Settings", preferredStyle: UIAlertControllerStyle.alert) 
     alert.addAction(UIAlertAction(title: "Settings", style: UIAlertActionStyle.default, handler: { alertAction in 
      alert.dismiss(animated: true, completion: nil) 

      let url: URL? = URL(string: UIApplicationOpenSettingsURLString) 
      if url != nil 
      { 
       UIApplication.shared.openURL(url!) 
      } 

     })) 
     alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { alertAction in 
      alert.dismiss(animated: true, completion: nil) 
     })) 
     self.present(alert, animated: true, completion: nil) 
    } 
} 

func buyProduct(_ sender: UIButton) { 
    let payment = SKPayment(product: productsArray[sender.tag]) 
    SKPaymentQueue.default().add(payment) 
} 

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 

    for transaction in transactions { 

     switch transaction.transactionState { 

     case SKPaymentTransactionState.purchased: 
      print("Transaction Approved") 
      print("Product Identifier: \(transaction.payment.productIdentifier)") 
      self.deliverProduct(transaction) 
      SKPaymentQueue.default().finishTransaction(transaction) 

     case SKPaymentTransactionState.failed: 
      print("Transaction Failed") 
      SKPaymentQueue.default().finishTransaction(transaction) 
     default: 
      break 
     } 
    } 
} 

func deliverProduct(_ transaction:SKPaymentTransaction) { 

    if transaction.payment.productIdentifier == "com.brianjcoleman.testiap1" 
    { 
     print("Consumable Product Purchased") 
     // Unlock Feature 
    } 
    else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap2" 
    { 
     print("Non-Consumable Product Purchased") 
     // Unlock Feature 
    } 
    else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap3" 
    { 
     print("Auto-Renewable Subscription Product Purchased") 
     // Unlock Feature 
    } 
    else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap4" 
    { 
     print("Free Subscription Product Purchased") 
     // Unlock Feature 
    } 
    else if transaction.payment.productIdentifier == "com.brianjcoleman.testiap5" 
    { 
     print("Non-Renewing Subscription Product Purchased") 
     // Unlock Feature 
    } 
} 

func restorePurchases(_ sender: UIButton) { 
    SKPaymentQueue.default().add(self) 
    SKPaymentQueue.default().restoreCompletedTransactions() 
} 

とコードテーブルビュー

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{ 
    let cellFrame = CGRect(x: 0, y: 0, width: self.tableView.frame.width, height: 52.0) 
    let retCell = UITableViewCell(frame: cellFrame) 

    if self.productsArray.count != 0 
    { 
     if indexPath.row == 5 
     { 
      let restoreButton = UIButton(frame: CGRect(x: 10.0, y: 10.0, width: UIScreen.main.bounds.width - 20.0, height: 44.0)) 
      restoreButton.titleLabel!.font = UIFont (name: "HelveticaNeue-Bold", size: 20) 
      restoreButton.addTarget(self, action: #selector(ViewController.restorePurchases(_:)), for: UIControlEvents.touchUpInside) 
      restoreButton.backgroundColor = UIColor.black 
      restoreButton.setTitle("Restore Purchases", for: UIControlState()) 
      retCell.addSubview(restoreButton) 
     } 
     else 
     { 
      let singleProduct = productsArray[indexPath.row] 

      let titleLabel = UILabel(frame: CGRect(x: 10.0, y: 0.0, width: UIScreen.main.bounds.width - 20.0, height: 25.0)) 
      titleLabel.textColor = UIColor.black 
      titleLabel.text = singleProduct.localizedTitle 
      titleLabel.font = UIFont (name: "HelveticaNeue", size: 20) 
      retCell.addSubview(titleLabel) 

      let descriptionLabel = UILabel(frame: CGRect(x: 10.0, y: 10.0, width: UIScreen.main.bounds.width - 70.0, height: 40.0)) 
      descriptionLabel.textColor = UIColor.black 
      descriptionLabel.text = singleProduct.localizedDescription 
      descriptionLabel.font = UIFont (name: "HelveticaNeue", size: 12) 
      retCell.addSubview(descriptionLabel) 

      let buyButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.width - 60.0, y: 5.0, width: 50.0, height: 20.0)) 
      buyButton.titleLabel!.font = UIFont (name: "HelveticaNeue", size: 12) 
      buyButton.tag = indexPath.row 
      buyButton.addTarget(self, action: #selector(ViewController.buyProduct(_:)), for: UIControlEvents.touchUpInside) 
      buyButton.backgroundColor = UIColor.black 
      let numberFormatter = NumberFormatter() 
      numberFormatter.numberStyle = .currency 
      numberFormatter.locale = Locale.current 
      buyButton.setTitle(numberFormatter.string(from: singleProduct.price), for: UIControlState()) 
      retCell.addSubview(buyButton) 
     } 
    } 

    return retCell 
} 

答えて

2

第1の機能の両方の問題は、before Swift 3というNSArraysがその汎用タイプ(つまり、 ではなく、[SKProduct])。単にas? SKProduct一部を取り払う

は警告を修正するだろうが、それだけで1回の呼び出しですべてのコンテンツを追加するためにきれいになります:

// Old 
for i in 0 ..< products.count 
{ 
    self.product = products[i] as? SKProduct 
    self.productsArray.append(product!) 
} 

// New: 
productsArray.append(contentsOf: products) 

ながら、両方response.productsresponse.invalidProductIdentifiersは次のようにインポートされたため、エラーがあります[Any]が最初に入力されました([SKProduct]および[String])。最も簡単な解決策は、単に直接、配列を使用することです:

// Old: 
products = response.invalidProductIdentifiers 

for product in products 

// New: 
for product in response.invalidProductIdentifiers 

それは印刷のみなので、私はおそらくちょうど直接配列を印刷したいです。

第2の関数のエラーは、変数がどの型の配列であるべきかをコンパイラが知る必要があるためです。名前から、私はそれが[String]であることを意図していたと思うだろうが、(同じ行の警告が示すように)使用されていないので、行を削除するだけでよい。


完全な更新/近代化/均一なスタイルのビューコントローラ:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, SKProductsRequestDelegate, SKPaymentTransactionObserver { 

    enum Product: String { 
     case test1 = "com.brianjcoleman.testiap1" 
     case test2 = "com.brianjcoleman.testiap2" 
     case test3 = "com.brianjcoleman.testiap3" 
     case test4 = "com.brianjcoleman.testiap4" 
     case test5 = "com.brianjcoleman.testiap5" 

     static var allValues: [Product] { 
      return [.test1, .test2, .test3, .test4, .test5] 
     } 
    } 

    let tableView = UITableView() 
    var productsArray = [SKProduct]() 

    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     tableView.frame = self.view.frame 

     tableView.separatorColor = .clear 

     tableView.dataSource = self 
     tableView.delegate = self 

     self.view.addSubview(tableView) 

     SKPaymentQueue.default().add(self) 
     self.requestProductData() 
    } 

    override func viewWillDisappear(_ animated: Bool) 
    { 
     super.viewWillDisappear(animated) 

     SKPaymentQueue.default().remove(self) 
    } 

    // In-App Purchase Methods 

    func requestProductData() 
    { 
     if SKPaymentQueue.canMakePayments() { 
      let productIdentifiers = Set(Product.allValues.map { $0.rawValue }) 
      let request = SKProductsRequest(productIdentifiers: productIdentifiers) 
      request.delegate = self 
      request.start() 
     } else { 
      let alert = UIAlertController(title: "In-App Purchases Not Enabled", 
              message: "Please enable In App Purchase in Settings", 
              preferredStyle: .alert) 
      alert.addAction(UIAlertAction(title: "Settings", style: .default, handler: { _ in 
       alert.dismiss(animated: true, completion: nil) 

       if let url = URL(string: UIApplicationOpenSettingsURLString) { 
        UIApplication.shared.openURL(url) 
       } 
      })) 
      alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { _ in 
       alert.dismiss(animated: true, completion: nil) 
      })) 
      self.present(alert, animated: true, completion: nil) 
     } 
    } 

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) 
    { 
     let products = response.products 

     if products.count != 0 { 
      productsArray.append(contentsOf: products) 
      self.tableView.reloadData() 
     } else { 
      print("No products found") 
     } 

     let invalidIdentifiers = response.invalidProductIdentifiers 
     if invalidIdentifiers.count > 0 { 
      print("Invalid product identifiers: \(invalidIdentifiers)") 
     } 
    } 

    func buyProduct(_ sender: UIButton) 
    { 
     let payment = SKPayment(product: productsArray[sender.tag]) 
     SKPaymentQueue.default().add(payment) 
    } 

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) 
    { 
     for transaction in transactions { 
      switch transaction.transactionState { 
      case .purchased, 
       .restored: 
       print("Transaction Approved") 
       print("Product Identifier: \(transaction.payment.productIdentifier)") 
       self.deliverProduct(transaction) 
       SKPaymentQueue.default().finishTransaction(transaction) 

      case .failed: 
       print("Transaction Failed") 
       SKPaymentQueue.default().finishTransaction(transaction) 

      case .deferred, 
       .purchasing: 
       break 
      } 
     } 
    } 

    func deliverProduct(_ transaction:SKPaymentTransaction) 
    { 
    } 

    func restorePurchases(_ sender: UIButton) 
    { 
     SKPaymentQueue.default().add(self) 
     SKPaymentQueue.default().restoreCompletedTransactions() 
    } 

    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) 
    { 
     print("Transactions Restored") 

     for transaction in queue.transactions { 
      processTransaction(transaction: transaction) 
     } 

     let alert = UIAlertController(title: "Thank You", 
             message: "Your purchase(s) were restored.", 
             preferredStyle: .alert) 
     present(alert, animated: true) 
    } 

    private func processTransaction(transaction: SKPaymentTransaction) 
    { 
     guard let product = Product(rawValue: transaction.payment.productIdentifier) else { 
      print("Unknown product identifier: \(transaction.payment.productIdentifier)") 
      return 
     } 
     switch product { 
     case .test1: 
      print("Consumable Product Purchased") 
      // Unlock Feature 

     case .test2: 
      print("Non-Consumable Product Purchased") 
      // Unlock Feature 

     case .test3: 
      print("Auto-Renewable Subscription Product Purchased") 
      // Unlock Feature 

     case .test4: 
      print("Free Subscription Product Purchased") 
      // Unlock Feature 

     case .test5: 
      print("Non-Renewing Subscription Product Purchased") 
      // Unlock Feature 
     } 
    } 

    // Screen Layout Methods 

    func numberOfSections(in tableView: UITableView) -> Int 
    { 
     return 1 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return self.productsArray.count + 1 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    { 
     let cellFrame = CGRect(x: 0, y: 0, width: self.tableView.frame.width, height: 52.0) 
     let retCell = UITableViewCell(frame: cellFrame) 

     if self.productsArray.count != 0 { 
      if indexPath.row == Product.allValues.count 
      { 
       let restoreButton = UIButton(frame: CGRect(x: 10.0, y: 10.0, width: UIScreen.main.bounds.width - 20.0, height: 44.0)) 
       restoreButton.titleLabel?.font = UIFont(name: "HelveticaNeue-Bold", size: 20) 
       restoreButton.addTarget(self, action: #selector(ViewController.restorePurchases(_:)), for: .touchUpInside) 
       restoreButton.backgroundColor = .black 
       restoreButton.setTitle("Restore Purchases", for: .normal) 
       retCell.addSubview(restoreButton) 
      } else { 
       let singleProduct = productsArray[indexPath.row] 

       let titleLabel = UILabel(frame: CGRect(x: 10.0, y: 0.0, width: UIScreen.main.bounds.width - 20.0, height: 25.0)) 
       titleLabel.textColor = .black 
       titleLabel.text = singleProduct.localizedTitle 
       titleLabel.font = UIFont(name: "HelveticaNeue", size: 20) 
       retCell.addSubview(titleLabel) 

       let descriptionLabel = UILabel(frame: CGRect(x: 10.0, y: 10.0, width: UIScreen.main.bounds.width - 70.0, height: 40.0)) 
       descriptionLabel.textColor = .black 
       descriptionLabel.text = singleProduct.localizedDescription 
       descriptionLabel.font = UIFont(name: "HelveticaNeue", size: 12) 
       retCell.addSubview(descriptionLabel) 

       let buyButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.width - 60.0, y: 5.0, width: 50.0, height: 20.0)) 
       buyButton.titleLabel?.font = UIFont(name: "HelveticaNeue", size: 12) 
       buyButton.tag = indexPath.row 
       buyButton.addTarget(self, action: #selector(ViewController.buyProduct(_:)), for: .touchUpInside) 
       buyButton.backgroundColor = .black 
       let numberFormatter = NumberFormatter() 
       numberFormatter.numberStyle = .currency 
       numberFormatter.locale = .current 
       buyButton.setTitle(numberFormatter.string(from: singleProduct.price), for: .normal) 
       retCell.addSubview(buyButton) 
      } 
     } 

     return retCell 
    } 

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    { 
     return 52.0 
    } 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     tableView.deselectRow(at: indexPath, animated: true) 
    } 

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
    { 
     if section == 0 { 
      return 64.0 
     } 

     return 32.0 
    } 

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
    { 
     let ret = UILabel(frame: CGRect(x: 10, y: 0, width: self.tableView.frame.width - 20, height: 32.0)) 
     ret.backgroundColor = .clear 
     ret.text = "In-App Purchases" 
     ret.textAlignment = .center 
     return ret 
    } 
} 
+0

ありがとうございました!残りのコードは最新のものですか? – BroSimple

+0

私は慎重に見ていませんでした。あなたが投稿したエラーに対処しました。私はあなたが[ 'UIAlertController'](https://developer.apple.com/documentation/uikit/uialertcontroller)に' UIAlertView'を更新する必要があります気付かなかった、といくつかの文体のものがあります。これはGithubやAppleか、誰かから得たzipファイルですか? – Kevin

+0

チュートリアルブログ – BroSimple

関連する問題