2016-12-19 4 views
2

Derzeit arbeite ich daran, meine Anwendung an Apple zu senden, und ich habe ein seltsames Problem, bei dem meine Produktkennungen nicht sofort geladen werden. Manchmal, wenn Sie den Laden schnell genug laden, sind die Preise nicht geladen und Sie können keinen Kauf tätigen. Apple meldet, dass sie keinen Kauf über ihr ipv6-Netzwerk tätigen können, aber ich habe dieses Problem auch auf ipv4 gesehen.Verzögertes Laden von Produkten in Store Swift v3

Sehen Sie irgendwelche logischen Probleme, die dieses Problem und/oder IPv6-Non-Friendly-Code verursachen würden? Vielen Dank.

-Code folgt:

IAPManager:

import Foundation 
import StoreKit 
import RealmSwift 
import AVFoundation 

class IAPManager: NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver 
{ 
static let sharedInstance = IAPManager() 

private let realm = try! Realm() 

// SKRequest 
var request:SKProductsRequest! 
// Array of SKProducts 
var products:[SKProduct] = [] 

// Audio 
var audioPlayer: AVAudioPlayer! 

// Received Response From Store 
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { 

    // Check for Response 
    self.products = response.products 
} 

// Creates String Array of Product Identifiers 
func getStoreProductIdentifiers() -> [String] 
{ 
    var identifiers: [String] = [] 

    let hintsPackXS = "net.identitywithheld.HintsPackXS" 

    let hintsPackS = "net.identitywithheld.HintsPackS" 

    let hintsPackM = "net.identitywithheld.HintsPackM" 

    let hintsPackL = "net.identitywithheld.HintsPackL" 

    let hintsPackXL = "net.identitywithheld.HintsPackXL" 

    let removeAds = "net.identitywithheld.RemoveAds" 

    identifiers.append(hintsPackXS) 
    identifiers.append(hintsPackS) 
    identifiers.append(hintsPackM) 
    identifiers.append(hintsPackL) 
    identifiers.append(hintsPackXL) 
    identifiers.append(removeAds) 

    return identifiers 
} 

// Perform Request with Identifiers 
func performProductRequestForIdentifiers(identifiers:[String]){ 

    // Create Set Out of String Array and Type Cast as Set<String> 
    // Note that sets are not in any paritcular order. 
    let products = NSSet(array: identifiers) as! Set<String> 

    // Set request to call based on products identifier 
    self.request = SKProductsRequest(productIdentifiers: products) 

    // Set Delegate to self (this class) 
    self.request.delegate = self 

    // Start Request 
    self.request.start() 
} 

// Request Store Products 
// Gets Identifiers and Performs Requests (Ties Together) 
func requestStoreProducts(){ 
    self.performProductRequestForIdentifiers(identifiers: self.getStoreProductIdentifiers()) 
} 

// Checks to see if user can make purchases 
func setupPurchases() -> Bool 
{ 
    // Check to See if Can Make Payments 
    if SKPaymentQueue.canMakePayments(){ 

     // Sets Self As Observer 
     SKPaymentQueue.default().add(self) 

     return true 
    } 
    else 
    { 
     return false 
    } 
} 

// Requests Payment Request 
func createPaymentRequestForProduct(product:SKProduct) 
{ 
    let payment = SKMutablePayment(product: product) 
    payment.quantity = 1 

    // Starts Payment Process 
    SKPaymentQueue.default().add(payment) 
} 

// Payment Observer - Is Updated Whenever There's An Update 
//MARK - Transaction Observer 
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 

    // For Each Transaction in Transaction Array [SKPaymentTransaction] 
    for transaction in transactions { 
     switch transaction.transactionState{ 
     case .purchasing: 
      print("purchasing") 
      break 
     case .purchased: 
      print("purchased") 
      complete(transaction: transaction) 
      queue.finishTransaction(transaction) // Marks as Finished to Remove from Queue 
      break 
     case .deferred: 
      print("deferred") 
      break 
     case .failed: 
      print("failed") 
      fail(transaction: transaction) 
      queue.finishTransaction(transaction) // Marks as Finished to Remove from Queue 
      break 
     case .restored: 
      print("restored") 
      restore(transaction: transaction) 
      queue.finishTransaction(transaction) // Marks as Finished to Remove from Queue 
      break 
     } 
    } 
} 

