iOS7 - 未在沙箱验证的收据 - 错误21002(java.lang.IllegalArgumentException) [英] iOS7 - receipts not validating at sandbox - error 21002 (java.lang.IllegalArgumentException)

查看:415
本文介绍了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\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上抛出了各种异常!

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?

感谢您的阅读。

/ YR

根据要求,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;
}

经过一些实验后的新细节,已确定将现有数据作为基数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的开发论坛上。 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

这篇关于iOS7 - 未在沙箱验证的收据 - 错误21002(java.lang.IllegalArgumentException)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