我正在将应用程序从 iOS6 转换为 iOS7。在我使用不推荐使用的transactionReceipt
方法之前,现在我正在尝试推荐的方法来检索收据,然后在 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];
以上是代码中唯一的变化。以下是我验证它的方式,没有变化:
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 代码,除了在沙箱中尝试任何错误之外没有任何变化:
// 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\n(\n [status] => 21002\n [exception] => java.lang.IllegalArgumentException\n)\n
sandbox - Array\n(\n [status] => 21002\n [exception] => java.lang.IllegalArgumentException\n)\n
看起来我正在向 Apple 抛出各种异常!
同样,唯一的区别是收据是如何检索和编码的。有没有人遇到过这个问题并解决了?
谢谢阅读。
/年
根据要求,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 编码发送现有数据可能会侵犯一些内部限制。如果它超过了某个内部限制,则数据甚至不会发送,它会在设备本地失败,低于此限制,它会被发送。列是:数据格式,编码数据的大小,是否到达服务器:
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 字节。