// Complete Purchase 
private func complete(transaction: SKPaymentTransaction) { 
    print("complete...") 
    deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier) 

    // Check Whether Sounds Are On 
    let gameDataObj = realm.objects(GameData.self).filter("id == 0").first 
    let soundOn = gameDataObj!.sound 

    if(soundOn == true) 
    { 
     let hintSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "purchaseComplete", ofType: "caf")!) 
     try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback) 
     try? AVAudioSession.sharedInstance().setActive(true) 

     try? audioPlayer = AVAudioPlayer(contentsOf: hintSound as URL) 
     audioPlayer.volume = 0.5 
     audioPlayer!.prepareToPlay() 
     audioPlayer!.play() 
    } 

    // If On, Play Sound 
} 


// Restore Purchases 
private func restore(transaction: SKPaymentTransaction) { 
    guard let productIdentifier = transaction.original?.payment.productIdentifier else { return } 
    print("restore... \(productIdentifier)") 
    deliverPurchaseNotificationFor(identifier: productIdentifier) 
    SKPaymentQueue.default().finishTransaction(transaction) 
} 

private func fail(transaction: SKPaymentTransaction) { 
    print("fail...") 
    if let transactionError = transaction.error as? NSError { 
     if transactionError.code != SKError.paymentCancelled.rawValue { 
      print("Transaction Error: \(transaction.error?.localizedDescription)") 
     } 
    } 
    SKPaymentQueue.default().finishTransaction(transaction) 
} 

private func deliverPurchaseNotificationFor(identifier: String?) { 
    guard let identifier = identifier else { return } 

    let gameDataObj = realm.objects(GameData.self).filter("id == 0") 
    var hints = gameDataObj.first!.hints 
    var hintsPurchase = false 

    if(identifier == "net.identitywithheld.HintsPackXS") 
    { 
     print("Extra Small Pack") 
     hints = hints + 10 
     hintsPurchase = true 
    } 
    else if(identifier == "net.identitywithheld.HintsPackS") 
    { 
     print("Small Pack") 
     hints = hints + 45 
     hintsPurchase = true 
    } 
    else if(identifier == "net.identitywithheld.HintsPackM") 
    { 
     print("Medium Pack") 
     hints = hints + 125 
     hintsPurchase = true 
    } 
    else if(identifier == "net.identitywithheld.HintsPackL") 
    { 
     print("Large Pack") 
     hints = hints + 200 
     hintsPurchase = true 
    } 
    else if(identifier == "net.identitywithheld.HintsPackXL") 
    { 
     print("Extra Large Pack") 
     hints = hints + 500 
     hintsPurchase = true 
    } 
    else if(identifier == "net.identitywithheld.RemoveAds") 
    { 
     print("Remove Ads") 
     try! realm.write { 
      gameDataObj.first!.ads = false 
     } 
    } 

    // If Hint Purchase, Set Hints 
    if(hintsPurchase == true) 
    { 
     try! realm.write { 
      gameDataObj.first!.hints = hints 
     } 
    } 
} 

func getTextWidth(font: UIFont, text: String) -> CGFloat 
{ 
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 17, height: 17)) 
    label.text = text 
    label.font = font 
    label.sizeToFit() 

    return label.frame.width 
} 

func getTextHeight(font: UIFont, text: String, width: CGFloat) -> CGFloat 
{ 
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: 17)) 
    label.text = text 
    label.font = font 
    label.numberOfLines = 0 
    label.sizeToFit() 

    return label.frame.height 
} 
} 

App Delegierter

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
    openRealm() 
    // Override point for customization after application launch. 
    // Use Firebase library to configure APIs 
    FIRApp.configure() 
    GADMobileAds.configure(withApplicationID: adMobAppID) 

    // Store Call to Get Products if Can Make Purchases 

    if (IAPManager.sharedInstance.setupPurchases() == true) 
    { 
     IAPManager.sharedInstance.requestStoreProducts() 

     UserDefaults.standard.set(true, forKey: "IAPCapable") 
     UserDefaults.standard.synchronize() 
    } 
    else 
    { 
     UserDefaults.standard.set(false, forKey: "IAPCapable") 
     UserDefaults.standard.synchronize() 
    } 

    // Initialize the Chartboost library 
    Chartboost.start(withAppId: "identitywithheld", appSignature: "identitywithheld", delegate: nil) 

    return true 
} 

Antwort

0

Danach kräftig zu testen, wurde mir klar, dass ich nicht den Laden Last wurde zu verzögern und deshalb waren die Produkte nicht voll geladen. Dies ist kein ipv6-Problem.

Um dieses Problem zu beheben, habe ich einen Aktivitätsindikator hinzugefügt und einen Timer implementiert, um zu überprüfen, ob die Produkte vor der Anzeige des Geschäfts geladen wurden.

Verwandte Themen