this is my code:
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
but it comes up with this error:
Cannot invoke 'addTransactionObserver' with an argument list of type '(ViewController4)'
this is my code:
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
but it comes up with this error:
Cannot invoke 'addTransactionObserver' with an argument list of type '(ViewController4)'
According to SKPaymentQueue Class Reference, the parameter for addTransactionObserver method needs to conform to protocol SKPaymentTransactionObserver.
Check if your ViewController4 conforms to the protocol.
class ViewController4: UIViewController, SKPaymentTransactionObserver /* , OtherProtocols... */ {
//...
}
WHAT? Your answer makes no sense, of course i have this protocal
Please try to be polite. The people who try to help you here are mostly just other developers who are volunteering their time to help you with your problems.
Since the following compiles just fine in a playground in Xcode 7 beta 2 targeting iOS 9:
import StoreKit
class Test: NSObject, SKPaymentTransactionObserver
{
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {}
func attemptAddingSelfAsObserver()
{
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
}
let observer = Test()
observer.attemptAddingSelfAsObserver()and the following works just fine in a playground in Xcode 6.4 targeting iOS 8.4:
import StoreKit
class Test: NSObject, SKPaymentTransactionObserver
{
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {}
func attemptAddingSelfAsObserver()
{
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
}
let observer = Test()
observer.attemptAddingSelfAsObserver()it suggests that there is another issue in the rest of your code, like not conforming to the protocol correctly as OOPer mentioned as the most likely problem.
Note that the SKPaymentTransactionObserver protocol method requirements are different depending on whether you are using the iOS 8.4 or iOS 9 SDKs.
Then, without more info, readers of your question have no clue to find out what's happening.
Please try to describe your issue, provide as much info as you can. For example, you can show some parts of your class definition.
in the top line it say viewcontroller4 does not confirm to protocol: SKPaymentTransactionObserver
Can you help:
This is my code:
/
/
/
/
/
/
/
import UIKit
import iAd
import StoreKit
class ViewController4: UIViewController, ADBannerViewDelegate, SKPaymentTransactionObserver, SKProductsRequestDelegate {
class Test: NSObject, SKPaymentTransactionObserver
{
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {}
func attemptAddingSelfAsObserver()
{
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
}
@IBOutlet var s1: UIButton!
@IBOutlet var s2: UIButton!
@IBOutlet var s3: UIButton!
@IBOutlet var more: UIButton!
@IBOutlet var info: UIButton!
@IBOutlet var home: UIButton!
@IBOutlet var banner: ADBannerView!
@IBOutlet var restore: UIButton!
@IBOutlet var skipsl: UILabel!
var moreon = 1
func updatelbl() {
if infinite == "off" {
skipsl.text = "Skips = \(skips)"
}
else if infinite == "on" {
skipsl.text = "Skips = Infinite"
}
}
func morefunc() {
if moreon == 1 {
s1.setTitle("22 skips £4.99", forState: .Normal)
s2.setTitle("30 skips £6.99", forState: .Normal)
s3.setTitle("45 skips £9.99", forState: .Normal)
moreon = 2
s2.enabled = true
s3.enabled = true
}
else if moreon == 2 {
s1.setTitle("60 skips £11.99", forState: .Normal)
s2.setTitle("100 skips £17.99", forState: .Normal)
s3.setTitle("Remove Failsafe £14.99", forState: .Normal)
moreon = 3
s2.enabled = true
s3.enabled = true
}
else if moreon == 3 {
s1.setTitle("Infinite skips £29.99", forState: .Normal)
s2.setTitle("N/A", forState: .Normal)
s3.setTitle("N/A", forState: .Normal)
moreon = 0
}
else if moreon == 0 {
s1.setTitle("3 skips 79p", forState: .Normal)
s2.setTitle("6 skips £1.49", forState: .Normal)
s3.setTitle("13 skips £2.99", forState: .Normal)
moreon = 1
s2.enabled = true
s3.enabled = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
updatelbl()
s1.layer.cornerRadius = 10
s2.layer.cornerRadius = 10
s3.layer.cornerRadius = 10
info.layer.cornerRadius = 10
home.layer.cornerRadius = 10
restore.layer.cornerRadius = 10
more.layer.cornerRadius = 10
restore.enabled = false
s1.enabled = false
s2.enabled = false
s3.enabled = false
if(SKPaymentQueue.canMakePayments()) {
print("IAP is enabled, loading")
let productID: NSSet = NSSet(objects: "wnp3skips, wnp6skips, wnp13skips, wnp22skips, wnp30skips, wnp45skips, wnp60skips, wnp100skips, wnpinfinite, wnpfailsafe")
let request = SKProductsRequest(productIdentifiers: productID as! Set<String>)
request.delegate = self
request.start()
} else {
print("please enable IAPS")
}
}
@IBAction func s1(sender: AnyObject) {
if moreon == 0 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp3skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 1 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp22skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 2 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp60skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 3 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnpinfinite") {
p = product
buyProduct()
break;
}
}
}
updatelbl()
}
@IBAction func s2(sender: AnyObject) {
if moreon == 0 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp6skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 1 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp30skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 2 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp100skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 3 {
s2.enabled = false
}
updatelbl()
}
@IBAction func s3(sender: AnyObject) {
if moreon == 0 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp13skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 1 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnp45skips") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 2 {
for product in list {
let prodID = product.productIdentifier
if(prodID == "wnpfailsafe") {
p = product
buyProduct()
break;
}
}
}
else if moreon == 3 {
s3.enabled = false
}
updatelbl()
}
@IBAction func more(sender: AnyObject) {
morefunc()
}
func addskips3() {
skips = skips + 3
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips6() {
skips = skips + 6
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips13() {
skips = skips + 13
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips22() {
skips = skips + 22
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips30() {
skips = skips + 30
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips45() {
skips = skips + 45
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips60() {
skips = skips + 60
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskips100() {
skips = skips + 100
NSUserDefaults.standardUserDefaults().setObject(skips, forKey: "skips")
NSUserDefaults.standardUserDefaults().synchronize()
}
func addskipsinfinite() {
infinite = "on"
NSUserDefaults.standardUserDefaults().setObject(infinite, forKey: "infinite")
NSUserDefaults.standardUserDefaults().synchronize()
}
func failsafeoff() {
failsafeper = "on"
NSUserDefaults.standardUserDefaults().setObject(failsafeper, forKey: "failsafeper")
NSUserDefaults.standardUserDefaults().synchronize()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
/
}
var list = [SKProduct]()
var p = SKProduct()
func buyProduct() {
print("buy " + p.productIdentifier)
let pay = SKPayment(product: p)
let observer = Test()
observer.attemptAddingSelfAsObserver()
SKPaymentQueue.defaultQueue().addPayment(pay as SKPayment)
}
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
print("product request")
let myProduct = response.products
for product in myProduct {
print("product added")
print(product.productIdentifier)
print(product.localizedTitle)
print(product.localizedDescription)
print(product.price)
list.append(product as! SKProduct)
}
restore.enabled = true
s1.enabled = true
s2.enabled = true
s3.enabled = true
}
func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {
print("transactions restored")
for transaction in queue.transactions {
let t: SKPaymentTransaction = transaction as! SKPaymentTransaction
let prodID = t.payment.productIdentifier as String
switch prodID {
case "wnp3skips":
addskips3()
case "wnp6skips":
addskips6()
case "wnp13skips":
addskips13()
case "wnp22skips":
addskips22()
case "wnp30skips":
addskips30()
case "wnp45skips":
addskips45()
case "wnp60skips":
addskips60()
case "wnp100skips":
addskips100()
case "wnpinfinite":
addskipsinfinite()
case "wnpfailsafe":
failsafeoff()
default:
print("IAP not setup")
}
updatelbl()
}
}
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("add paymnet")
for transaction:AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
print(trans.error)
switch trans.transactionState {
case .Purchased:
print("buy, ok unlock iap here")
print(p.productIdentifier)
let prodID = p.productIdentifier as String
switch prodID {
case "wnp3skips":
addskips3()
case "wnp6skips":
addskips6()
case "wnp13skips":
addskips13()
case "wnp22skips":
addskips22()
case "wnp30skips":
addskips30()
case "wnp45skips":
addskips45()
case "wnp60skips":
addskips60()
case "wnp100skips":
addskips100()
case "wnpinfinite":
addskipsinfinite()
case "wnpfailsafe":
failsafeoff()
default:
print("IAP not setup")
}
queue.finishTransaction(trans)
break;
case .Failed:
print("buy error")
queue.finishTransaction(trans)
break;
default:
print("default")
break;
}
}
}
func paymentQueue(queue: SKPaymentQueue!, removedTransactions transactions: [AnyObject]!)
{
println("remove trans");
}
func finishTransaction(trans:SKPaymentTransaction)
{
print("finish trans")
SKPaymentQueue.defaultQueue().finishTransaction(trans)
}
@IBAction func RestorePurchases(sender: UIButton) {
let observer = Test()
observer.attemptAddingSelfAsObserver()
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
}
}
I assume you use iOS 8.4 with Xcode 6.4 . If not, please show what version of Xcode you are using.
And you define paymentQueue(updatedTransactions:) method in your ViewController4 class, which is needed to conform to SKPaymentTransactionObserver .
But, as LCS have noted already, parameter types of paymentQueue(updatedTransactions:) are defferent between iOS 8.4 SDK and iOS 9 SDK .
The method paymentQueue(updatedTransactions:) in your ViewController4 class:
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {is for iOS9 SDK with Xcode 7.
Change the line to fit for iOS8.4 SDK:
func paymentQueue(queue: SKPaymentQueue!, updatedTransactions transactions: [AnyObject]!) {