2016-12-19 9 views
2

현재 Apple에 신청서를 제출하는 중입니다. 제품 식별자가 즉시로드되지 않는 이상한 문제가 발생합니다. 때로는 상점을 충분히 빨리로드하면 가격이로드되지 않고 구매할 수없는 경우가 있습니다. 애플은 ipv6 네트워크에서 구매할 수 없다고보고하고 있지만 ipv4에서도이 문제를 봤습니다.Store Swift v3에 지연된 제품로드

이 문제 및/또는 ipv6 비독점 코드의 원인이되는 논리 문제가 있습니까? 고맙습니다.

코드는 다음과 같습니다

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

앱 위임 적극적으로이 문제를 테스트 한 후, 내가 가게 부하를 지연시키고되지 않았 음을 깨달았다

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 
} 

답변

0

을 따라서 제품이 완전히로드되지 않았습니다. 이것은 ipv6 문제가 아닙니다.

이 문제를 해결하기 위해 작업 표시기를 추가하고 상점을 표시하기 전에 제품이로드되었는지 확인하고 타이머를 구현했습니다.