我的应用程序只在App Store崩溃了!似乎与IAP收据验证有关

时间:2015-03-12 05:47:25

标签: ios swift in-app-purchase app-store

我发布了我的游戏更新,我认为它会修复IAP的收据验证。

这一切都适用于我的开发环境,但是如果你从应用程序商店下载应用程序,它会在启动时崩溃。我查看了设备上的崩溃报告,但我无法确切地说出我所犯的错误,因为如果我从计算机构建,这一切都很完美。非常令人沮丧的Apple会在发布时崩溃我的应用程序时接受我的更新!

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread:  3

Last Exception Backtrace:
0   CoreFoundation                  0x1845a259c __exceptionPreprocess + 132
1   libobjc.A.dylib                 0x194cf40e4 objc_exception_throw + 60
2   CoreFoundation                  0x184487904 -[__NSArrayI objectAtIndex:] + 224
3   Kill Sector                     0x1000b3714 0x10001c000 + 620308
4   CFNetwork                       0x183f8af34 __67+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]_block_invoke_2 + 188
5   Foundation                      0x18545b4a8 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 16
6   Foundation                      0x1853acc34 -[NSBlockOperation main] + 96
7   Foundation                      0x18539c5bc -[__NSOperationInternal _start:] + 636
8   Foundation                      0x18545e20c __NSOQSchedule_f + 228
9   libdispatch.dylib               0x19533936c _dispatch_client_callout + 16
10  libdispatch.dylib               0x1953434c0 _dispatch_queue_drain + 1216
11  libdispatch.dylib               0x19533c474 _dispatch_queue_invoke + 132
12  libdispatch.dylib               0x195345224 _dispatch_root_queue_drain + 664
13  libdispatch.dylib               0x19534675c _dispatch_worker_thread3 + 108
14  libsystem_pthread.dylib         0x1955152e4 _pthread_wqthread + 816
15  libsystem_pthread.dylib         0x195514fa8 start_wqthread + 4

这是我的支票收据代码:

   func checkReceipt(){

        var appStoreURL = "https://buy.itunes.apple.com/verifyReceipt"

        #if DEBUG
            appStoreURL = "https://sandbox.itunes.apple.com/verifyReceipt"
        #endif


        var appStoreStatusZero = false  // we connected to correct app store

        if let url = NSBundle.mainBundle().appStoreReceiptURL {
            if let receipt = NSData(contentsOfURL: url) {
                var error: NSError?

                let requestContents = ["receipt-data": receipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))]
                let requestData = NSJSONSerialization.dataWithJSONObject(requestContents, options: NSJSONWritingOptions(rawValue: 0), error: &error)
                if requestData == nil {
                    println("not receiving request Data")

                }

                let storeURL = NSURL(string: appStoreURL)
                let storeRequest = NSMutableURLRequest(URL: storeURL!)
                storeRequest.HTTPMethod = "POST"
                storeRequest.HTTPBody = requestData

                let queue = NSOperationQueue()

                NSURLConnection.sendAsynchronousRequest(storeRequest, queue: queue, completionHandler: {
                    response, data, error in
                    if error != nil {
                        println("connection error")
                        return
                    } else {
                        var error: NSError?
                        let jsonResponse = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0), error: &error) as NSDictionary?
                        if jsonResponse == nil {
                            println("json error")
                            return
                        } else {


                            var receiptInfo = jsonResponse?.objectForKey("receipt") as NSDictionary?
                            var inAppInfo = receiptInfo?.objectForKey("in_app") as NSArray?
                            var thisIAPInfo = inAppInfo?.objectAtIndex(0) as NSDictionary?
                            var removeAdsID = thisIAPInfo?.objectForKey("product_id") as String?

                            if removeAdsID == self.productID {
                                self.adsRemoved = true
                            }
                        }
                    }
                })


            }
        }

    }
  1. 我在这里做的事情有什么明显的错吗?我不能告诉我哪里出错了。

  2. 有没有办法测试它,好像它在应用程序商店?我尝试过临时部署,但我的应用程序运行正常。很难说我是否在没有测试的情况下修复了这个错误!

1 个答案:

答案 0 :(得分:0)

首先,您永远不应该直接从设备验证Apple服务器的收据。它不是很安全。您应该选择本地收据验证或服务器收据验证,以防万一与Apple验证服务器通信。

我认为您的代码崩溃了,因为您没有检查theese语句的结果。在某个地方你会变得零而且崩溃。

var receiptInfo = jsonResponse?.objectForKey("receipt") as NSDictionary?
var inAppInfo = receiptInfo?.objectForKey("in_app") as NSArray?
var thisIAPInfo = inAppInfo?.objectAtIndex(0) as NSDictionary?
var removeAdsID = thisIAPInfo?.objectForKey("product_id") as String?

尝试使用if let构造。在获取元素之前检查数组边界,它可能是空的。

类似的东西:

if let receiptInfo = jsonResponse.objectForKey("receipt") as NSDictionary? {
    if let inAppInfo = receiptInfo.objectForKey("in_app") as NSArray? {
        if (inAppInfo.count > 0) {
            if let thisIAPInfo = inAppInfo.objectAtIndex(0) as? NSDictionary {
                if let removeAdsID = thisIAPInfo.objectForKey("product_id") as String? {
                    // Do what you want here
                }
            }
        }
    }
}

要想知道如何让它变得更美丽,你可以阅读: http://blog.scottlogic.com/2014/12/08/swift-optional-pyramids-of-doom.html