应用程序内购买偶尔崩溃

时间:2016-03-06 13:19:10

标签: ios swift in-app-purchase

我有一个应用程序已发布,并且应用程序内购买似乎在用户购买时偶尔使用,但我注意到Crashlytics(结构)应用程序不断崩溃,我无法弄清楚为什么因为我无法复制任何设备上的崩溃。这是我第一次整合应用内购买,所以请耐心等待。

我无法弄清楚什么是错的,特别是因为特定设备没有模式,有时候它有效,有时候它(显然)没有。我知道这可能有多种原因,但在正确的方向上轻推会很棒。 这是崩溃日志

string x = ...
string y = ...
char[] c = new char[x.Length];
for (int i = 0; i < x.Length; i++)
{
    c[i] = (char)(x[i] | y[i]);
}
string result = new string(c);

我遗失的任何东西?

修改

这是用户点按删除广告按钮时调用的内容

Thread : Crashed: com.apple.main-thread
0  app                            0xc2658 WelcomeViewController.purchaseAlert() -> () (WelcomeViewController.swift)
1  app                            0xc2658 WelcomeViewController.purchaseAlert() -> () (WelcomeViewController.swift)
2  app                            0xc1148 @objc WelcomeViewController.removeAdsTapped(UIButton) -> () (WelcomeViewController.swift:164)
3  UIKit                          0x29691771 -[UIApplication sendAction:to:from:forEvent:] + 80
4  UIKit                          0x29691701 -[UIControl sendAction:to:forEvent:] + 64
5  UIKit                          0x2967961f -[UIControl _sendActionsForEvents:withEvent:] + 446
6  UIKit                          0x29691051 -[UIControl touchesEnded:withEvent:] + 616
7  UIKit                          0x29690cbf -[UIWindow _sendTouchesForEvent:] + 646
8  UIKit                          0x296895d7 -[UIWindow sendEvent:] + 642
9  UIKit                          0x2965a119 -[UIApplication sendEvent:] + 204
10 UIKit                          0x29658757 _UIApplicationHandleEventQueue + 5134
11 CoreFoundation                 0x25485257 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
12 CoreFoundation                 0x25484e47 __CFRunLoopDoSources0 + 454
13 CoreFoundation                 0x254831af __CFRunLoopRun + 806
14 CoreFoundation                 0x253d5bb9 CFRunLoopRunSpecific + 516
15 CoreFoundation                 0x253d59ad CFRunLoopRunInMode + 108
16 GraphicsServices               0x2664faf9 GSEventRunModal + 160
17 UIKit                          0x296c1fb5 UIApplicationMain + 144
18 app                            0xbaba4 main (AppDelegate.swift:15)
19 libdispatch.dylib              0x25088873 (Missing)

购买产品

 func purchaseAlert() {


        let priceFormatter: NSNumberFormatter = {

            let pf = NSNumberFormatter()
            pf.formatterBehavior = .Behavior10_4
            pf.numberStyle = .CurrencyStyle
            return pf


        }()

        priceFormatter.locale = storeProducts.first!.priceLocale

        let productPrice = storeProducts.first!.price

      let price = priceFormatter.stringFromNumber(productPrice)!

        let alert = UIAlertController(title: "Remove Ads for \(price)", message: "This purchase will remove all ad's that show through out the app", preferredStyle: .Alert)

         alert.addAction(UIAlertAction(title: "Go Back", style: .Default, handler: nil))

        alert.addAction(UIAlertAction(title: "Remove Ad's", style: .Default, handler: { (_) -> Void in


            self.removeADs()

        }))




        self.presentViewController(alert, animated: true, completion: nil)

    }

这假定总会有产品,应该有。

更新 我已经更新了应用程序并等了一个多星期才得到一些数据,结果发现用户仍然无法购买。我现在安全地解开所有选项,所以没有零值,这样就不会导致崩溃,但我一直在跟踪删除广告按钮上的点击,我注意到我得到了类似的东西( 20个,10个用户)表示用户一次又一次地点击并导致无法购买。我还跟踪了是否有从商店退回的产品,并且有97%的时间存在。我仍然无法确定问题所在,并且按钮上的按钮绝对不是偶然的,因为删除广告按钮几乎是不合适的。我仍然会收到一些购买,但大多数都失败了。

2 个答案:

答案 0 :(得分:1)

如果没有任何可以复制的崩溃或xCode错误,仍然很难帮助您。但是,正如我所说,你至少可以改进你的代码,以确保不存在值为零的崩溃。

因此,您应该将购买提醒功能更改为此

 func purchaseAlert() {


    let priceFormatter: NSNumberFormatter = {

        let pf = NSNumberFormatter()
        pf.formatterBehavior = .Behavior10_4
        pf.numberStyle = .CurrencyStyle
        return pf


    }()

    /// safely unwrap storeProducts.first! to ensure its not nil
    /// if its nil than exit the method 
    guard let firstStoreProduct = storeProducts.first! else { return }

    // no more ! needed at the end which might caused a crash before
    priceFormatter.locale = firstStoreProduct.priceLocale

    // safely create the product price, if you can't exit the method
    guard let productPrice = firstStoreProduct.price else { return }

    // no more ! needed at the end which might also caused a crash before because product price cannot be nil anymore when getting to this line
    let price = priceFormatter.stringFromNumber(productPrice)


    let alert = UIAlertController(title: "Remove Ads for \(price)", message: "This purchase will remove all ad's that show through out the app", preferredStyle: .Alert)

     alert.addAction(UIAlertAction(title: "Go Back", style: .Default, handler: nil))

    alert.addAction(UIAlertAction(title: "Remove Ad's", style: .Default, handler: { (_) -> Void in


        self.removeADs()

    }))




    self.presentViewController(alert, animated: true, completion: nil)

}

正如你所看到的,我使用2个保护语句(就像let一样)来安全地解开东西。我更喜欢这种方式而不是使用“if let”金字塔。如果您不喜欢这种方式,或者由于某种原因,如果出现错误,您可以提前从方法返回,将其更改为“if let”。

您的移除广告方法应该如下所示

 func removeADs() {

    if let product = storeProducts.first! {

         Purchasables.store.purchaseProduct(product)
     }
}

这样你就摆脱了一些!你在哪里展开价值而不确保它们不是零。 我需要看看你的数组或字典和相关代码,以便进一步确定什么可能是零。

答案 1 :(得分:0)

我在一个月前遇到了同样的问题,在90%的情况下都没有崩溃。这是一个Apple的Bug,线程不停,我不知道为什么......但要解决这个问题我取消了请求(SKProductsRequest),它运行正常:

var request: SKProductsRequest! //global to cancel when disappear
//request products when you want (viewDidLoad for example)
request = SKProductsRequest(productIdentifiers: productID as! Set<String>)
            request.delegate = self
            request.start()

当消失的viewcontroller:

override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
        request.delegate = nil;
        request.cancel()
        SKPaymentQueue.defaultQueue().removeTransactionObserver(self)
    }