我发布了我的游戏更新,我认为它会修复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
}
}
}
})
}
}
}
我在这里做的事情有什么明显的错吗?我不能告诉我哪里出错了。
有没有办法测试它,好像它在应用程序商店?我尝试过临时部署,但我的应用程序运行正常。很难说我是否在没有测试的情况下修复了这个错误!
答案 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