Я пытаюсь интегрировать встроенные покупки в мое приложение, созданное с помощью cocos2d x c ++. Я использую easyNdk Helper для покупок в приложении. Мои покупки в приложении прекрасно работают для моих приложений Objective C. Но для cocos2d x это ошибка для следующей строки
if ([[RageIAPHelper sharedInstance] productPurchased:productP.productIdentifier])
На самом деле значение получено из файла CPP в форме аргументов и правильно показывает их значение в NSLog, но оно всегда показывает объекты как ноль, даже если objetcs выводит их сохраненное значение в NSLog
также @try условие не работает
и, наконец, выбросить следующую ошибку
Пожалуйста, помогите мне, что я должен сделать?
Спасибо
мой код .CPP
NDKHelper::AddSelector("HelloWorldSelectors",
"SampleSelector",
callfuncND_selector(Main::cameFromObjC),
this);
CCDictionary* prms = CCDictionary::create();
prms->setObject(CCString::create("SampleSelector"), "to_be_called");
prms->setObject(CCString::create(result), "BirdNameKey");
SendMessageWithParams(string("SampleSelector"), prms);
и .mm код
- (void) SampleSelector:(NSObject *)prms
{
NSLog(@"purchase something called");
NSDictionary *parameters = [[NSDictionary alloc]init];// (NSDictionary*)prms;
parameters = (NSDictionary*)prms;
NSLog(@"Passed params are : %@", parameters);
// Fetching the name of the method to be called from Native to C++
// For a ease of use, i have passed the name of method from C++
NSString* CPPFunctionToBeCalled = (NSString*)[parameters objectForKey:@"to_be_called"];
//NSString *str = [NSString stringWithFormat:@"%@",[parameters valueForKey:@"BirdNameKey"]];
NSString *BirdName = [parameters valueForKey:@"BirdNameKey"];
NSString *str = [[NSString alloc]initWithFormat:@"%@",[parameters objectForKey:@"BirdNameKey"]];
NSUserDefaults *d2 = [NSUserDefaults standardUserDefaults];
NSLog(@"%@ , %@ , %@", str,BirdName,[d2 objectForKey:@"product"]); // output is ok for all
SKProduct * product = (SKProduct *) [ APPDELEGATE.productDictionary objectForKey:[d2 objectForKey:@"product"]];
[ APPDELEGATE.priceFormatter setLocale:product.priceLocale];
APPDELEGATE.currentProduct =product;
if ([[RageIAPHelper sharedInstance] productPurchased:product.productIdentifier])
{
// check the product purchased or not but app crash at this if statement
}
[IOSNDKHelper SendMessage:CPPFunctionToBeCalled WithParameters:nil];
}
У меня также была эта проблема, и я решил ее.
в вашем IAPhelper.mm
Только сделай это Замени эту строку
_purchasedProductIdentifiers = [NSMutableSet set];
со следующей строкой
_purchasedProductIdentifiers = [[NSMutableSet alloc] init];
как показано ниже
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {
if ((self = [super init])) {
// Store product identifiers
_productIdentifiers = productIdentifiers;
// Check for previously purchased products
// _purchasedProductIdentifiers = [NSMutableSet set];
_purchasedProductIdentifiers = [[NSMutableSet alloc] init];
for (NSString * productIdentifier in _productIdentifiers) {
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased) {
[_purchasedProductIdentifiers addObject:productIdentifier];
// NSLog(@"Previously purchased: %@", productIdentifier);
} else {
// NSLog(@"Not purchased: %@", productIdentifier);
}
}
// Add self as transaction observer
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
return self;
}
Я вижу две (потенциальные) проблемы с вашим кодом,
во-первых
CCDictionary* prms = CCDictionary::create();
Обратите внимание, что инициализация объекта данных таким способом не гарантирует, что он не будет освобожден при попытке доступа к нему позже в коде (особенно в других функциях).
Итак, попробуйте это вместо этого,
CCDictionary* prms = new CCDictionary();
prms->init ... (the initialization)
Но учтите, что, выполнив это, вы теперь обязаны удалить этот объект, как только закончите с ним. Кроме того, я не уверен насчет реализации метода «setObject», если он сохраняет объект, то я считаю, что этот шаг не понадобится, но я не уверен, поэтому вы должны проверить его!
во-вторых
NSDictionary *parameters = [[NSDictionary alloc]init];// (NSDictionary*)prms;
parameters = (NSDictionary*)prms;
NSLog(@"Passed params are : %@", parameters);
Я думаю, что есть проблема в этом кастинге (или я могу ошибаться)
Я предлагаю вам сделать что-то подобное
(NSDictionary *)nsDictionaryFromCCDictionary:(cocos2d::CCDictionary *)ccDictionary {
if (ccDictionary == NULL) {
return NULL;
} else if (ccDictionary->allKeys() == NULL) {
return NULL;
} else if (ccDictionary->allKeys()->count() <= 0) {
return NULL;
}
cocos2d::CCLog("1");
NSMutableDictionary *nsDict = [NSMutableDictionary dictionaryWithCapacity:ccDictionary->allKeys()->count()];
cocos2d::CCLog("2");
for (int i = 0; i < ccDictionary->allKeys()->count(); i++) {
cocos2d::CCLog("3");
cocos2d::CCObject* obj = ccDictionary->objectForKey(((cocos2d::CCString *)ccDictionary->allKeys()->objectAtIndex(i))->getCString());
NSObject* nsObject;
if(isKindOfClass(obj, cocos2d::CCDictionary))
{
nsObject = @"Dictionary";
}
else if(isKindOfClass(obj, cocos2d::CCArray))
{
nsObject = @"Array";
}
else if (isKindOfClass(obj, cocos2d::CCString))
{
const char* cstring = ((cocos2d::CCString*)obj)->getCString();
nsObject = [[[NSString alloc] initWithBytes:cstring length:strlen(cstring) encoding:NSUTF8StringEncoding] autorelease];
}
else if (isKindOfClass(obj, cocos2d::CCInteger))
{
nsObject = [NSString stringWithFormat:@"%d", ((cocos2d::CCInteger*)obj)->getValue()];
}
else
{
nsObject = @"Unknown Object";
}
[nsDict setValue:nsObject forKey:[AnalyticXStringUtil nsstringFromCString:((cocos2d::CCString *)ccDictionary->allKeys()->objectAtIndex(i))->getCString()]];
}
return nsDict;
}
Я вставил код выше из >>> https://github.com/diwu/AnalyticX/blob/master/Add-To-Your-Own-Project/AnalyticXStringUtil.mm
Попробуйте получить словарь как CCDictionary и проверить, является ли этот объект допустимым (поскольку у mm может быть c ++ и целевой код c, так что это не будет проблемой). После создания NSDictionary попробуйте распечатать его. Надеюсь, на этот раз это не даст вам ошибок.