iOS7 - 收据未在沙箱中验证 - 错误 21002 (java.lang.IllegalArgumentException)
我正在将应用程序从 iOS6 转换为 iOS7.在我使用已弃用的 transactionReceipt
方法之前,现在我正在尝试推荐的方法来检索收据,然后以 base 64 进行编码:
I'm converting an app from iOS6 to iOS7. Before I used the deprecated transactionReceipt
method so now I'm trying the recommended methods to retrieve the receipt, and then encode in base 64:
NSData *working = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
// Tried 64 or 76 chars/line and LF or CR line endings
NSString *receipt = [working base64EncodedStringWithOptions:kNilOptions];
以上是代码中唯一的变化.以下是我验证它的方式,没有变化:
The above is the only change in the code. Below is how I validate it, no changes:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue,
^{
NSMutableString *url = [NSMutableString string];
[url appendFormat:@"%@", WEB_SERVICE];
[url appendFormat:@"receipt=%@", receipt];
NSStringEncoding encoding;
NSError *error = [NSError new];
NSURL *URL = [NSURL URLWithString:url];
NSString *json = [NSString stringWithContentsOfURL:URL usedEncoding:&encoding error:&error];
// check json and error
// ... code omitted
}
在服务器端,这是我用来验证收据的 PHP 代码,除了尝试沙箱是否有任何错误之外没有任何变化:
On the server side, this is the PHP code I use to verify the receipt, no change other than trying the sandbox for any error:
// Encode as JSON
$json = json_encode(array('receipt-data' => $receipt));
// Try production first, if it doesn't work, then try the sandbox
$working = postJSONToURL('https://buy.itunes.apple.com/verifyReceipt', $json, false);
error_log('production - '.print_r($working, true));
if (@$working['status'] !== 0) // === 21007)
$working = postJSONToURL('https://sandbox.itunes.apple.com/verifyReceipt', $json, true);
error_log('sandbox - '.print_r($working, true));
这是错误日志输出:
production - Array
(
[status] => 21002
[exception] => java.lang.IllegalArgumentException
)
sandbox - Array
(
[status] => 21002
[exception] => java.lang.IllegalArgumentException
)
看起来我正在向 Apple 抛出各种异常!
It looks like I'm throwing all kinds of exceptions over at Apple!
同样,唯一的区别是收据的检索和编码方式.有没有人遇到过这个问题并修复过?
Again the only difference is how the receipt is retrieved and encoded. Has anyone encountered this problem and fixed it?
感谢阅读.
/年
根据要求,PostJSONToURL 的代码:
As requested, code for PostJSONToURL:
function postJSONToURL($url, $json, $disableSSLVerify = false)
{
$resource = curl_init($url);
curl_setopt($resource, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($resource, CURLOPT_POSTFIELDS, $json);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, true);
curl_setopt($resource, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: '.strlen($json)));
curl_setopt($resource, CURLOPT_HEADER, 0);
if ($disableSSLVerify)
{
curl_setopt($resource, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($resource, CURLOPT_SSL_VERIFYPEER, 0);
}
//curl_setopt($resource, CURLOPT_VERBOSE, true);
//curl_setopt($resource, CURLOPT_STDERR, $fp = fopen('/tmp/curl_output'.rand(1000, 9999).'.txt', 'w'));
$contents = json_decode(curl_exec($resource), true);
if (!$contents)
$contents = array();
curl_close($resource);
//fclose($fp);
return $contents;
}
经过一些实验后的新细节已经确定,将现有数据作为 base 64 编码发送可能会侵犯某些内部限制.如果超过某个内部限制,则数据甚至不会发送,它在设备上本地失败,低于此限制,则发送.列有:数据格式、编码数据大小、是否到达服务器:
New details after some experimenting, have determined that sending the existing data as base 64 encoded is likely encroaching on some internal limit. If it exceeds some internal limit, the data isn't even sent, it fails locally on the device, below that, it is sent. Columns are: data format, size of encoded data, whether it reached the server:
raw receipt data 5K N/A
base64 no options 6.66K yes
base64 76 chars/line 6.75K no
base64 64 chars/line 6.77K no
hex coded 10K no
注意发送成功和不发送的差别小于100字节.
Note that the difference between successfully sending and not sending is less than 100 bytes.
推荐答案
我遇到过这个问题并到处查看,包括在 Apple 的开发论坛上.苹果会给出几个股票回复,仅此而已.我认为这是苹果方面的一个错误.设备上的本地验证将起作用,因此请尝试转换为该验证.如果您绝对必须使用服务器端验证,那么现在似乎只有 transactionReceipt
可以工作.
I've had this problem and looked everywhere, including on Apple's development forums. Apple will give a couple of stock replies, and that's it. I think it's a bug on Apple's side. Validation locally on the device will work, so try to convert to that. If you absolutely must use server side validation, only transactionReceipt
seems to work right now.
该功能只是被弃用,而不是被禁止,所以我只会使用它并希望 Apple 批准该应用程序.事实上,这就是我刚刚做的,手指交叉,等待批准.
The function is just deprecated, not banned, so I would just use it and hope Apple approves of the app. In fact, it's what I just did, fingers crossed, waiting for approval.
您可以像这样将代码括起来以关闭 Xcode 中的警告:
You can turn off the warning in Xcode by bracketing your code like this:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// code using transactionReceipt
#pragma clang diagnostic pop
相关文章