Изменение внутренних свойств объектов NSO (в частности, SKPaymentTransaction)
Я пытаюсь протестировать наш сервер проверки квитанций, и хотя я могу изменить внутренний API, чтобы избежать этой проблемы, это означает, что мы не полностью тестируем клиентский API, поэтому я бы хотел этого избежать.
Как часть нашего API, мы проходим через SKPaymentTransaction и затем передаем Transaction.transactionReceipt на наш сервер.
Чтобы проверить это правильно, я бы хотел создать экземпляр SKPaymentTransaction с транзакцией по моему выбору (действительные и недействительные значения).
К сожалению, SKPaymentTransaction определяет свойство actionReceipt только для чтения, и я не могу объявить расширение / подкласс, определяющее его как readwrite из-за этого.
Мне также кажется, что я не могу привести указатель SKPaymentTransaction к символу *, чтобы вручную вставить значения в память, поскольку XCode не позволяет этого в ARC.
Кто-нибудь имеет представление о том, как я могу добиться того, что я ищу?
Спасибо ли
2 ответа
Оказывается, я могу быстро получить получатель транзакции и получить свои данные в вызове.
Так что я получаю что-то вроде
-(void)test_function
{
SKPaymentTransaction* invalidTransaction = [[SKPaymentTransaction alloc] init];
Method swizzledMethod = class_getInstanceMethod([self class], @selector(replaced_getTransactionReceipt));
Method originalMethod = class_getInstanceMethod([invalidTransaction class], @selector(transactionReceipt));
method_exchangeImplementations(originalMethod, swizzledMethod);
// Call to receipt verification server
}
- (NSData*)replaced_getTransactionReceipt
{
return [@"blah" dataUsingEncoding:NSUTF8StringEncoding];
}
Я написал сообщение в блоге, показывающее мой процесс и дающее немного больше деталей здесь.
http://engineering-game-dev.com/2014/07/23/injecting-data-into-obj-c-readonly-properties/
Я вложил в подкласс SKPaymentTransaction (например, MutableSKPaymentTransaction), переопределяя параметры только для чтения. Уже существует изменяемая транзакция SKPaymentTransaction, которую вы можете использовать, или вы можете переопределить SKPayment аналогичным образом.
Пример:
в файле заголовка (MutableSKPaymentTransaction.h)
#import <StoreKit/StoreKit.h>
@interface MutableSKPaymentTransaction : SKPaymentTransaction
@property (readwrite, copy, nonatomic) NSError * error;
@property (readwrite, copy, nonatomic) SKPayment * payment;
@property (readwrite, copy, nonatomic) NSString * transactionIdentifier;
@property (readwrite, copy, nonatomic) NSDate * transactionDate;
@property (readwrite, copy, nonatomic) NSArray * downloads;
@property (readwrite, copy, nonatomic) SKPaymentTransaction *originalTransaction;
@property (assign, nonatomic) SKPaymentTransactionState transactionState;
@end
и в файле метода (MutableSKPaymentTransaction.m):
#import "MutableSKPaymentTransaction.h"
@implementation MutableSKPaymentTransaction
// readonly override
@synthesize error = _error;
@synthesize payment = _payment;
@synthesize transactionIdentifier = _transactionIdentifier;
@synthesize transactionDate = _transactionDate;
@synthesize downloads = _downloads;
@synthesize originalTransaction = _originalTransaction;
@synthesize transactionState = _transactionState;
@end