annotate eventLogger.mm @ 30:c0a6f7c66719

Josh M test "in house" version 0.1
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Wed, 27 Feb 2013 11:39:07 +0000
parents fabb3a5cdfc9
children 23ef179c3748
rev   line source
rt300@0 1 //
rt300@0 2 // eventLogger.mm
rt300@0 3 // oscSenderExample
rt300@0 4 //
rt300@0 5 // Created by Robert Tubb on 05/11/2012.
rt300@0 6 //
rt300@0 7 //
rt300@4 8
rt300@8 9 //---------------------------------------------------------------------------
rt300@0 10 #include "eventLogger.h"
rt300@1 11
rt300@1 12 EventLogger eventLogger;
rt300@29 13
rt300@8 14 //---------------------------------------------------------------------------
rt300@1 15 EventLogger::EventLogger(){
rt300@14 16 //QuestionnaireViewController * questionnaireViewController;
rt300@8 17
rt300@25 18 consentGiven = true; // unless told otherwise by introView
rt300@8 19 loggingEnabled = true;
rt300@22 20 serverConnectionOK = false;
rt300@22 21 questionnaireCompleted = false;
rt300@22 22 questionnaireUploaded = false;
rt300@27 23 currentHTTPRequestID = -1;
rt300@27 24 logUploadInProgress = false;
rt300@22 25 ofxiPhoneDeviceType iOSdeviceType = ofxiPhoneGetDeviceType();
rt300@22 26 cout << "Device: " << iOSdeviceType << '\n';
rt300@22 27
rt300@25 28 nextUploadQty = UPLOAD_CHUNK_SIZE; // amount of data uploaded is always more than UPLOAD_CHUNK_SIZE events
rt300@27 29
rt300@8 30 }
rt300@8 31 //---------------------------------------------------------------------------
rt300@24 32 // draw() - show path of last N scroll events - can be scrubbed along?
rt300@24 33 //
rt300@24 34 //---------------------------------------------------------------------------
rt300@29 35
rt300@8 36 void EventLogger::init(){
rt300@4 37
rt300@30 38 checkExistingLogFile(ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME);
rt300@8 39 sessionStartTime = ofGetSystemTime();
rt300@9 40
rt300@9 41 testConnection();
rt300@7 42
rt300@25 43 logEvent(APP_STARTED);
rt300@29 44
rt300@30 45 NSString *jsondata;
rt300@30 46 jsondata=@"{\"test\":\"test\"";
rt300@30 47 serverComms = [[ServerComms alloc] init];
rt300@29 48
rt300@30 49 }
rt300@30 50 //---------------------------------------------------------------------------
rt300@30 51 // this reads the persistent log file , checks if we've used the app before and
rt300@30 52 // if we've answered questionnaire or not
rt300@30 53 void EventLogger::checkExistingLogFile(const string &jsonFile){
rt300@30 54 Json::Value root;
rt300@30 55 Json::Reader reader;
rt300@30 56
rt300@30 57 /////////////
rt300@30 58 // read file
rt300@30 59
rt300@30 60 ifstream theFile(jsonFile.c_str());
rt300@30 61 stringstream fileText;
rt300@30 62 string line;
rt300@30 63 if(!theFile){
rt300@30 64
rt300@30 65 firstEverAppOpen();
rt300@30 66 return;
rt300@30 67 }else{
rt300@30 68 while(theFile){
rt300@30 69 theFile >> line;
rt300@30 70 // cout << line; // lots!!!!
rt300@30 71 fileText << line;
rt300@30 72 }
rt300@30 73 theFile.close();
rt300@30 74 }
rt300@30 75
rt300@30 76 // otherwise, we've been in here before
rt300@30 77
rt300@30 78 /////////////
rt300@30 79 // Parse json
rt300@30 80 cout << "size of log JSON string:" << fileText.str().length() << "BYTES \n";
rt300@30 81
rt300@30 82 bool parsingSuccessful = reader.parse( fileText.str(), root );
rt300@30 83
rt300@30 84 if ( !parsingSuccessful )
rt300@30 85 {
rt300@30 86 // report to the user the failure and their locations in the document.
rt300@30 87 std::cout << "Failed to parse event log JSON: \n"
rt300@30 88 << reader.getFormattedErrorMessages();
rt300@30 89 return;
rt300@30 90 }
rt300@30 91
rt300@30 92 /////////////////
rt300@30 93 // now put user deets into variables
rt300@30 94
rt300@30 95 userName = root["userName"].asString();
rt300@30 96 deviceID = root["deviceID"].asLargestInt();
rt300@30 97 nextUploadNumber = root["uploadNumber"].asInt();
rt300@30 98 savedInteractionTime = root["savedInteractionTime"].asLargestInt();
rt300@30 99 questionnaireCompleted = root["questionnaireCompleted"].asBool();
rt300@30 100 questionnaireUploaded = root["questionnaireUploaded"].asBool();
rt300@30 101 interfaceOrder = root["interfaceOrder"].asInt();
rt300@30 102
rt300@29 103
rt300@30 104 // check for unuploaded evts
rt300@30 105 const Json::Value jlogs = root["events"];
rt300@29 106
rt300@30 107 for ( int index = 0; index < jlogs.size(); ++index ) theEvents.push_back(lEvent(jlogs[index]));
rt300@30 108 if(theEvents.size() > nextUploadQty && ! logUploadInProgress){
rt300@30 109 //try to upload
rt300@30 110 uploadEventLog(true);
rt300@30 111 }
rt300@30 112
rt300@30 113 //////////////
rt300@30 114 // what stage is the experiment at??
rt300@30 115
rt300@30 116 if(questionnaireCompleted && !questionnaireUploaded){
rt300@30 117 // then read it in and upload it
rt300@30 118 Json::Value JQ = root["questionnaire"];
rt300@30 119 Json::Value JArray = JQ["qAnswers"];
rt300@30 120 if(JArray.size() < 2){
rt300@30 121 cout << "Error - status of questionnaire is wierd\n";
rt300@30 122 }
rt300@30 123 for ( unsigned int i = 0; i < JArray.size(); i++ )
rt300@30 124 {
rt300@30 125 questionnaireAnswers.push_back(JArray[i].asInt());
rt300@30 126 }
rt300@30 127 questionnaireComments = JQ["comments"].toStyledString();
rt300@30 128 uploadQuestionnaire();
rt300@30 129 }
rt300@30 130 //TODO if questionnaire wasn't reached but still opened then set the timer to something sensible
rt300@30 131
rt300@30 132 if(!questionnaireCompleted){
rt300@30 133 // for now sod it, start from scratch
rt300@30 134 firstEverAppOpen();
rt300@30 135 return;
rt300@30 136 }
rt300@30 137 cout << "Total interaction time: " << savedInteractionTime << '\n';
rt300@30 138
rt300@30 139 //timer.setInteractionTime(savedInteractionTime);
rt300@30 140 //timer.setOrderFromPrevious(interfaceOrder);
rt300@30 141
rt300@8 142 }
rt300@29 143
rt300@8 144 //---------------------------------------------------------------------------
rt300@30 145
rt300@30 146 void EventLogger::firstEverAppOpen(){
rt300@30 147 cout<<"no event log file - first APP open\n";
rt300@30 148 nextUploadNumber = 0;
rt300@30 149 deviceID = ofGetSystemTimeMicros();
rt300@30 150 savedInteractionTime = 0;
rt300@30 151 questionnaireCompleted = false;
rt300@30 152 questionnaireUploaded = false;
rt300@30 153
rt300@30 154 ((testApp *)ofGetAppPtr())->showIntro();
rt300@30 155 consentGiven = false;
rt300@30 156
rt300@30 157 }
rt300@30 158
rt300@30 159
rt300@30 160 //---------------------------------------------------------------------------
rt300@28 161 void EventLogger::questionnaireAnswersObtained(vector<int> answers, const char* userComments){
rt300@22 162
rt300@22 163 questionnaireCompleted = true;
rt300@22 164 questionnaireAnswers = answers;
rt300@28 165 questionnaireComments = userComments;
rt300@22 166 uploadQuestionnaire();
rt300@22 167
rt300@22 168 }
rt300@22 169 //---------------------------------------------------------------------------
rt300@27 170 void EventLogger::uploadQuestionnaire(){
rt300@22 171 // show indicator
rt300@22 172 cout << "^^^^^^^^ UPLOADING QUESTIONNAIRE ^^^^^^^^ \n";
rt300@22 173
rt300@27 174 sendToServer("questionnaire", questionnaireToJson(), true);
rt300@27 175
rt300@22 176 }
rt300@22 177 //---------------------------------------------------------------------------
rt300@27 178 bool EventLogger::sendToServer(string functionName, Json::Value jsonData, bool async = false){
rt300@22 179
rt300@22 180 Json::FastWriter writer;
rt300@22 181 string jsontext = writer.write( jsonData );
rt300@22 182
rt300@27 183 // remove newline
rt300@22 184 if (!jsontext.empty() && jsontext[jsontext.length()-1] == '\n') {
rt300@22 185 jsontext.erase(jsontext.length()-1);
rt300@22 186 }
rt300@30 187 ostringstream jd;
rt300@30 188 jd << jsontext;
rt300@30 189 NSString *theData = [NSString stringWithUTF8String:jd.str().c_str()];
rt300@30 190 NSString *theType = [NSString stringWithUTF8String:functionName.c_str()];
rt300@22 191
rt300@30 192 if(async){
rt300@30 193 [serverComms doPostRequest:theType withData:theData];
rt300@30 194 }else{
rt300@30 195 bool success = [serverComms doSyncPostRequest:theType withData:theData];
rt300@30 196 return success;
rt300@30 197 }
rt300@29 198
rt300@27 199 }
rt300@27 200 //-----------------------------
rt300@30 201 void EventLogger::questionnaireOK(){
rt300@30 202 questionnaireUploaded = true;
rt300@30 203 }
rt300@30 204 //-----------------------------
rt300@30 205 void EventLogger::eventlogOK(){
rt300@30 206 //theEvents.clear();
rt300@30 207 cout << "EVENT LOG UPLOAD SUCCESS\n";
rt300@30 208 nextUploadNumber++;
rt300@30 209 logUploadInProgress = false;
rt300@30 210 }
rt300@30 211 //-----------------------------
rt300@30 212 void EventLogger::testConnectionOK(){
rt300@30 213 cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n";
rt300@30 214 serverConnectionOK = true;
rt300@30 215 }
rt300@30 216 //-----------------------------
rt300@30 217 void EventLogger::questionnaireNotOK(){
rt300@30 218 questionnaireUploaded = false;
rt300@30 219 }
rt300@30 220 //-----------------------------
rt300@30 221 void EventLogger::eventlogNotOK(){
rt300@30 222 // try later
rt300@30 223 nextUploadQty += UPLOAD_CHUNK_SIZE;
rt300@30 224 logUploadInProgress = false;
rt300@30 225 }
rt300@30 226 //-----------------------------
rt300@30 227 void EventLogger::testConnectionNotOK(){
rt300@30 228 cout << "^^^^^^^^ server connection NOT OK ^^^^^^^^ \n";
rt300@30 229 serverConnectionOK = false;
rt300@30 230 // alert?
rt300@30 231
rt300@30 232 }
rt300@30 233 /*
rt300@27 234 void EventLogger::urlResponse(ofHttpResponse & response){
rt300@27 235 cout << "gotHTTPRequestStatus\n";
rt300@27 236 cout << "HTTP REQUEST NAME " << response.request.name << "\n";
rt300@27 237 cout << "HTTP STATUS " << response.status << "\n";
rt300@27 238 cout << "HTTP ERROR " << response.error << "\n";
rt300@27 239 cout << "HTTP DATA " << response.data << "\n"; // ofBuffer
rt300@9 240
rt300@27 241 bool sent;
rt300@27 242 stringstream respStr;
rt300@27 243 respStr << response.data;
rt300@22 244
rt300@27 245 if (response.status == 200){
rt300@27 246 if(respStr.str() == "OK"){
rt300@22 247
rt300@22 248 sent = true;
rt300@22 249 }else{
rt300@22 250 // not ok
rt300@22 251 // problem serverside
rt300@22 252 sent = false;
rt300@22 253 }
rt300@9 254 }else{
rt300@22 255
rt300@22 256 sent = false;
rt300@9 257 // SHOW AN ALERT TO USER?
rt300@9 258 }
rt300@27 259
rt300@27 260 // now do request specific stuff
rt300@27 261 if(response.request.name == "eventlog"){
rt300@27 262 if(!sent){
rt300@27 263 // try later
rt300@27 264 nextUploadQty += UPLOAD_CHUNK_SIZE;
rt300@27 265 }else{
rt300@27 266
rt300@27 267 // if success - clear memory
rt300@27 268 theEvents.clear();
rt300@27 269 cout << "UPLOAD SUCCESS\n";
rt300@27 270 nextUploadNumber++;
rt300@27 271 }
rt300@27 272 logUploadInProgress = false;
rt300@27 273 }else if(response.request.name == "questionnaire"){
rt300@27 274 if(sent){
rt300@27 275 questionnaireUploaded = true;
rt300@27 276 }else{
rt300@27 277 questionnaireUploaded = false; // will try next time... when?
rt300@27 278 }
rt300@27 279 }else if(response.request.name == "testConnection"){
rt300@27 280
rt300@27 281 if (sent){
rt300@27 282 cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n";
rt300@27 283 serverConnectionOK = true;
rt300@27 284 }else{
rt300@28 285 serverConnectionOK = false;
rt300@27 286 cout << "server connection ERROR \n";
rt300@27 287 }
rt300@27 288 }
rt300@27 289
rt300@22 290 }
rt300@30 291 */
rt300@22 292 //---------------------------------------------------------------------------
rt300@22 293 bool EventLogger::testConnection(){
rt300@22 294 Json::Value root;
rt300@30 295 root["test"] = "test";
rt300@27 296 sendToServer("testConnection", root, true);
rt300@27 297
rt300@9 298 }
rt300@9 299 //---------------------------------------------------------------------------
rt300@9 300
rt300@27 301 bool EventLogger::uploadEventLog(bool async){
rt300@28 302
rt300@22 303 // show indicator
rt300@27 304 logUploadInProgress = true;
rt300@25 305 cout << "^^^^^^^^ ATTEMPTING TO UPLOAD " << theEvents.size() << " EVENTS ^^^^^^^^ .\n";
rt300@27 306 if(!async){
rt300@27 307 bool success = sendToServer("eventlog", logsToJson(), async);
rt300@27 308 if(!success){
rt300@29 309 // try later : NOPE has maximum size
rt300@27 310 nextUploadQty += UPLOAD_CHUNK_SIZE;
rt300@27 311 }else{
rt300@27 312
rt300@27 313 // if success - clear memory
rt300@30 314 //theEvents.clear();
rt300@27 315 cout << "UPLOAD SUCCESS\n";
rt300@27 316 nextUploadNumber++;
rt300@27 317 }
rt300@27 318 logUploadInProgress = false;
rt300@27 319 return success;
rt300@9 320 }else{
rt300@27 321 sendToServer("eventlog", logsToJson(), async);
rt300@9 322 }
rt300@1 323 }
rt300@8 324 //----------------------------------------------------------------------------
rt300@27 325
rt300@27 326 //----------------------------------------------------------------------------
rt300@9 327 //void EventLogger::deleteLogFile(){
rt300@8 328
rt300@8 329
rt300@28 330 //---------------------------------------------------------------------------
rt300@28 331 // only called when doing supervised tests
rt300@27 332 void EventLogger::newUser(){
rt300@27 333 cout<<"setup new user\n";
rt300@29 334 deleteLogs();
rt300@27 335 nextUploadNumber = 0;
rt300@27 336 deviceID = ofGetSystemTimeMicros();
rt300@27 337 savedInteractionTime = 0;
rt300@28 338 totalInteractionTime = 0;
rt300@28 339 sessionStartTime = ofGetSystemTime();
rt300@27 340 questionnaireCompleted = false;
rt300@29 341 questionnaireUploaded = false;
rt300@29 342
rt300@29 343 ((testApp *)ofGetAppPtr())->showIntro();
rt300@27 344
rt300@27 345 }
rt300@8 346 //---------------------------------------------------------------------------
rt300@8 347 // called from alertView OK in iViewController
rt300@8 348 void EventLogger::setUsername(const char *u){
rt300@8 349 userName = u;
rt300@28 350 // start interaction clock
rt300@29 351
rt300@29 352 //timer.startInteractionClock();
rt300@29 353 [((testApp *)ofGetAppPtr())->tsc startTimer];
rt300@28 354 }
rt300@28 355 //---------------------------------------------------------------------------
rt300@28 356 void EventLogger::thinnedLogEvent(lEvent newEvent){
rt300@28 357 static lEvent previousEvent(APP_STARTED); // initialised as whatever. hopefully won't log
rt300@28 358 static int eventCounter = 0;
rt300@28 359
rt300@28 360 // if first event then log it. it won't be, but still.
rt300@28 361 if(theEvents.size() == 0){
rt300@28 362 theEvents.push_back(newEvent);
rt300@28 363 previousEvent = newEvent;
rt300@28 364 return;
rt300@28 365 }
rt300@28 366
rt300@28 367 // if previous event is more than 300ms ago, or event type has changed, log both of them
rt300@28 368 int gap = newEvent.eventTime - previousEvent.eventTime;
rt300@28 369 if(gap > 300 || newEvent.eventType != previousEvent.eventType){
rt300@28 370 // if prev event not logged, log it
rt300@28 371 if((*theEvents.end()).eventTime != previousEvent.eventTime){
rt300@28 372 theEvents.push_back(previousEvent);
rt300@28 373 }
rt300@28 374 theEvents.push_back(newEvent);
rt300@7 375
rt300@28 376 }
rt300@28 377
rt300@28 378 // otherwise only record every Nth event
rt300@28 379 if(eventCounter >= EVENT_THIN_FACTOR){
rt300@28 380 theEvents.push_back(newEvent);
rt300@28 381 eventCounter = 0;
rt300@28 382
rt300@28 383 }
rt300@28 384 eventCounter++;
rt300@28 385 previousEvent = newEvent;
rt300@7 386 }
rt300@8 387 //---------------------------------------------------------------------------
rt300@5 388 void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){
rt300@3 389 //cout << "log: " << evtType << "\n";
rt300@1 390
rt300@1 391 // scroll has 2 double coords
rt300@1 392 // zoom has 1 double scale
rt300@1 393 // save preset has 2 coords
rt300@1 394 // switch view has view type
rt300@9 395 // slider change has int slider index and 1 float value
rt300@1 396
rt300@4 397 // get time for key index
rt300@4 398
rt300@5 399 // thinFactor
rt300@5 400 if(!loggingEnabled) return;
rt300@4 401 switch ( evtType ) {
rt300@28 402 // data thinning here
rt300@28 403 case SCROLL:
rt300@28 404 thinnedLogEvent(lEvent(evtType,centre.x,centre.y));
rt300@28 405 break;
rt300@28 406 case ZOOM:
rt300@28 407 thinnedLogEvent(lEvent(evtType,scale));
rt300@28 408 break;
rt300@28 409 case CHANGE_SLIDER:
rt300@28 410 thinnedLogEvent(lEvent(evtType,sliderVal , 0.0 , sliderID));
rt300@28 411 break;
rt300@29 412 // non thinned data
rt300@4 413 case SAVE_PRESET:
rt300@5 414 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@4 415 // Code
rt300@4 416 break;
rt300@4 417 case SAVE_DESET:
rt300@5 418 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@4 419 break;
rt300@28 420
rt300@5 421 case SCROLL_STOPPED:
rt300@5 422 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
rt300@22 423 cout << "SCROLL STOPPED EVENT\n";
rt300@22 424 break;
rt300@22 425 case SNAPPED_TO_PRESET:
rt300@22 426 theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID));
rt300@22 427 cout << "SCROLL STOPPED EVENT\n";
rt300@4 428 break;
rt300@25 429 case SWAP_VIEW:
rt300@25 430 theEvents.push_back(lEvent(evtType,0.0 , 0.0 , sliderID)); // slider ID is which view
rt300@25 431 break;
rt300@4 432 default:
rt300@25 433 // default is just an event type with no values
rt300@25 434 theEvents.push_back(lEvent(evtType));
rt300@4 435 break;
rt300@1 436 }
rt300@27 437 if(theEvents.size() > nextUploadQty && !logUploadInProgress){
rt300@27 438 //try to upload asynchronously
rt300@27 439 uploadEventLog(true);
rt300@7 440 }
rt300@9 441 //sessionTime = (ofGetSystemTime() - sessionStartTime);
rt300@28 442 totalInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime); // milliseconds
rt300@28 443
rt300@1 444 }
rt300@29 445 //--------------------------------------------------------------------
rt300@29 446 // called from newUser
rt300@29 447 void EventLogger::deleteLogs(){
rt300@29 448 // the
rt300@29 449 theEvents.clear();
rt300@29 450 string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME;
rt300@29 451 ofFile logFile(fname,ofFile::WriteOnly);
rt300@29 452 logFile << "";
rt300@29 453 logFile.close();
rt300@29 454 }
rt300@8 455 //---------------------------------------------------------------------------
rt300@7 456
rt300@7 457 void EventLogger::exitAndSave(){
rt300@25 458
rt300@25 459 if(!consentGiven){
rt300@25 460 logEvent(CONSENT_DENIED);
rt300@25 461 Json::Value jlogs = logsToJson();
rt300@25 462 // try to upload TODO (no - might hang and prevent exit???)
rt300@27 463 uploadEventLog(true);
rt300@25 464 return;
rt300@25 465 }
rt300@25 466 logEvent(APP_EXITED);
rt300@25 467 savedInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime);
rt300@7 468 // save user details
rt300@8 469 string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME;
rt300@8 470
rt300@25 471 // try to upload TODO (no - might hang and prevent exit???)
rt300@27 472 // do it async because event list needs to be cleared to prevent saving on device
rt300@27 473 uploadEventLog(false);
rt300@7 474
rt300@8 475 // write to file
rt300@25 476 // json without the logs that were uploaded!
rt300@25 477 Json::Value jlogs = logsToJson();
rt300@8 478 ofFile logFile(fname,ofFile::WriteOnly);
rt300@8 479 logFile << jlogs;
rt300@29 480 logFile.close();
rt300@8 481
rt300@8 482 }
rt300@8 483 //---------------------------------------------------------------------------
rt300@8 484
rt300@8 485 Json::Value EventLogger::logsToJson(){
rt300@8 486 // put all logged events into Json formatted string
rt300@8 487 Json::Value root;
rt300@8 488
rt300@8 489 vector<lEvent>::iterator eventIter;
rt300@8 490
rt300@22 491 root["programVersion"] = PROGRAM_VERSION;
rt300@8 492 root["userName"] = userName;
rt300@8 493 root["deviceID"] = deviceID;
rt300@25 494 root["uploadNumber"] = nextUploadNumber;
rt300@22 495 root["iOSdeviceType"] = iOSdeviceType;
rt300@25 496 root["savedInteractionTime"] = savedInteractionTime;
rt300@22 497 root["questionnaireCompleted"] = questionnaireCompleted;
rt300@22 498 root["questionnaireUploaded"] = questionnaireUploaded;
rt300@30 499 root["questionnaire"] = questionnaireToJson();
rt300@30 500
rt300@8 501
rt300@8 502 int i = 0;
rt300@8 503 for(eventIter = theEvents.begin(); eventIter < theEvents.end(); eventIter++){
rt300@8 504 root["events"][i] = (*eventIter).eventToJson();
rt300@8 505 i++;
rt300@7 506 }
rt300@25 507 root["numEventsHere"] = i;
rt300@8 508 return root;
rt300@8 509 }
rt300@22 510
rt300@8 511 //---------------------------------------------------------------------------
rt300@22 512
rt300@22 513 Json::Value EventLogger::questionnaireToJson(){
rt300@22 514 // put all answers into Json formatted string
rt300@22 515 Json::Value root;
rt300@22 516
rt300@22 517 vector<int>::iterator aIter;
rt300@22 518
rt300@22 519 Json::Value questionnaire;
rt300@22 520
rt300@22 521 int i = 0;
rt300@22 522 for(aIter = questionnaireAnswers.begin(); aIter < questionnaireAnswers.end(); aIter++){
rt300@22 523 questionnaire[i] = (*aIter);
rt300@22 524 i++;
rt300@22 525 }
rt300@22 526
rt300@22 527 root["qAnswers"] = questionnaire;
rt300@28 528 root["comments"] = questionnaireComments;
rt300@22 529 root["userName"] = userName;
rt300@22 530 root["deviceID"] = deviceID;
rt300@22 531 root["iOSdeviceType"] = iOSdeviceType;
rt300@22 532 root["programVersion"] = PROGRAM_VERSION;
rt300@22 533
rt300@22 534 return root;
rt300@22 535 }
rt300@30 536
rt300@8 537 //---------------------------------------------------------------------------
rt300@30 538 void EventLogger::printAll(){
rt300@30 539 cout << "-----------------ALL LOGGED EVENTS----------------- \n";
rt300@30 540 vector<lEvent>::iterator evIter;
rt300@30 541 cout << logsToJson() << "\n";
rt300@30 542 cout << "---------------------QUESTIONNAIRE---------------- \n";
rt300@30 543 cout << questionnaireToJson() << "\n";
rt300@30 544 };
rt300@8 545 //---------------------------------------------------------------------------