2013-11-21 12 views
5
mehrfach durch Fehler genannt

ich einen In-App-Kauf mache, aber ich habe einen Fehler, dass ich nicht finden kann, woher es kommt ...SKPaymentTransactionStatePurchased

Zunächst einmal habe ich einen Knopf und Wenn Sie darauf klicken, meine App Anfrage das Produkt, fängt die Antwort, Sie zahlen, und Sie erhalten das Produkt (alles funktioniert in Ordnung). Aber hier kommt mein Problem. Wenn ich auf den Knopf klicke, um wieder etwas zu kaufen, erhalte ich ZWEI Warnungen, dass ich etwas ZWEI Mal gekauft habe. Selbst wenn ich zum dritten Mal klicke, erhalte ich DREI Warnungen, dass ich etwas DREI Mal gekauft habe und vier und fünf, je nachdem, wie oft ich geklickt habe.

So scheint es, wie einige Variable die Anfragen zu speichern hält .. Hier ist mein Code:

Dieses die Produkt-ID validiert

- (void) validateProductIdentifiers 
{ 
NSString *monedas = @" ID FROM PRODUCT "; 
NSSet *product = [NSSet setWithObject:monedas]; 

productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:product]; 

productsRequest.delegate = self; 
[[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
[productsRequest start]; 
NSLog(@"STARTED REQUEST"); 
} 

Dies die Antwort von Apple Griffe

- (void)productsRequest:(SKProductsRequest *)request 
didReceiveResponse:(SKProductsResponse *)response 
{ 


productsRequest=nil; 

int found=0; 

SKProduct *paraPagar; 
skProducts = response.products; 

for (SKProduct * skProduct in skProducts) { 
      NSLog(@"Found product: %@ %@ %0.2f", 
      skProduct.productIdentifier, 
      skProduct.localizedTitle, 
      skProduct.price.floatValue); 
    found=1; 

    paraPagar = skProduct; 
} 
if (found==1){ 
    payment = [SKMutablePayment paymentWithProduct:paraPagar]; 
    payment.quantity = 1; 

    [[SKPaymentQueue defaultQueue]addPayment:payment]; 

}else{ 

//error (not relevant code) 

} 
} 

Zahlung akzeptieren und beenden ing Transaktion

- (void)paymentQueue:(SKPaymentQueue *)queue 
updatedTransactions:(NSArray *)transactions 
{ 



for (SKPaymentTransaction *transaction in transactions) { 
    switch (transaction.transactionState) { 

     case SKPaymentTransactionStatePurchased: 
      NSLog(@"BOUGHT"); 

      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
      [self completeTransaction:transaction]; 


      break; 
     case SKPaymentTransactionStateFailed: 
      NSLog(@"FAILED"); 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 

      [self failedTransaction]; 
      break; 
     case SKPaymentTransactionStateRestored: 
      NSLog(@"RESTORED"); 
      //[self restoreTransaction:transaction]; 
      [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
     case SKPaymentTransactionStatePurchasing: 
      NSLog(@"PURCHASING"); 
     default: 
      break; 
    } 

} 

} 

Vielen Dank für Ihre Zeit!

Antwort

8

Problem behoben.

Das Problem war, dass der Beobachter jedes Mal dupliziert wurde, wenn ich auf die Schaltfläche klickte oder wenn ich die Ansichten änderte.

Die Lösung fügt ein Flag hinzu, um zu sehen, ob der Beobachter bereits hinzugefügt wurde.

static bool hasAddObserver=NO; 

PAYMENT METHOD{ 
if (!hasAddObserver) { 
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    hasAddObserver=YES; 
} 
..... 
+3

Pro Apples Dokumentation, * "Ihre Anwendung sollte während der Anwendungsinitialisierung einen Beobachter zur Zahlungswarteschlange hinzufügen."* So funktioniert Ihre Lösung, aber noch besser ist es, einmal für Transaktionen zu beobachten, sobald Ihre App startet. – smileyborg

0

Erinnerst du

[[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 

, wenn der Kauf abgeschlossen ist anrufen?

+0

Es in hinzugefügt wird "Fall SKPaymentTransactionStatePurchased:" Muss ich es woanders hinzufügen? – mursang

-2
[addTransactionObserver] should run only once time. 
so you can use singleton pattern to solve this problem. 

+ (InAppPurchase *)sharedInstance 
{ 
    static dispatch_once_t once; 
    static InAppPurchase * sharedInstance; 
    dispatch_once(&once, ^{ 
     sharedInstance = [[self alloc] initWithProductIdentifiers:nil]; 
    }); 
    return sharedInstance; 
} 

- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers { 

    if ((self = [super init])) { 
     // Add self as transaction observer 
     [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 
    } 
    return self; 
} 
+0

Aber es kann dieses Problem nicht lösen. Sie sollten es besser bei didFinishLaunchingWithOptions wie [InAppPurchase sharedInstance]; Wenn Sie wollen kaufen Sie etwas, Sie können wie [[InAppPurchase sharedInstance] buyProduct: (SKProduct) myProduct]; – joe

3

hatte ich das gleiche Problem, würde ich auf einem IAP kaufen klicken und mehrere Antworten und Käufe von Apple erhalten würde.

addTransactionObserver() wurde jedes Mal aufgerufen, wenn ich ging und kam zurück zur Ansicht über viewDidLoad().

ich gebraucht un-beobachten sie in viewWillDisappear():

override func viewWillDisappear() { 
    SKPaymentQueue.defaultQueue().removeTransactionObserver(self) 
} 

ich could't einen Flag verwenden, um wie die Antwort von in mursang mehr Beobachter zu verhindern, weil ich für Transaktionen in anderen Ansichten angehören.

+0

gute Antwort auch :) – mursang

+0

Nun, mein Beobachter ist ein Nachkomme von UIViewController, wie ich es brauche, um einige UI-Aktionen in updatedTransactions durchzuführen: Methode Keine Möglichkeit, bis die ViewDidLoad-Methode aufgerufen und eine Instanz dieses UIViewController erstellt wurde. –

0

Swift 3: Nach @sponrad Antwort

override func viewWillDisappear(_ animated: Bool) { 
    SKPaymentQueue.default().remove(self) 
}