应用内购买无效,显示无商品

时间:2016-05-24 10:24:38

标签: ios in-app-purchase

我正在学习Apple提供的应用程序内购买。所以我正在学习本教程: http://www.appcoda.com/in-app-purchase-tutorial/

我按照本教程中的所有步骤操作。首先,我创建了一个app id,然后使用该app id在iTunes中创建了一个应用程序。然后我创建了两个应用程序内购买,产品ID为“com.outlines.feature1”和“com.outlines.feature2”,两者都是可消耗的。 其余代码我只是按照上面教程中的步骤进行操作

import UIKit
import StoreKit

protocol IAPurchaceViewControllerDelegate {
    func didBuyColorsCollection(collectionIndex: Int)
}


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

@IBOutlet weak var tblProducts: UITableView!

var delegate: IAPurchaceViewControllerDelegate!

var selectedProductIndex: Int!
var transactionInProgress = false

let productIdentifiers = NSSet(array: ["com.outlines.feature1", "com.outlines.feature2"])
 var product: SKProduct?
var productsArray = Array<SKProduct>()

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    tblProducts.delegate = self
    tblProducts.dataSource = self

    //checks whether the In-App feature is activated or not
    requestProductInfo()

    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}

func requestProductInfo(){
    if SKPaymentQueue.canMakePayments() {
        let request = SKProductsRequest(productIdentifiers:
            productIdentifiers as! Set<String>)
        print("This is the request to be sent \(request)")
        request.delegate = self
        request.start()//calls productsRequest() function
    }
    else {
        print("Cannot perform In App Purchases.")
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

// MARK: IBAction method implementation

@IBAction func dismiss(sender: AnyObject) {
    dismissViewControllerAnimated(true, completion: nil)
}


// MARK: UITableView method implementation

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


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


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("idCellProduct", forIndexPath: indexPath) as UITableViewCell

    let product = productsArray[indexPath.row]
    cell.textLabel?.text = product.localizedTitle
    cell.detailTextLabel?.text = product.localizedDescription

    return cell
}


func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    selectedProductIndex = indexPath.row
    showActions()
    tableView.cellForRowAtIndexPath(indexPath)?.selected = false
}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 80.0
}




/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
    if response.products.count != 0 {
        for product in response.products {
            productsArray.append(product as SKProduct)
        }

        tblProducts.reloadData()
    }
    else {
        print("There are no products.")
    }

    if response.invalidProductIdentifiers.count != 0 {
        print("Invalid "+response.invalidProductIdentifiers.description)
    }
}

func showActions() {
    if transactionInProgress {
        return
    }

    let actionSheetController = UIAlertController(title: "IAPDemo", message: "What do you want to do?", preferredStyle: UIAlertControllerStyle.ActionSheet)

    let buyAction = UIAlertAction(title: "Buy", style: UIAlertActionStyle.Default) { (action) -> Void in
        let payment = SKPayment(product: self.productsArray[self.selectedProductIndex] as SKProduct)
        SKPaymentQueue.defaultQueue().addPayment(payment)
        self.transactionInProgress = true
    }

    let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (action) -> Void in

    }

    actionSheetController.addAction(buyAction)
    actionSheetController.addAction(cancelAction)

    presentViewController(actionSheetController, animated: true, completion: nil)
}

func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions as [SKPaymentTransaction] {
        switch transaction.transactionState {
        case SKPaymentTransactionState.Purchased:
            print("Transaction completed successfully.")
            SKPaymentQueue.defaultQueue().finishTransaction(transaction)
            transactionInProgress = false
            delegate.didBuyColorsCollection(selectedProductIndex)

        case SKPaymentTransactionState.Failed:
            print("Transaction Failed");
            SKPaymentQueue.defaultQueue().finishTransaction(transaction)
            transactionInProgress = false

        default:
            print(transaction.transactionState.rawValue)
        }
    }
}  
}

没有错误,但是当我在iPhone上运行它时,控制台显示:

This is the request to be sent <SKProductsRequest: 0x15d86210>
There are no products.
Invalid ["com.outlines.feature1", "com.outlines.feature2"]

控制台没有显示任何产品,但我在iTunes ID中添加了两个应用内功能。这是截图: In-App Purchases in iTunes

谁能告诉我我做错了什么?

4 个答案:

答案 0 :(得分:29)

我终于解决了。代码和应用程​​序内购买制作过程中没有错误。提到上传快照的早期解决方案也不是问题。

问题是协议,税收和烘焙中的合同。教程中没有提到它,但我们需要在iTunes中完成协议,税务和银行合同,这是我没有做过的。填写合同表格后,将予以处理。然后合同将生效,然后将识别在iTunes中创建的应用内购买。

答案 1 :(得分:11)

要在您的设备上测试IAP,您不需要提交屏幕截图。只有在您提交应用时才需要它。

确保您对以下每个问题都回答“是”:

  1. 您是否为应用ID启用了应用内购买?
  2. 您是否已检查过您的产品已清关待售?
  3. 您项目的.plist捆绑ID是否与您的应用ID相匹配?
  4. 您是否为新的App ID生成并安装了新的配置文件?
  5. 您是否已使用此新配置文件将项目配置为代码签名?
  6. 您在制作SKProductRequest时是否使用完整的产品ID?
  7. 自从将产品添加到iTunes Connect后,您有几个小时的时间?
  8. 您是否尝试从设备中删除该应用并重新安装?
  9. 你的设备越狱了吗?如果是这样,您需要恢复IAP的越狱才能正常工作。
  10. 如果你对这些问题中的任何一个回答“否”,那就是你的问题。

    您正在使用tableView,请确保您已设置要在单元格中加载的正确参数。愿你的问题与tableview有关。

答案 2 :(得分:0)

您的应用内购买未完全设置,如您所见,他们的状态为“等待屏幕截图”:

  

在您提交应用内购买以供审核之前,您必须上传一个   屏幕截图。此屏幕截图仅供审核之用。它会   不在App Store上显示。截图必须至少是   312x390像素,至少72 DPI。

通常我会根据应用内购买建议制作截图,剪切并上传至iTunesConnect。

完成此操作后,您当前购买的状态应为“准备提交”:

enter image description here

P.S。需要一些时间来进行新的更改,所以要耐心等待:)。

答案 3 :(得分:0)

您需要在productID字段中包含完整的字符串com.product.productID。该界面让您相信您只需要最后一部分:productID,但在我使用完整的显式ID重新创建新的应用内购买之前它对我不起作用:(

可能与前一天接受税务/银行业务有关。