Передняя: iOS внутренняя покупка в Unity
В этом тексте рассказывается о реализации внутренней покупки в iOS для проекта на Unity. Автор делится опытом и описывает процесс работы с кодом.
Идея: реализация внутренней покупки в Unity с использованием кода для iOS.
Эффект: представлены скриншоты окна покупки и результата покупки.
Процесс: автор не стал подробно описывать процесс, а приложил скриншоты.
OC код:
#import <Foundation/Foundation.h>
@interface IAPInterface : NSObject
@end
#import "IAPInterface.h"
#import "IAPManager.h"
@implementation IAPInterface
void TestMsg(){
NSLog(@"Msg received");
}
void TestSendString(void *p){
NSString *list = [NSString stringWithUTF8String:p];
NSArray *listItems = [list componentsSeparatedByString:@"\t"];
for (int i =0; i<listItems.count; i++) {
NSLog(@"msg %d : %@",i,listItems[i]);
}
}
void TestGetString(){
NSArray *test = [NSArray arrayWithObjects:@"t1",@"t2",@"t3", nil];
NSString *join = [test componentsJoinedByString:@"\n"];
UnitySendMessage("Main", "IOSToU", [join UTF8String]);
}
IAPManager *iapManager = nil;
void InitIAPManager(){
iapManager = [[IAPManager alloc] init];
[iapManager attachObserver];
}
bool IsProductAvailable(){
return [iapManager CanMakePayment];
}
void RequstProductInfo(void *p){
NSString *list = [NSString stringWithUTF8String:p];
NSLog(@"productKey:%@",list);
[iapManager requestProductData:list];
}
void BuyProduct(void *p){
[iapManager buyRequest:[NSString stringWithUTF8String:p]];
}
@end
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
@interface IAPManager : NSObject<SKProductsRequestDelegate, SKPaymentTransactionObserver>{
SKProduct *proUpgradeProduct;
SKProductsRequest *productsRequest;
}
-(void)attachObserver;
-(BOOL)CanMakePayment;
-(void)requestProductData:(NSString *)productIdentifiers;
-(void)buyRequest:(NSString *)productIdentifier;
@end
#import "IAPManager.h"
@implementation IAPManager
-(void) attachObserver{
NSLog(@"AttachObserver");
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
-(BOOL) CanMakePayment{
return [SKPaymentQueue canMakePayments];
}
-(void) requestProductData:(NSString *)productIdentifiers{
NSArray *idArray = [productIdentifiers componentsSeparatedByString:@"\t"];
NSSet *idSet = [NSSet setWithArray:idArray];
[self sendRequest:idSet];
}
-(void)sendRequest:(NSSet *)idSet{
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:idSet];
request.delegate = self;
[request start];
}
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSArray *products = response.products;
for (SKProduct *p in products) {
UnitySendMessage("Main", "ShowProductList", [[self productInfo:p] UTF8String]);
}
for(NSString *invalidProductId in response.invalidProductIdentifiers){
NSLog(@"Invalid product id:%@",invalidProductId);
}
[request autorelease];
}
-(void)buyRequest:(NSString *)productIdentifier{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:productIdentifier];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
-(NSString *)productInfo:(SKProduct *)product{
NSArray *info = [NSArray arrayWithObjects:product.localizedTitle,product.localizedDescription,product.price,product.productIdentifier, nil];
return [info componentsJoinedByString:@"\t"];
}
-(NSString *)transactionInfo:(SKPaymentTransaction *)transaction{
return [self encode:(uint8_t *)transaction.transactionReceipt.bytes length:transaction.transactionReceipt.length];
//return [[NSString alloc] initWithData:transaction.transactionReceipt encoding:NSASCIIStringEncoding];
}
-(NSString *)encode:(const uint8_t *)input length:(NSInteger) length{
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData *data = [NSMutableData dataWithLength:((length+2)/3)*4];
``` ## Проверка покупок в iOS
Если мы не предпримем никаких действий, джейлбрейк-устройства могут напрямую обойти проверку платежей и получить результат. Это крайне неприятно для нас, разработчиков, которые потратили много времени и усилий на разработку. Поэтому нам необходимо изучить информацию о проверке покупок внутри приложения и узнать, как предотвратить подобные ситуации.
### Полезные ресурсы:
* https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1
* http://hpique.github.io/RMStore-presentation-for-NSBarcelona
* http://asciiwwdc.com/2014/sessions/305
### Локальная проверка:
Преимущества:
* Не требуется серверная проверка.
Недостатки:
* Необходимо включить OpenSSL в проект.
Ссылки:
* http://stackoverflow.com/a/20039394/656428
* https://github.com/robotmedia/RMStore#receipt-verification
* https://github.com/robotmedia/RMStore/wiki/Receipt-verification
### Серверная проверка:
Преимущества:
* Серверная проверка по SSL — наиболее надёжный способ определить подлинность записей о покупках.
Недостатки:
* Требуется развёртывание сервера, обмен данными между сервером и приложением может быть легче взломать.
Ссылки:
* https://github.com/nomad/venice
* https://github.com/pcrawfor/iap_verifier
### Двойная проверка:
Сначала локальная проверка, затем повторная проверка на сервере (кажется ненужной).
### Прочее:
* Mac App с именем Receigen от etiemble.com генерирует код, который можно интегрировать в Xcode.
### Распространённые методы взлома:
* http://blog.hussulinux.com/2013/04/apple-ios-in-app-purchase-hacking-how-to-prevent-specially-com-zeptolab-ctrbonus-superpower1-hacks/
* http://stackoverflow.com/a/17687827/656428
### В заключение:
* Серверная верификация подходит для приложений с собственной системой учётных записей, которая может защитить IAP от взлома. В противном случае её легко взломать.
* Для локальной верификации используйте следующие методы для усиления защиты:
* Убедитесь, что сертификат SSL, используемый для подключения к серверу App Store, является сертификатом EV.
* Проверьте, соответствует ли информация, возвращаемая при проверке, информации в объекте SKPayment.
* Убедитесь, что квитанция имеет действительную подпись.
* Убедитесь, что новые транзакции имеют уникальный идентификатор транзакции.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )