如何在AS3 Air SDK中解码Base64编码的iOS App Store收据
解决Air SDK 29中缺失mx.utils.Base64Encoder的iOS收据验证方案
我之前也碰到过Air SDK升级后Flex相关类被移除的问题,别担心,我们可以自己实现一个轻量的Base64编码工具类,完美适配iOS App Store收据的远程验证需求。以下是具体的解决方案:
1. 自定义Base64编码工具类
Base64的编码逻辑是标准的,我们可以直接在AS3中实现,不需要依赖任何外部库。创建一个名为CustomBase64Encoder的类:
package { import flash.utils.ByteArray; public class CustomBase64Encoder { private static const BASE64_CHARS:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; public static function encodeByteArray(byteArray:ByteArray):String { var result:String = ""; var padding:String = ""; var bytesLeft:int = byteArray.length % 3; // 处理不足3字节的情况,添加padding if (bytesLeft > 0) { for (var i:int = bytesLeft; i < 3; i++) { padding += "="; byteArray.writeByte(0); } byteArray.position = 0; } while (byteArray.bytesAvailable > 0) { var b1:int = byteArray.readUnsignedByte(); var b2:int = byteArray.readUnsignedByte(); var b3:int = byteArray.readUnsignedByte(); // 拆分字节为6位的片段 var chunk1:int = b1 >> 2; var chunk2:int = ((b1 & 0x03) << 4) | (b2 >> 4); var chunk3:int = ((b2 & 0x0F) << 2) | (b3 >> 6); var chunk4:int = b3 & 0x3F; // 映射到Base64字符 result += BASE64_CHARS.charAt(chunk1); result += BASE64_CHARS.charAt(chunk2); result += BASE64_CHARS.charAt(chunk3); result += BASE64_CHARS.charAt(chunk4); } // 替换末尾的padding if (padding.length > 0) { result = result.substring(0, result.length - padding.length) + padding; } return result; } } }
2. 整合到iOS收据验证流程中
接下来,我们可以用这个自定义类来处理收据的编码和远程验证:
import flash.net.URLRequest; import flash.net.URLRequestMethod; import flash.net.URLLoader; import flash.utils.ByteArray; import flash.events.Event; import flash.events.IOErrorEvent; import flash.system.NativeApplication; // 获取iOS App Store收据 var receiptByteArray:ByteArray = NativeApplication.nativeApplication.applicationReceipt; if (receiptByteArray != null) { // 使用自定义工具类编码收据 var receiptBase64:String = CustomBase64Encoder.encodeByteArray(receiptByteArray); // 构建验证请求(注意沙盒和生产环境的URL不同) var requestURL:String = "https://sandbox.itunes.apple.com/verifyReceipt"; // 测试用沙盒,正式环境替换为https://buy.itunes.apple.com/verifyReceipt var request:URLRequest = new URLRequest(requestURL); request.method = URLRequestMethod.POST; request.contentType = "application/json"; // 构建请求体 var requestBody:String = '{"receipt-data": "' + receiptBase64 + '"}'; request.data = new ByteArray(); request.data.writeUTFBytes(requestBody); // 发送请求并处理响应 var loader:URLLoader = new URLLoader(); loader.addEventListener(Event.COMPLETE, onVerifyComplete); loader.addEventListener(IOErrorEvent.IO_ERROR, onVerifyError); loader.load(request); } else { trace("未获取到App Store收据"); } function onVerifyComplete(event:Event):void { var loader:URLLoader = URLLoader(event.target); var response:Object = JSON.parse(loader.data); trace("验证结果:", response); // 根据苹果返回的status字段判断验证是否成功(status=0为成功) if (response.status == 0) { // 验证通过,处理业务逻辑 trace("收据验证成功"); } else { // 验证失败,根据错误码排查问题 trace("收据验证失败,错误码:" + response.status); } } function onVerifyError(event:IOErrorEvent):void { trace("验证请求出错:", event.text); }
3. 注意事项
- 环境区分:测试阶段一定要用沙盒验证URL,正式发布后切换到生产环境URL,避免验证失败。
- 收据完整性:确保获取到的收据字节数组没有损坏,否则编码后会导致苹果验证不通过。
- 错误处理:苹果返回的
status字段有多种错误码,比如21002表示收据数据格式错误,21003表示收据无法验证,你可以对照官方文档对应处理。
内容的提问来源于stack exchange,提问作者hpeide
相关产品推荐
相关产品推荐

