Bug in flurry.ios.cpp

Monkey Targets Forums/iOS/Bug in flurry.ios.cpp

Peeling(Posted 2015) [#1]
void BBFlurry::logEvent(String eventId, Array<class String> params)
{
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];

for (int i = 0; i < sizeof(params) / sizeof(params[0]); i = i + 2)
{
[myDictionary setObject:params[i].ToNSString() forKey:params[i + 1].ToNSString()];
}
[Flurry logEvent:eventId.ToNSString() withParameters:myDictionary];
}


sizeof(params) and sizeof(params[0]) bear no relationship to the number of strings in the array.


Peeling(Posted 2015) [#2]
Also, onstartsession sends the string "apiKey" as the apiKey, rather than the... api key.

IGNORE. This problem was caused by later modifications to the function, not the version available to download.


Peeling(Posted 2015) [#3]
AND it submits keys as values and vice versa when sending parameters.


MikeHart(Posted 2015) [#4]
Is that my Flurry module you are talking about?


Peeling(Posted 2015) [#5]
I'm not sure. It's the one I have in my monkey modules folder, but I can't see any attribution other than in the flurry.h header.

It may well have nothing to do with you. It's possible it's something that was added by another company we worked with in the past. I mentioned it here just in case it was something currently shipped with Monkey.


Peeling(Posted 2015) [#6]
Searched and found this:

http://www.fantomgl.com/flurry-monkey-x

which seems to be (almost) the one I have. Might be the older version (can't download it to check). Looks like it is yours after all :)

So, this line:

NSString* apiKey = @_STRINGIZE(CFG_FLURRY_APIKEY);

That sends the string "CFG_FLURRY_APIKEY" as the apikey, because STRINGIZE just turns the contents of the brackets into a string.


Ignore the above. Function had been modified from the original to take a parameter, which was why STRINGIZE didn't work.

This line:

for (int i = 0; i < sizeof(params) / sizeof(params[0]); i=i+2){

sizeof(params)/sizeof(params[0]) is always 1, because params is an object not a classical array.

This line (actually it's in there twice)

[myDictionary setObject:params[i].ToNSString() forKey:params[i+1].ToNSString()];

params[i] is the key and params[i+1] is the value, but that line adds them to the dictionary the wrong way around.

This line:

for (int i = 0; i < sizeof(params) ; i=i+2){

Again, sizeof(params) isn't related to the number of elements in the array object.


MikeHart(Posted 2015) [#7]
>>This line (actually it's in there twice)
Definitely not in the current version.


>>That sends the string "CFG_FLURRY_APIKEY" as the apikey,

I tested it before and back then. I got data in IOS projects. Your post indicates that it can't. Weird.


MikeHart(Posted 2015) [#8]
I will look into it in the next weeks.


MikeHart(Posted 2015) [#9]
Regarding

NSString* apiKey = @_STRINGIZE(CFG_FLURRY_APIKEY);.


Are you sure? Cause the official Admob module does it the same way.

_view.adUnitID=@_STRINGIZE(CFG_ADMOB_PUBLISHER_ID);



Peeling(Posted 2015) [#10]
If you go here:

http://www.fantomgl.com/flurry-monkey-x/

and download the 'new' version (27/04/2014), you get this version of flurry.ios.cpp:





#import "libs/Flurry.h"

class BBFlurry{

static BBFlurry *_flurry;
int _state;

public:
BBFlurry();

static BBFlurry *GetFlurry();

void onStartSession();
void onEndSession();
void logEvent(String eventId);
void logEvent(String eventId, Array<class String> params);
void logEvent(String eventId, BOOL timed);
void logEvent(String eventId, Array<class String> params, BOOL timed);
void setLogEnabled(int logFlag);
void onError(String errorId, String message, String errorClass);
void onPageView();
void setUserID(String userID);
void setAge(NSInteger age);
void setGender(String gender);

};

//flurry.ios.cpp

#define _QUOTE(X) #X
#define _STRINGIZE(X) _QUOTE(X)

BBFlurry *BBFlurry::_flurry;

BBFlurry::BBFlurry():_state(-1){
_state=0;
}

BBFlurry *BBFlurry::GetFlurry(){
if( !_flurry ) _flurry=new BBFlurry();
return _flurry;
}


void BBFlurry::onStartSession(){
NSString* apiKey = @_STRINGIZE(CFG_FLURRY_APIKEY);
[Flurry startSession:apiKey];
}

void BBFlurry::onEndSession(){
//not supported in IOS
//[Flurry endSession];
}

void BBFlurry::logEvent(String eventId){
[Flurry logEvent:eventId.ToNSString()];
}

void BBFlurry::logEvent(String eventId, Array<class String> params){
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];

for (int i = 0; i < sizeof(params) / sizeof(params[0]); i=i+2){
[myDictionary setObject:params[i].ToNSString() forKey:params[i+1].ToNSString()];
};
[Flurry logEvent:eventId.ToNSString() withParameters:myDictionary];
}

void BBFlurry::logEvent(String eventId, BOOL timed){
if (timed == TRUE) {
[Flurry logEvent:eventId.ToNSString() timed:YES];
}
else
[Flurry logEvent:eventId.ToNSString()];
}

void BBFlurry::setUserID(String userID){
[Flurry setUserID:userID.ToNSString()];
}

void BBFlurry::setGender(String gender){
[Flurry setGender:gender.ToNSString()];
}

void BBFlurry::setAge(NSInteger age){
[Flurry setAge:age];
}

void BBFlurry::logEvent(String eventId, Array<class String> params, BOOL timed){
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];

for (int i = 0; i < sizeof(params) ; i=i+2){
[myDictionary setObject:params[i].ToNSString() forKey:params[i+1].ToNSString()];
};

if (timed == TRUE) {
[Flurry logEvent:eventId.ToNSString() withParameters:myDictionary timed:YES];
}
else
[Flurry logEvent:eventId.ToNSString() withParameters:myDictionary];
}

void BBFlurry::setLogEnabled(int logFlag){
//Not supported in iOS
}

void BBFlurry::onError(String errorId, String message, String errorClass){
NSException *e = [NSException

exceptionWithName:errorClass.ToNSString()

reason:message.ToNSString()

userInfo:nil];

[Flurry logError:errorId.ToNSString() message:message.ToNSString() exception:e];
}

void BBFlurry::onPageView(){
[Flurry logPageView];
}





This code DOES have the lines I highlighted regarding counting the number of params incorrectly and passing the keys/values the wrong way around.

EDIT: My mistake about the apikey! Sorry. That function had been changed since your original version (like I said, I inherited this set of modules) and had an API key as a parameter. Obviously stringizing a parameter isn't going to work :) I'll amend my earlier post to correct this.