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@1
|
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@8
|
35 void EventLogger::init(){
|
rt300@4
|
36
|
rt300@8
|
37 readJsonToLog(ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME);
|
rt300@8
|
38 sessionStartTime = ofGetSystemTime();
|
rt300@9
|
39
|
rt300@9
|
40 testConnection();
|
rt300@7
|
41
|
rt300@25
|
42 logEvent(APP_STARTED);
|
rt300@8
|
43 }
|
rt300@8
|
44 //---------------------------------------------------------------------------
|
rt300@22
|
45 void EventLogger::questionnaireAnswersObtained(vector<int> answers){
|
rt300@22
|
46
|
rt300@22
|
47 questionnaireCompleted = true;
|
rt300@22
|
48 questionnaireAnswers = answers;
|
rt300@22
|
49
|
rt300@22
|
50 uploadQuestionnaire();
|
rt300@22
|
51
|
rt300@22
|
52 }
|
rt300@22
|
53 //---------------------------------------------------------------------------
|
rt300@27
|
54 void EventLogger::uploadQuestionnaire(){
|
rt300@22
|
55 // show indicator
|
rt300@22
|
56 cout << "^^^^^^^^ UPLOADING QUESTIONNAIRE ^^^^^^^^ \n";
|
rt300@22
|
57
|
rt300@27
|
58 sendToServer("questionnaire", questionnaireToJson(), true);
|
rt300@27
|
59
|
rt300@22
|
60 }
|
rt300@22
|
61 //---------------------------------------------------------------------------
|
rt300@27
|
62 bool EventLogger::sendToServer(string functionName, Json::Value jsonData, bool async = false){
|
rt300@22
|
63 bool sent;
|
rt300@22
|
64 string request;
|
rt300@22
|
65
|
rt300@22
|
66 if(functionName == "testConnection"){
|
rt300@22
|
67 request = "http://127.0.0.1:8080/testservice/testConnection?jsontext=";
|
rt300@22
|
68 }else if(functionName == "questionnaire"){
|
rt300@22
|
69 request = "http://127.0.0.1:8080/testservice/questionnaire?jsontext=";
|
rt300@22
|
70 }else if(functionName == "eventlog"){
|
rt300@22
|
71 request = "http://127.0.0.1:8080/testservice/eventlog?jsontext=";
|
rt300@22
|
72 }
|
rt300@22
|
73 Json::FastWriter writer;
|
rt300@22
|
74 string jsontext = writer.write( jsonData );
|
rt300@22
|
75
|
rt300@27
|
76 // remove newline
|
rt300@22
|
77 if (!jsontext.empty() && jsontext[jsontext.length()-1] == '\n') {
|
rt300@22
|
78 jsontext.erase(jsontext.length()-1);
|
rt300@22
|
79 }
|
rt300@22
|
80
|
rt300@22
|
81 request.append(jsontext);
|
rt300@27
|
82
|
rt300@27
|
83 if(!async){
|
rt300@27
|
84 ofURLFileLoader fileLoader;
|
rt300@27
|
85 ofHttpResponse resp;
|
rt300@27
|
86 resp = fileLoader.get(request);
|
rt300@22
|
87
|
rt300@27
|
88 cout << "HTTP STATUS " << resp.status << "\n";
|
rt300@27
|
89 cout << "HTTP ERROR " << resp.error << "\n";
|
rt300@27
|
90 cout << "HTTP DATA " << resp.data << "\n"; // ofBuffer
|
rt300@27
|
91
|
rt300@27
|
92 stringstream response;
|
rt300@27
|
93 response << resp.data;
|
rt300@27
|
94
|
rt300@27
|
95 if (resp.status == 200){
|
rt300@27
|
96 if(response.str() == "OK"){
|
rt300@27
|
97
|
rt300@27
|
98 sent = true;
|
rt300@27
|
99 }else{
|
rt300@27
|
100 // not ok
|
rt300@27
|
101 // problem serverside
|
rt300@27
|
102 sent = false;
|
rt300@27
|
103 }
|
rt300@27
|
104 }else{
|
rt300@27
|
105
|
rt300@27
|
106 sent = false;
|
rt300@27
|
107 // SHOW AN ALERT TO USER?
|
rt300@27
|
108 }
|
rt300@27
|
109
|
rt300@27
|
110 return sent;
|
rt300@27
|
111 }else{ // async
|
rt300@27
|
112 ofURLFileLoader fileLoader;
|
rt300@27
|
113 currentHTTPRequestID = ofLoadURLAsync(request, functionName);
|
rt300@27
|
114 ofRegisterURLNotification(this);
|
rt300@27
|
115
|
rt300@27
|
116 return true; // ???
|
rt300@27
|
117 }
|
rt300@27
|
118 }
|
rt300@27
|
119 //-----------------------------
|
rt300@27
|
120 void EventLogger::urlResponse(ofHttpResponse & response){
|
rt300@27
|
121 cout << "gotHTTPRequestStatus\n";
|
rt300@27
|
122 cout << "HTTP REQUEST NAME " << response.request.name << "\n";
|
rt300@27
|
123 cout << "HTTP STATUS " << response.status << "\n";
|
rt300@27
|
124 cout << "HTTP ERROR " << response.error << "\n";
|
rt300@27
|
125 cout << "HTTP DATA " << response.data << "\n"; // ofBuffer
|
rt300@9
|
126
|
rt300@27
|
127 bool sent;
|
rt300@27
|
128 stringstream respStr;
|
rt300@27
|
129 respStr << response.data;
|
rt300@22
|
130
|
rt300@27
|
131 if (response.status == 200){
|
rt300@27
|
132 if(respStr.str() == "OK"){
|
rt300@22
|
133
|
rt300@22
|
134 sent = true;
|
rt300@22
|
135 }else{
|
rt300@22
|
136 // not ok
|
rt300@22
|
137 // problem serverside
|
rt300@22
|
138 sent = false;
|
rt300@22
|
139 }
|
rt300@9
|
140 }else{
|
rt300@22
|
141
|
rt300@22
|
142 sent = false;
|
rt300@9
|
143 // SHOW AN ALERT TO USER?
|
rt300@9
|
144 }
|
rt300@27
|
145
|
rt300@27
|
146 // now do request specific stuff
|
rt300@27
|
147 if(response.request.name == "eventlog"){
|
rt300@27
|
148 if(!sent){
|
rt300@27
|
149 // try later
|
rt300@27
|
150 nextUploadQty += UPLOAD_CHUNK_SIZE;
|
rt300@27
|
151 }else{
|
rt300@27
|
152
|
rt300@27
|
153 // if success - clear memory
|
rt300@27
|
154 theEvents.clear();
|
rt300@27
|
155 cout << "UPLOAD SUCCESS\n";
|
rt300@27
|
156 nextUploadNumber++;
|
rt300@27
|
157 }
|
rt300@27
|
158 logUploadInProgress = false;
|
rt300@27
|
159 }else if(response.request.name == "questionnaire"){
|
rt300@27
|
160 if(sent){
|
rt300@27
|
161 questionnaireUploaded = true;
|
rt300@27
|
162 }else{
|
rt300@27
|
163 questionnaireUploaded = false; // will try next time... when?
|
rt300@27
|
164 }
|
rt300@27
|
165 }else if(response.request.name == "testConnection"){
|
rt300@27
|
166
|
rt300@27
|
167 if (sent){
|
rt300@27
|
168 cout << "^^^^^^^^ server connection OK ^^^^^^^^ \n";
|
rt300@27
|
169 serverConnectionOK = true;
|
rt300@27
|
170 }else{
|
rt300@27
|
171 cout << "server connection ERROR \n";
|
rt300@27
|
172 }
|
rt300@27
|
173 }
|
rt300@27
|
174
|
rt300@22
|
175 }
|
rt300@22
|
176 //---------------------------------------------------------------------------
|
rt300@22
|
177 bool EventLogger::testConnection(){
|
rt300@22
|
178 Json::Value root;
|
rt300@22
|
179 root["test"] = "test";
|
rt300@22
|
180
|
rt300@22
|
181
|
rt300@27
|
182 sendToServer("testConnection", root, true);
|
rt300@27
|
183
|
rt300@9
|
184 }
|
rt300@9
|
185 //---------------------------------------------------------------------------
|
rt300@8
|
186 void EventLogger::readJsonToLog(const string &jsonFile){
|
rt300@8
|
187 Json::Value root;
|
rt300@8
|
188 Json::Reader reader;
|
rt300@5
|
189
|
rt300@5
|
190
|
rt300@8
|
191 ifstream theFile(jsonFile.c_str());
|
rt300@8
|
192 stringstream fileText;
|
rt300@8
|
193 string line;
|
rt300@8
|
194 if(!theFile){
|
rt300@8
|
195
|
rt300@8
|
196 firstEverAppOpen();
|
rt300@8
|
197
|
rt300@8
|
198 return;
|
rt300@8
|
199 }else{
|
rt300@8
|
200 while(theFile){
|
rt300@8
|
201 theFile >> line;
|
rt300@9
|
202 // cout << line; // lots!!!!
|
rt300@8
|
203 fileText << line;
|
rt300@8
|
204 }
|
rt300@8
|
205 theFile.close();
|
rt300@8
|
206 }
|
rt300@8
|
207
|
rt300@9
|
208 cout << "size of log JSON string:" << fileText.str().length() << "BYTES \n";
|
rt300@9
|
209
|
rt300@8
|
210 bool parsingSuccessful = reader.parse( fileText.str(), root );
|
rt300@8
|
211
|
rt300@8
|
212 if ( !parsingSuccessful )
|
rt300@8
|
213 {
|
rt300@8
|
214 // report to the user the failure and their locations in the document.
|
rt300@22
|
215 std::cout << "Failed to parse event log JSON: \n"
|
rt300@8
|
216 << reader.getFormattedErrorMessages();
|
rt300@8
|
217 return;
|
rt300@8
|
218 }
|
rt300@8
|
219
|
rt300@8
|
220 // now put user deets into variables
|
rt300@8
|
221 userName = root["userName"].asString();
|
rt300@8
|
222 deviceID = root["deviceID"].asLargestInt();
|
rt300@25
|
223 nextUploadNumber = root["uploadNumber"].asInt();
|
rt300@25
|
224 savedInteractionTime = root["savedInteractionTime"].asLargestInt();
|
rt300@22
|
225 questionnaireCompleted = root["questionnaireCompleted"].asBool();
|
rt300@22
|
226 questionnaireUploaded = root["questionnaireUploaded"].asBool();
|
rt300@22
|
227
|
rt300@22
|
228
|
rt300@22
|
229 if(questionnaireCompleted && !questionnaireUploaded){
|
rt300@22
|
230 // then read it in and upload it
|
rt300@22
|
231 Json::Value JArray = root["questionnaireAnswers"];
|
rt300@22
|
232 if(JArray.size() < 2){
|
rt300@22
|
233 cout << "Error - status of questionnaire is wierd\n";
|
rt300@22
|
234 }
|
rt300@22
|
235 for ( unsigned int i = 0; i < JArray.size(); i++ )
|
rt300@22
|
236 {
|
rt300@22
|
237 questionnaireAnswers.push_back(JArray[1].asInt());
|
rt300@22
|
238 }
|
rt300@22
|
239 uploadQuestionnaire();
|
rt300@22
|
240 }
|
rt300@8
|
241
|
rt300@8
|
242 // check for unuploaded evts
|
rt300@8
|
243 const Json::Value jlogs = root["events"];
|
rt300@8
|
244
|
rt300@8
|
245 for ( int index = 0; index < jlogs.size(); ++index ) theEvents.push_back(lEvent(jlogs[index]));
|
rt300@27
|
246 if(theEvents.size() > nextUploadQty && ! logUploadInProgress){
|
rt300@8
|
247 //try to upload
|
rt300@27
|
248 uploadEventLog(true);
|
rt300@8
|
249 }
|
rt300@8
|
250 // TODO if the total interaction time is greater than a certain amount && no questions answered - questionnaire time!
|
rt300@25
|
251 cout << "Total interaction time: " << savedInteractionTime << '\n';
|
rt300@9
|
252
|
rt300@8
|
253
|
rt300@9
|
254 }
|
rt300@9
|
255
|
rt300@9
|
256
|
rt300@9
|
257 //---------------------------------------------------------------------------
|
rt300@9
|
258
|
rt300@27
|
259 bool EventLogger::uploadEventLog(bool async){
|
rt300@22
|
260 // show indicator
|
rt300@27
|
261 logUploadInProgress = true;
|
rt300@25
|
262 cout << "^^^^^^^^ ATTEMPTING TO UPLOAD " << theEvents.size() << " EVENTS ^^^^^^^^ .\n";
|
rt300@27
|
263 if(!async){
|
rt300@27
|
264 bool success = sendToServer("eventlog", logsToJson(), async);
|
rt300@27
|
265 if(!success){
|
rt300@27
|
266 // try later
|
rt300@27
|
267 nextUploadQty += UPLOAD_CHUNK_SIZE;
|
rt300@27
|
268 }else{
|
rt300@27
|
269
|
rt300@27
|
270 // if success - clear memory
|
rt300@27
|
271 theEvents.clear();
|
rt300@27
|
272 cout << "UPLOAD SUCCESS\n";
|
rt300@27
|
273 nextUploadNumber++;
|
rt300@27
|
274 }
|
rt300@27
|
275 logUploadInProgress = false;
|
rt300@27
|
276 return success;
|
rt300@9
|
277 }else{
|
rt300@27
|
278 sendToServer("eventlog", logsToJson(), async);
|
rt300@9
|
279 }
|
rt300@1
|
280 }
|
rt300@8
|
281 //----------------------------------------------------------------------------
|
rt300@27
|
282
|
rt300@27
|
283 //----------------------------------------------------------------------------
|
rt300@9
|
284 //void EventLogger::deleteLogFile(){
|
rt300@8
|
285
|
rt300@8
|
286 //---------------------------------------------------------------------------
|
rt300@8
|
287
|
rt300@8
|
288 void EventLogger::firstEverAppOpen(){
|
rt300@25
|
289 cout<<"no event log file - first APP open\n";
|
rt300@25
|
290 nextUploadNumber = 0;
|
rt300@8
|
291 deviceID = ofGetSystemTimeMicros();
|
rt300@25
|
292 savedInteractionTime = 0;
|
rt300@22
|
293 questionnaireCompleted = false;
|
rt300@22
|
294 questionnaireUploaded = false;
|
rt300@8
|
295
|
rt300@24
|
296 ((testApp *)ofGetAppPtr())->showIntro();
|
rt300@25
|
297 consentGiven = false;
|
rt300@8
|
298
|
rt300@8
|
299 }
|
rt300@27
|
300 void EventLogger::newUser(){
|
rt300@27
|
301 cout<<"setup new user\n";
|
rt300@27
|
302 nextUploadNumber = 0;
|
rt300@27
|
303 deviceID = ofGetSystemTimeMicros();
|
rt300@27
|
304 savedInteractionTime = 0;
|
rt300@27
|
305 questionnaireCompleted = false;
|
rt300@27
|
306 questionnaireUploaded = false;
|
rt300@27
|
307 consentGiven = true; // other wise we wouldn't be doing this
|
rt300@27
|
308 ((testApp *)ofGetAppPtr())->introHidden(true); // hacky
|
rt300@27
|
309
|
rt300@27
|
310 }
|
rt300@8
|
311 //---------------------------------------------------------------------------
|
rt300@8
|
312 // called from alertView OK in iViewController
|
rt300@8
|
313 void EventLogger::setUsername(const char *u){
|
rt300@8
|
314 userName = u;
|
rt300@7
|
315
|
rt300@7
|
316 }
|
rt300@8
|
317
|
rt300@8
|
318 //---------------------------------------------------------------------------
|
rt300@8
|
319 // log zoom event
|
rt300@5
|
320 void EventLogger::logEvent(const leventType& evtType,const TwoVector& centre, const double& scale, const int& sliderID, const double& sliderVal){
|
rt300@3
|
321 //cout << "log: " << evtType << "\n";
|
rt300@1
|
322
|
rt300@1
|
323 // scroll has 2 double coords
|
rt300@1
|
324 // zoom has 1 double scale
|
rt300@1
|
325 // save preset has 2 coords
|
rt300@1
|
326 // switch view has view type
|
rt300@9
|
327 // slider change has int slider index and 1 float value
|
rt300@1
|
328
|
rt300@4
|
329 // get time for key index
|
rt300@4
|
330
|
rt300@5
|
331 // thinFactor
|
rt300@5
|
332 if(!loggingEnabled) return;
|
rt300@4
|
333 switch ( evtType ) {
|
rt300@4
|
334 case SAVE_PRESET:
|
rt300@5
|
335 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@4
|
336 // Code
|
rt300@4
|
337 break;
|
rt300@4
|
338 case SAVE_DESET:
|
rt300@5
|
339 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@4
|
340 break;
|
rt300@4
|
341 case SCROLL:
|
rt300@5
|
342 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@5
|
343 break;
|
rt300@5
|
344 case SCROLL_STOPPED:
|
rt300@5
|
345 theEvents.push_back(lEvent(evtType,centre.x,centre.y));
|
rt300@22
|
346 cout << "SCROLL STOPPED EVENT\n";
|
rt300@22
|
347 break;
|
rt300@22
|
348 case SNAPPED_TO_PRESET:
|
rt300@22
|
349 theEvents.push_back(lEvent(evtType,centre.x,centre.y,sliderID));
|
rt300@22
|
350 cout << "SCROLL STOPPED EVENT\n";
|
rt300@4
|
351 break;
|
rt300@4
|
352 case ZOOM:
|
rt300@5
|
353 theEvents.push_back(lEvent(evtType,scale));
|
rt300@4
|
354 break;
|
rt300@4
|
355 case CHANGE_SLIDER:
|
rt300@5
|
356 theEvents.push_back(lEvent(evtType,sliderVal , 0.0 , sliderID));
|
rt300@4
|
357 break;
|
rt300@25
|
358 case SWAP_VIEW:
|
rt300@25
|
359 theEvents.push_back(lEvent(evtType,0.0 , 0.0 , sliderID)); // slider ID is which view
|
rt300@25
|
360 break;
|
rt300@4
|
361 default:
|
rt300@25
|
362 // default is just an event type with no values
|
rt300@25
|
363 theEvents.push_back(lEvent(evtType));
|
rt300@4
|
364 break;
|
rt300@1
|
365 }
|
rt300@27
|
366 if(theEvents.size() > nextUploadQty && !logUploadInProgress){
|
rt300@27
|
367 //try to upload asynchronously
|
rt300@27
|
368 uploadEventLog(true);
|
rt300@7
|
369 }
|
rt300@9
|
370 //sessionTime = (ofGetSystemTime() - sessionStartTime);
|
rt300@25
|
371 totalInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime);
|
rt300@25
|
372 if(totalInteractionTime > QUESTIONNAIRE_ENABLE_TIME){
|
rt300@25
|
373 TopButtonViewController *tbvc = ((testApp *)ofGetAppPtr())->topButtonViewController;
|
rt300@25
|
374 [tbvc enableQuestionButton];
|
rt300@25
|
375 }
|
rt300@1
|
376 }
|
rt300@8
|
377
|
rt300@8
|
378 //---------------------------------------------------------------------------
|
rt300@7
|
379
|
rt300@7
|
380 void EventLogger::exitAndSave(){
|
rt300@25
|
381
|
rt300@25
|
382 if(!consentGiven){
|
rt300@25
|
383 logEvent(CONSENT_DENIED);
|
rt300@25
|
384 Json::Value jlogs = logsToJson();
|
rt300@25
|
385 // try to upload TODO (no - might hang and prevent exit???)
|
rt300@27
|
386 uploadEventLog(true);
|
rt300@25
|
387 return;
|
rt300@25
|
388 }
|
rt300@25
|
389 logEvent(APP_EXITED);
|
rt300@25
|
390 savedInteractionTime = savedInteractionTime + (ofGetSystemTime() - sessionStartTime);
|
rt300@7
|
391 // save user details
|
rt300@8
|
392 string fname = ofxiPhoneGetDocumentsDirectory() + EVENT_LOG_FILENAME;
|
rt300@8
|
393
|
rt300@25
|
394 // try to upload TODO (no - might hang and prevent exit???)
|
rt300@27
|
395 // do it async because event list needs to be cleared to prevent saving on device
|
rt300@27
|
396 uploadEventLog(false);
|
rt300@7
|
397
|
rt300@8
|
398 // write to file
|
rt300@25
|
399 // json without the logs that were uploaded!
|
rt300@25
|
400 Json::Value jlogs = logsToJson();
|
rt300@8
|
401 ofFile logFile(fname,ofFile::WriteOnly);
|
rt300@8
|
402 logFile << jlogs;
|
rt300@8
|
403
|
rt300@8
|
404 }
|
rt300@8
|
405 //---------------------------------------------------------------------------
|
rt300@8
|
406
|
rt300@8
|
407 Json::Value EventLogger::logsToJson(){
|
rt300@8
|
408 // put all logged events into Json formatted string
|
rt300@8
|
409 Json::Value root;
|
rt300@8
|
410
|
rt300@8
|
411 vector<lEvent>::iterator eventIter;
|
rt300@8
|
412
|
rt300@22
|
413 root["programVersion"] = PROGRAM_VERSION;
|
rt300@8
|
414 root["userName"] = userName;
|
rt300@8
|
415 root["deviceID"] = deviceID;
|
rt300@25
|
416 root["uploadNumber"] = nextUploadNumber;
|
rt300@22
|
417 root["iOSdeviceType"] = iOSdeviceType;
|
rt300@25
|
418 root["savedInteractionTime"] = savedInteractionTime;
|
rt300@22
|
419 root["questionnaireCompleted"] = questionnaireCompleted;
|
rt300@22
|
420 root["questionnaireUploaded"] = questionnaireUploaded;
|
rt300@22
|
421 if(questionnaireCompleted && !questionnaireUploaded){
|
rt300@22
|
422 root["qAnswers"] = questionnaireToJson();
|
rt300@22
|
423 }
|
rt300@8
|
424
|
rt300@8
|
425 int i = 0;
|
rt300@8
|
426 for(eventIter = theEvents.begin(); eventIter < theEvents.end(); eventIter++){
|
rt300@8
|
427 root["events"][i] = (*eventIter).eventToJson();
|
rt300@8
|
428 i++;
|
rt300@7
|
429 }
|
rt300@25
|
430 root["numEventsHere"] = i;
|
rt300@8
|
431 return root;
|
rt300@8
|
432 }
|
rt300@22
|
433
|
rt300@8
|
434 //---------------------------------------------------------------------------
|
rt300@22
|
435
|
rt300@22
|
436 Json::Value EventLogger::questionnaireToJson(){
|
rt300@22
|
437 // put all answers into Json formatted string
|
rt300@22
|
438 Json::Value root;
|
rt300@22
|
439
|
rt300@22
|
440 vector<int>::iterator aIter;
|
rt300@22
|
441
|
rt300@22
|
442 Json::Value questionnaire;
|
rt300@22
|
443
|
rt300@22
|
444 int i = 0;
|
rt300@22
|
445 for(aIter = questionnaireAnswers.begin(); aIter < questionnaireAnswers.end(); aIter++){
|
rt300@22
|
446 questionnaire[i] = (*aIter);
|
rt300@22
|
447 i++;
|
rt300@22
|
448 }
|
rt300@22
|
449
|
rt300@22
|
450 root["qAnswers"] = questionnaire;
|
rt300@22
|
451 root["userName"] = userName;
|
rt300@22
|
452 root["deviceID"] = deviceID;
|
rt300@22
|
453 root["iOSdeviceType"] = iOSdeviceType;
|
rt300@22
|
454 root["programVersion"] = PROGRAM_VERSION;
|
rt300@22
|
455
|
rt300@22
|
456 return root;
|
rt300@22
|
457 }
|
rt300@8
|
458 //---------------------------------------------------------------------------
|
rt300@8
|
459 //---------------------------------------------------------------------------
|
rt300@22
|
460 //---------------------------------------------------------------------------
|