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:
Can anyone tell me what I am doing wrong??
Restart the device Tap Power off or Restart (depending on your device this text may be different). If needed, hold down the power button again to turn the device back on. Wait for the device to start back up. Re-open the app or game and check if the in-app purchase has been delivered.
If you get hit with a message on your Apple iPhone or iPad that says “Purchase – In-app purchases are not allowed” when trying to buy purchases from within apps, it may be related to a restriction setting on the device. From the Home screen, swipe over to the screen with the “Settings” icon, then select it.
Make sure that you're signed in with the same Apple ID that you used to make the purchase. Make sure that in-app purchases are allowed on your device. Restart your device: Restart your iPhone.
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.
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With