1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dingxiaowei-iOSPurchase

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Передняя: iOS внутренняя покупка в Unity

В этом тексте рассказывается о реализации внутренней покупки в iOS для проекта на Unity. Автор делится опытом и описывает процесс работы с кодом.

Идея: реализация внутренней покупки в Unity с использованием кода для iOS.

Эффект: представлены скриншоты окна покупки и результата покупки.

Процесс: автор не стал подробно описывать процесс, а приложил скриншоты.

OC код:

  • IAPInterface — это класс, который служит связующим звеном между Unity и OC кодом для внутренней покупки. Он содержит методы для взаимодействия с системой покупки, такие как TestMsg, TestSendString, TestGetString, InitIAPManager, IsProductAvailable, RequstProductInfo и BuyProduct.
#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
  • IAPManager — это класс, реализующий функции внутренней покупки на iOS. Он имеет методы attachObserver, CanMakePayment, requestProductData и buyRequest.
#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 )

Вы можете оставить комментарий после Вход в систему

Введение

Интра-покупки в Unity для iOS. Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/dingxiaowei-iOSPurchase.git
git@api.gitlife.ru:oschina-mirror/dingxiaowei-iOSPurchase.git
oschina-mirror
dingxiaowei-iOSPurchase
dingxiaowei-iOSPurchase
master