注意:我正在为Mac开发,而不是iOS!
- (void)recordTransaction:(SKPaymentTransaction *)transaction
{
if ([transaction.payment.productIdentifier isEqualToString:kInAppProIdentifier])
{
[[NSUserDefaults standardUserDefaults] setValue:transaction.transactionReceipt forKey:@"proUpgradeTransactionReceipt" ];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
我从编译器中得到此错误:
error: property 'transactionReceipt' not found on object of type 'SKPaymentTransaction *'; did you mean 'transactionDate'? [3]
另外,我在reference for the SKPaymentTransaction
class中找不到transactionReceipt
属性! (即使此页面包含对“收据”的一些引用,也没有transactionReceipt属性。)
但是the documentation说它应该存在!
成功的交易包括transactionIdentifier属性和transactionReceipt属性,该属性记录已处理付款的详细信息。您的申请无需对此信息进行任何操作。您可能希望记录此信息以建立事务的审计跟踪。如果您的应用程序使用服务器来传送内容,则可以将收据发送到您的服务器并由App Store进行验证。
这有什么问题?
答案 0 :(得分:4)
该属性是私有的,并在OS X上返回一个空字符串。
“在iOS上,这是事务的transactionReceipt的值 属性。在OS X上,这是收据文件的全部内容 在应用程序包中。使用base64对收据数据进行编码 编码“。
要获得收据,请使用:
[NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]]
此示例适用于iOS和OS X,以获取收据并将其发送到服务器进行验证(使用为OS X构建设置的宏):
NSData *tr ;
#ifdef OSX
tr = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]] ;
#else
tr = [transaction transactionReceipt];
#endif
NSString *jsonObjectString = [[self encode:(uint8_t *)[tr bytes] length:[tr length]] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *completeString = [NSString stringWithFormat:@"https://ssl.myserver.com/verify.php?%@", jsonObjectString];
NSURL *urlForValidation = [NSURL URLWithString:completeString];
NSMutableURLRequest *validationRequest = [[NSMutableURLRequest alloc] initWithURL:urlForValidation];
[validationRequest setHTTPMethod:@"GET"];
NSData *responseData = [NSURLConnection sendSynchronousRequest:validationRequest returningResponse:nil error:nil];
在验证时要小心,OS X和iOS收据的json对象是不同的,因此您可能需要单独的服务器端代码进行验证。
更新:添加编码收据的功能以便发布:
+ (NSString *)encode:(const uint8_t *)input length:(NSInteger)length {
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData *data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t *output = (uint8_t *)data.mutableBytes;
for (NSInteger i = 0; i < length; i += 3) {
NSInteger value = 0;
for (NSInteger j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger index = (i / 3) * 4;
output[index + 0] = table[(value >> 18) & 0x3F];
output[index + 1] = table[(value >> 12) & 0x3F];
output[index + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[index + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
答案 1 :(得分:1)
我类转储StoreKit以确定此方法是否存在且确实存在。这是标题:
@interface SKPaymentTransaction : NSObject
{
id _internal;
}
- (id)init;
- (id)initWithDictionary:(id)arg1;
- (id)initWithPayment:(id)arg1;
- (void)dealloc;
@property(readonly) NSError *error;
@property(readonly) SKPaymentTransaction *originalTransaction;
@property(readonly) SKPayment *payment;
@property(readonly) NSDate *transactionDate;
@property(readonly) NSString *transactionIdentifier;
- (id)transactionReceipt;
@property(readonly) long long transactionState;
- (BOOL)canMergeWithTransaction:(id)arg1;
- (id)matchingIdentifier;
- (BOOL)mergeWithTransaction:(id)arg1;
- (id)_transactionIdentifier;
@end
您可以将此方法与[transaction transactionReceipt]一起使用(并获得警告)。 Apple可能会也可能不会考虑使用私有方法并拒绝您的申请;但是,出于测试目的,它就在那里。
答案 2 :(得分:0)
根据Apple的官方10.7文档SKPaymentTransaction,没有transactionReceipt属性。