Krazzie KAy
Krazzie KAy

Reputation: 810

In-App Purchase not working, showing No Products

I am learning about In-App Purchase provided by Apple. So I was following this tutorial : http://www.appcoda.com/in-app-purchase-tutorial/

I followed all the steps in this tutorial. Firstly, I created an app id,and then created an app in iTunes using that app id. Then I created two In-App purchase with product id as "com.outlines.feature1" and "com.outlines.feature2", both of them consumable. The rest of the code I simply followed the steps from the above tutorial

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)
        }
    }
}  
}

There are no errors, but the when I run it on iPhone, the console shows:

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

The console shows no products, however I have added two in-app features in my iTunes id. Here is the screenshot: In-App Purchases in iTunes

Can anyone tell me what I am doing wrong??

Upvotes: 10

Views: 15626

Answers (5)

rasulfahad
rasulfahad

Reputation: 624

The accepted answer is correct.

But I want to point out, in my scenario, the reason was that I had recently renewed my Apple Developer membership, and after renewing, I had not updated the contract.

After agreeing and resubmitting the contract, my product SKUs started showing as before.

Apparently, the paid-app contract must be signed by you and Apple. This can keep the SKProductsRequest from validating the identifiers.

Upvotes: 0

Alex Stone
Alex Stone

Reputation: 47348

You need to have the complete string com.product.productID in the productID field. The interface makes you believe you only need the last part : productID, but it did not work for me until I re-created new in app purchases with the entire explicit ID :(

Could be related to accepting the tax/banking on the previous day.

Upvotes: 1

Krazzie KAy
Krazzie KAy

Reputation: 810

I solved it finally. There were no errors in the code nor in the In-App purchase making process. The earlier solution mentioned to upload a snapshot was also not the issue.

The issue was the contract in the Agreements, Tax and Baking. It was not mentioned in the tutorial, but we need to complete a contract in the Agreements, Tax and Banking in the iTunes, which I had not done. After filling up the forms for the contract, it will be processed. Then the contract will be in effect and then the In-App Purchases created in the iTunes will be recognized.

Upvotes: 51

Done
Done

Reputation: 1088

For testing IAP on your device you dont need screenshot to submit. It is only needed when you are submitting app.

Make sure you can answer “Yes” to each of these questions:

  1. Have you enabled In-App Purchases for your App ID?
  2. Have you checked Cleared for Sale for your product?
  3. Does your project’s .plist Bundle ID match your App ID?
  4. Have you generated and installed a new provisioning profile for the new App ID?
  5. Have you configured your project to code sign using this new provisioning profile?
  6. Are you using the full product ID when when making an SKProductRequest?
  7. Have you waited several hours since adding your product to iTunes Connect?
  8. Have you tried deleting the app from your device and reinstalling?
  9. Is your device jailbroken? If so, you need to revert the jailbreak for IAP to work.

If you answered “No” to any one of these questions, there’s your problem.

You are using tableView, make sure also you have set right parameters to be loaded in cell. May your problem is in connection releated to tableview.

Upvotes: 18

Alex Kosyakov
Alex Kosyakov

Reputation: 2176

Your In-App Purchases aren't fully set, as you see, they have status "Waiting for screenshot":

Before you submit your In-App Purchase for review, you must upload a screenshot. This screenshot will be for review purposes only. It will not be displayed on the App Store. Screenshots must be at least 312x390 pixels and at least 72 DPI.

Usually I make a screenshot with alert of In-App purchase suggestion, cut it and upload it ti iTunesConnect.

After doing that, you current purchases should have status Ready for Submit:

enter image description here

P.S. It takes some time to take new changes an effect, so be patient:)

Upvotes: 0

Related Questions