我正在将一个应用程序从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的地方抛出了各种异常!
唯一的区别是如何检索和编码收据。有人遇到过这个问题并解决了吗?
谢谢阅读。
/YR
按要求,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;
}
在一些实验后,新的细节已经确定,将现有数据作为base64编码发送可能会侵犯一些内部限制。如果超过了某个内部限制,数据甚至不会被发送,在设备本地失败;如果在该限制以下,则会被发送。列分别是:数据格式、编码数据大小、是否到达服务器:
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字节。