Today's Menu  Portugal
journal and plan nutrition
Z5RemoteDataController.m
Go to the documentation of this file.
1 //
2 // Z5RemoteDataController.m
3 // Z7Ma2AminoLight
4 //
5 // Created by Don Zeek on 11/12/14.
6 // Copyright (c) 2014 net.dzeek.y2014.ios.aminoview. All rights reserved.
7 //
8 
10 
11 // #import "GTLUtilities.h"
12 // #import "GTMHTTPFetcherLogging.h"
13 
14 // #import "Z5GoogleProvided.h"
15 #import "Z5DataController.h"
16 #import "NSString+MD5.h"
17 #import "NSData+MD5.h"
20 
21 #pragma mark -
22 #pragma mark Proxy delegate
23 
28 /*
29 @interface Z5RemoteDataDriveDelegate : NSObject <Z5RemoteDataFetchProtocol>
30 @property (nonatomic, strong) NSMutableArray *who;
31 @property (nonatomic, strong) Z5RemoteDataController *remoteDataController;
32 @end
33 
34 @implementation Z5RemoteDataDriveDelegate
35 {
36  BOOL kHomeAsk;
37  BOOL kHomeError;
38  GTLDriveFile *kHomeResult;
39  BOOL kFetchAsk;
40  BOOL kFetchError;
41  NSArray *kFetchResults;
42  BOOL kPublishAsk;
43  BOOL kPublishError;
44  id<Z5RemoteDataFetchProtocol> kController;
45 }
46 - (instancetype)initWith: (id<Z5RemoteDataFetchProtocol>)controller
47 {
48  self = [super init];
49  if (self) {
50  // NSLog(@"Z5RemoteDataDriveDelegate.init");
51  kHomeAsk = NO;
52  kHomeError = NO;
53  kHomeResult = nil;
54  kFetchAsk = NO;
55  kFetchError = NO;
56  kFetchResults = nil;
57  kPublishAsk = NO;
58  kPublishError = NO;
59  kController = controller;
60  }
61  return self;
62 
63 }
64 - (void) showHomeAsk
65 {
66  kHomeAsk = YES;
67  [kController showHomeAsk];
68 }
69 - (void) showHomeError:(NSError *) error
70 {
71  // NSLog(@"RemoteData/Z5RemoteDataDriveDelegate.showHomeError: %@", [error localizedDescription]);
72  kHomeError = YES;
73  [kController showHomeError:error];
74 }
75 - (BOOL) tellHomeError
76 {
77  [kController tellHomeError];
78  return kHomeError;
79 }
80 - (void) showHomeResult:(GTLDriveFile *)drivefile
81 {
82  kHomeResult = drivefile;
83  [kController showHomeResult:drivefile];
84  [[self remoteDataController] homeResultAvailable];
85 }
86 - (GTLDriveFile *) tellHomeResult
87 {
88  return kHomeResult;
89 }
90 
91 - (void) showFetchAsk
92 {
93  kFetchAsk = YES;
94  [kController showFetchAsk];
95 }
96 - (void) showFetchError
97 {
98  kFetchError = YES;
99  [kController showFetchError];
100 }
101 - (void) showFetchResult: (NSArray *)filen
102 {
103  kFetchResults = filen; // may need to create my own copy
104  [kController showFetchResult:filen];
105 }
106 - (void) showPublishAsk
107 {
108  kPublishAsk = YES;
109  [kController showPublishAsk];
110 }
111 - (void) showPublishError
112 {
113  kPublishError = YES;
114  [kController showPublishError];
115 }
116 - (void) showPublishResult
117 {
118  [kController showPublishResult];
119 }
120 - (void) showDataFetch:(NSData *)data
121 {
122  [kController showDataFetch:data];
123 }
124 - (void) showDataFetch:(NSData *)data fromFile: (NSString *)title withGoogleId: (NSString *)fileId
125 {
126  [kController showDataFetch:data fromFile:title withGoogleId:fileId];
127 }
128 - (void) showGoogleFileTitle: (NSString *) title andId: (NSString *) fileId
129 {
130  [kController showGoogleFileTitle:title andId:fileId];
131 }
132 - (void) showInsertResult: (GTLDriveFile *)newf
133 {
134  [kController showInsertResult: newf];
135 }
136 - (void) updateUI
137 {
138  // NSLog(@"RemoteData/Z5RemoteDataDriveDelegate.updateUI");
139  [kController updateUI];
140 }
141 @end
142 */
143 
153 #pragma mark -
154 #pragma mark Remote Data Control
155 
156 @interface Z5RemoteDataController ()
157 
158 @property (nonatomic, readonly) UINavigationController *kNavigator;
159 
160 @end
161 
162 @implementation Z5RemoteDataController
163 
164 
166 NSString *const kKeychainItemName = @"Todays-Menu:Google";
167 
168 - (instancetype)init
169 {
170  self = [super init];
171  if (self) {
172  _loginController = [[Z5GoogleLoginController alloc] init];
173  _emailController = [[Z5GmailDataController alloc] init];
174  _driveController = [[Z5GoogleDriveController alloc] init];
175  _calendarController = [[Z5GoogleCalendarDataController alloc] init];
176  _sessionController = [[Z5URLSessionController alloc] init];
177 
178  [_loginController configureGoogleSignIn];
179  GIDSignIn* signIn = [GIDSignIn sharedInstance];
180  if (nil != [_loginController signedInUsername]) {
181  [signIn signInSilently];
182  }
183  }
184  return self;
185 }
186 #pragma mark -
187 
192 - (void)loginDriveWithNavigation: (UINavigationController *)nav andHandler: (void (^)(void)) finishHandler
193 {
194  NSLog(@"MemoteData.logWithNavigation:withHandler");
195  assert(nil); // old version, not exercised
196  _kNavigator = nav;
197  if (nav) {
198  [self signInNowWithHandler:finishHandler];
199  } else {
200  NSLog(@"RemoteData.logWithNavigation:withHandler: ERROR");
201  }
202 }
208 
209  // TODO: Get the saved authentication, if any, from the keychain.
210  /*
211  GTMOAuth2Authentication *auth;
212  auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
213  clientID:clientID
214  clientSecret:clientSecret];
215 
216  // Retain the authentication object, which holds the auth tokens
217  //
218  // We can determine later if the auth object contains an access token
219  // by calling its -canAuthorize method
220  [self setAuthentication:auth];
221  */
222 }
223 
227 - (BOOL)isSignedIn {
228  NSString *name = [_loginController signedInUsername];
229  return (name != nil);
230 }
231 
232 
233 - (void)signInNowWithHandler: (void (^)(void)) finishHandler
234 {
235  if (![self isSignedIn]) {
236  // Sign in
237  [self runSigninThenHandler:finishHandler];
238  } else {
239  // Sign out
240 
241 // GTLServiceDrive *service = self.driveService;
242 //
243 // [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
244 // service.authorizer = nil;
245 
246  [self updateUI];
247  }
248 }
249 
251  if (![self isSignedIn]) {
252  // Sign in
253  [self runSigninThenHandler:^{
254  // [self updateUI];
255  }];
256  } else {
257  // Sign out
258 
259 // GTLServiceDrive *service = self.driveService;
260 //
261 // [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
262 // service.authorizer = nil;
263 
264  // [self updateUI];
265  }
266 }
267 
268 - (IBAction)logOffGoogleDrive
269 {
270  /*
271  [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
272  [GTMOAuth2ViewControllerTouch revokeTokenForGoogleAuthentication:class_auth];
273  */
274 }
275 
276 
277 
278 #pragma mark -
279 #pragma mark Sign In
280 
281 - (void)runSigninThenHandler:(void (^)(void))handler {
282  assert(nil);
283 }
284 
285 
286 #pragma mark Remote Home and List Access
287 
300 - (void)initializeAvailableWithDelegate: (id<Z5RemoteDataFetchProtocol>) delegate
301 {
302  [self refreshAuthentication];
303  NSLog(@"RemoteData.initializeAvailable, %@", ([self isSignedIn]?@"signed in":@"Logged Off"));
304  if ([self isSignedIn]) {
305 
306  /*
307  homeRequestDelegate = [[Z5RemoteDataDriveDelegate alloc] initWith:delegate];
308  [homeRequestDelegate setRemoteDataController:self];
309  [self queryHomeDirectoryInfoWithDelegate:homeRequestDelegate];
310  */
311  }
312 }
313 
320 {
321  // NSLog(@"RemaoteData.homeResultAvailable: calling for file list, home id: %@",
322  //[[homeRequestDelegate tellHomeResult] identifier]);
323  // [self queryFileListWithDelegate:homeRequestDelegate];
324 }
325 
326 
327 - (void)updateUI
328 {
329  /*
330  if (homeRequestDelegate) {
331  [homeRequestDelegate updateUI];
332  }
333  */
334 }
335 
336 /*
337 // this shoudlbe in Z5DataController
338 - (void)displayAlert:(NSString *)title format:(NSString *)format, ... {
339  NSString *result = format;
340  if (format) {
341  va_list argList;
342  va_start(argList, format);
343  result = [[NSString alloc] initWithFormat:format
344  arguments:argList];
345  va_end(argList);
346  }
347 
348  // UIAlertView *uav = [[UIAlertView alloc] initWithTitle:title message:result delegate:self cancelButtonTitle:@"OK/cancel" otherButtonTitles:nil];
349  // [uav show];
350 
351 
352  UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert"
353  message:@"This is an alert."
354  preferredStyle:UIAlertControllerStyleAlert];
355 
356  UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
357  handler:^(UIAlertAction * action) {}];
358 
359  [alert addAction:defaultAction];
360  [self presentViewController:alert animated:YES completion:nil];
361  }
362 */
363 
364 
365 
366 
367 #pragma mark - find-or-create home directory, from Coord-Medic-Rove/ZCMRemoteDataController
368 #pragma mark Home and MainData access
369 /*
370 - (GTLDriveFile *) homeDirectoryDriveFile
371 {
372  return [homeRequestDelegate tellHomeResult];
373 }
374 */
380 - (void) queryHomeDirectoryInfoWithDelegate: (id<Z5RemoteDataFetchProtocol>) delegate
381 {
382  /*
383  GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
384 
385  query.q = @"'root' in parents and title = 'NutritionSummary'";
386  query.maxResults = 150;
387  __block NSString *ret = @"none";
388 
389  // NSLog(@"RemoteData.queryHomeDirectoryInfo: execute query");
390  [delegate showHomeAsk];
391  // GTLServiceTicket *fileListTicket =
392  [self.driveService executeQuery:query
393  completionHandler:^(GTLServiceTicket *ticket,
394  GTLDriveFileList *fileList,
395  NSError *error) {
396 
397  // NSLog(@"RemoteData.queryHomeDirectoryInfo: nserror: %@", error);
398  if (nil == error) {
399  Boolean homeDirectoryFound = NO;
400 
401  for (GTLDriveFile *fil in fileList) {
402  if (![[fil.labels trashed] boolValue]) {
403  if ([[fil title] compare:@"NutritionSummary"] == NSOrderedSame) {
404  // NSLog(@"RemoteData.queryHomeDirectoryInfo: have home result: %@", delegate);
405  GTLDateTime *homeCreateDateTime = [fil createdDate];
406  ret = [[NSString alloc] initWithFormat:@"Home created: %@",[homeCreateDateTime stringValue]];
407  self.homeCreateDateTime3339 = [homeCreateDateTime stringValue];
408  self.homeDirectoryFileId = [fil identifier];
409 
410  homeDirectoryFound = YES;
411  [delegate showHomeResult:fil];
412  }
413  }
414  }
415  if (homeDirectoryFound) {
416  // NSLog(@"RemoteData.queryHomeDirectoryInfo/executeQuery: Finished home creation time check: ret: %@", ret);
417  // [self fetchMainDataInfo];
418  } else {
419  NSLog(@"RemoteData.queryHomeDirectoryInfo/executeQuery: Need to create NutritionSummary folder");
420 
421  // [self createHomeDirectoryFolder];
422  // moving code into this function
423  // allows getting delegate, however this is untested yet
424 
425  void (^w30HomeDirectory)(GTLServiceTicket *ticket,
426  GTLDriveFile *insertedFile, NSError *error) = ^(GTLServiceTicket *ticket,
427  GTLDriveFile *insertedFile, NSError *error) {
428  if (error == nil) {
429  // Uncomment the following line to print the File ID.
430  NSLog(@"RemoteData.w30HomeDirectory: Folder ID: %@", insertedFile.identifier);
431  // completionBlock(insertedFile, nil);
432  [self setHomeDirectoryFileId:insertedFile.identifier];
433 
434  [delegate showHomeResult:insertedFile];
435 
436  } else {
437  NSLog(@"RemoteData.w30HomeDirectory: error occurred: %@", error);
438  // completionBlock(nil, error);
439  }
440  };
441  NSLog(@"RemoteData.createHomeDirectoryFolder: GOOD LUCK last time -- IT WORKED FIRST TIME!!");
442  [self createFolderOnDrive:mainFolderName withBlock:w30HomeDirectory];
443 
444  }
445  } else {
446  [delegate showHomeError:error];
447  }
448  }
449  ];
450  */
451 }
452 
453 
454 // TODO: connect firebase
455 /*
456 -(void)createFolderOnDrive: (NSString *)name withBlock:(void(^)(GTLServiceTicket *ticket, GTLDriveFile *insertedFile, NSError *error))finalFix
457 {
458  [self createFolderOnDrive:name inDirectory:nil withBlock:finalFix];
459 }
460 -(void)createFolderOnDrive: (NSString *)name inDirectory: (NSString *)parentID withBlock:(void(^)(GTLServiceTicket *ticket, GTLDriveFile *insertedFile, NSError *error))finalFix
461 {
462 
463  GTLDriveFile *file = [GTLDriveFile object];
464  NSString *mimeType = @"application/vnd.google-apps.folder";
465  file.title = name; // @"CoordinatedMedicine";
466  file.descriptionProperty = @"folder for cloud app data";
467  file.mimeType = mimeType;
468  if (parentID.length && ![parentID isEqualToString:@"0"]) {
469  GTLDriveParentReference *parentRef = [GTLDriveParentReference object];
470  parentRef.identifier = parentID;
471  file.parents = [NSArray arrayWithObject:parentRef];
472  }
473 
474 
475  GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:file
476  uploadParameters:nil];
477 
478  // queryTicket can be used to track the status of the request, more information can
479  // be found on https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Uploading_Files
480  // GTLServiceTicket *queryTicket =
481  [self.driveService executeQuery:query completionHandler:finalFix];
482 
483 
484 }
485 */
487 {
488  // NSLog(@"RemoteData.isHomeInfoError: reporting %@", ([homeRequestDelegate tellHomeError]? @"error" : @"all good"));
489  // return [homeRequestDelegate tellHomeError];
490  return NO;
491 }
497 - (void) queryFileListWithDelegate:(id<Z5RemoteDataFetchProtocol>) delegate
498 {
499  /*
500  if ([homeRequestDelegate tellHomeError]) {
501  NSLog(@"RemoteData.queryFileListWithDelegate: HOME ERROR, NO-OP");
502  return;
503  }
504 
505  GTLServiceDrive *service = self.driveService;
506 
507 
508  // NSString *homeId = [[delegate tellHomeResult] identifier];
509  // NSLog(@"RemoteData.queryFileListWithDelegate: service: %@ home-id: %@", service, homeId);
510 
511  GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
512 
513  // maxResults specifies the number of results per page. Since we earlier
514  // specified shouldFetchNextPages=YES, all results should be fetched,
515  // though specifying a larger maxResults will reduce the number of fetches
516  // needed to retrieve all pages.
517  query.maxResults = 150;
518  */
519 
531  /*
532  [delegate showFetchAsk];
533 
534  // _fileListTicket =
535  [service executeQuery:query
536  completionHandler:^(GTLServiceTicket *ticket,
537  GTLDriveFileList *fileList,
538  NSError *error) {
539  // Callback
540  _fileList = fileList;
541  _fileListFetchError = error;
542  // _fileListTicket = nil;
543 
544  if (nil == error) {
545 
546  [delegate showFetchResult:[fileList items]];
547 
548  } else {
549  [delegate showFetchError];
550  }
551 
552  [delegate updateUI];
553  }];
554  */
555 }
556 
561 - (void) updateOrInsertMenuItemListOnDriveWithDelegate:(id<Z5RemoteDataFetchProtocol>) delegate
562 {
563  /*
564  GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
565 
566  NSString *queryString = [[NSString alloc] initWithFormat:@"'%@' in parents", [self homeDirectoryFileId]];
567  NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate queryString: %@", queryString);
568  query.q = queryString;
569  query.maxResults = 150;
570 
571  [delegate showPublishAsk];
572 */
576  // This first search should give me CoordinatedMedicine (by fileId),
577  // and all the 'name' ("coordmedic.json") data-file (also by fileId).
578  // Then look through name-file-list for GTLDriveFile-s with folder in parents
579 
580  // Auxiliary search would show parents for all name data-files. No, there are no more data-files,
581  // the shared files are elsewhere.
582 
583  // Auxiliary search first? After completion of file search (all files this app)
584  // update data file by [self updateDriveFile];
585  // OR create the file in the [self homeDirectoryFileId] folder
586  // GTLServiceTicket *fileListTicket =
587  /*
588  [self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
589  GTLDriveFileList *fileList,
590  NSError *error) {
591  if (error) {
592  [delegate showPublishError];
593  } else {
594  [delegate showPublishResult];
595  for (GTLDriveFile *file in fileList) {
596  NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: file in home: %@", [file title]);
597  }
598 
599  NSArray *names = [[NSArray alloc] initWithObjects:@"Leucine" , @"Arginine", nil];
600  for (NSString *name in names) {
601  NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: name: %@", name);
602  }
603 
604 
605 
606 
607 // [self fillMenuItemList];
608 // for (MenuItem *m5mo in [self menuItemsList]) {
609 // [self updateOrInsertMenuItem:m5mo onDrive: (GTLDriveFileList *) fileList withDelegate:delegate];
610 // } // END -- for MenuItem in list
611 
612 
613 
614  } // END -- if no error
615  }];
616  */
617 }
618 
624 - (void) insertMenuItem: (MenuItem *)m5mo withDelegate: (id <Z5RemoteDataFetchProtocol>)delegate
625 {
626  /* TODO: hook firebase
627 
628  NSString *newStr = [m5mo bodytext];
629  NSData* data = [newStr dataUsingEncoding:NSUTF8StringEncoding];
630 
631  // after check is complete, regardless, put up data file
632  GTLDriveFile *file = [GTLDriveFile object];
633 
634  NSString *newFileName; // = [[m5mo name] stringByAppendingString:@".mol"];
635  NSString *menuItemName = [m5mo name];
636  if ([menuItemName containsString:@".mol"]) {
637  newFileName = menuItemName;
638  } else if ([menuItemName containsString:@".pdb"]) {
639  newFileName = menuItemName;
640  } else if ([[m5mo bodytext] containsString:@"HEADER"]) {
641  newFileName = [[m5mo name] stringByAppendingString:@".pdb"];
642  } else {
643  newFileName = [[m5mo name] stringByAppendingString:@".mol"];
644  }
645 
646  file.title = newFileName;
647  file.descriptionProperty = @"Uploaded Menu-Item";
648  file.mimeType = @"text/plain"; // @"image/png";
649 
650  GTLDriveParentReference *newParent = [GTLDriveParentReference object];
651  newParent.identifier = [self homeDirectoryFileId];
652  file.parents = [NSArray arrayWithObject:newParent];
653 
654  // where is my new file id?
655  [self postData:data toNewGoogleDriveFile:file withDelegate:delegate];
656  */
657 }
658 
670 //- (void) updateOrInsertMenuItem: (MenuItem *) m5mo onDrive: (GTLDriveFileList *)fileList withDelegate:(id<Z5RemoteDataFetchProtocol>) delegate
671 //{
672 // // NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: generate file for %@", [m5mo name]);
673 // NSString *newFileName = [[m5mo name] stringByAppendingString:@".mol"];
674 // Boolean found_flag = NO;
675 // GTLDriveFile *found_file = nil;
676 //
677 // found_flag = NO;
678 // found_file = nil;
679 // for (GTLDriveFile *file in fileList) {
680 // if ([[file title] isEqualToString:newFileName]) {
681 // // NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: remote file: %@", [file title]);
682 // found_flag = YES;
683 // found_file = file;
684 // break;
685 // }
686 // }
687 //
688 //
689 // // After everything (/ this is more complicated now /),
690 // // check JSON file found, if not, insert.
691 // if (found_flag) {
692 // // NSString* newStr = [[NSString alloc] initWithData:[self mainData] encoding:NSUTF8StringEncoding];
693 // // NSLog(@"RemoteData.updateOrInsertDataFile: newStr: %@", newStr);
694 // NSString *newStr = [m5mo bodytext];
695 // // NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: bodytext: %@", newStr);
696 // NSString *localMD5hash = [newStr generateMD5Hash];
697 // NSString *driveMD5hash = [found_file md5Checksum];
698 // NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: remote MD5: %@", [found_file md5Checksum]);
699 // NSLog(@"RemoteData.updateOrInsertMenuItemListOnDriveWithDelegate: local MD5: %@", [newStr generateMD5Hash]);
700 // if ([localMD5hash isEqualToString:driveMD5hash]) {
701 // NSLog(@"... local and drive file equal");
702 // } else {
703 // NSLog(@"... local and drive file differ");
704 // // [self updateFragmentFile:found_file withData:content];
705 // // NSData *fileData = [[NSData alloc] initWithBase64EncodedString:newStr options:NSDataBase64EncodingEndLineWithCarriageReturn];
706 // NSData* data = [newStr dataUsingEncoding:NSUTF8StringEncoding];
707 //
708 // [self updateDriveFile:found_file withData: data];
709 // }
710 //
711 //
712 // } else {
713 // NSLog(@"RemoteData.update-or-insert-datafile: INSERT");
714 //
715 // [self insertMenuItem:m5mo withDelegate:delegate];
716 //
717 // } // END -- if found file
718 //}
719 
725 /*
726 - (void) trashMenuItem: (GTLDriveFile *)file
727 {
728  GTLQueryDrive *query = [GTLQueryDrive queryForFilesTrashWithFileId:[file identifier]];
729 
730  // GTLServiceTicket *fileListTicket =
731  [self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
732  GTLDriveFileList *fileList,
733  NSError *error) {
734  if (error) {
735  NSLog(@"RemoteData.trashMenuItem: ERROR: %@", [error localizedDescription]);
736  }
737  }];
738 }
739  */
743 - (void) fetchMenuItem: (NSString *)fileId onDriveWithDelegate:(id<Z5RemoteDataFetchProtocol>) delegate
744 {/*
745  GTLQueryDrive *query = [GTLQueryDrive queryForFilesGetWithFileId:fileId];
746  query.maxResults = 150;
747  // GTLServiceTicket *fileListTicket =
748  [self.driveService executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
749  GTLDriveFile *file,
750  NSError *error) {
751  if (error) {
752  [delegate showPublishError];
753  } else {
754  [delegate showPublishResult];
755  }
756  }];
757  */
758 }
759 
764 /*
765 - (void) updateDriveFile: (GTLDriveFile *)file withData: (NSData *)data
766 {
767  */
768 /*
769  GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:data MIMEType:file.mimeType];
770  GTLQueryDrive *query = [GTLQueryDrive queryForFilesUpdateWithObject:file
771  fileId:file.identifier
772  uploadParameters:uploadParameters];
773 
774  // UIAlertView *waitIndicator = [Z5DataController showWaitIndicator:@"Updating on Google Drive"];
775 
776  [self.driveService executeQuery:query
777  completionHandler:^(GTLServiceTicket *ticket,
778  GTLDriveFile *insertedFile, NSError *error) {
779  // [waitIndicator dismissWithClickedButtonIndex:0 animated:YES];
780  if (error == nil)
781  {
782  NSLog(@"RemoteDataController.updateDriveFile/complete: File ID: %@", insertedFile.identifier);
783 
784  // [Z5DataController showAlert:@"Google Drive" message:@"File updated!"];
785 
786  }
787  else
788  {
789  NSLog(@"RemoteDataController.updateDriveFile/complete:An error occurred: %@", error);
790  // [Z5DataController showAlert:@"Google Drive Update" message:@"Sorry, an error occurred!"];
791  }
792  }];
793 }
794 */
795 
796 //- (void) putTestFile
797 //{
798 // GTLDriveFile *rrfile;
799 // GTLDriveFile *file = nil;
800 // GTLDriveFile *found_file = nil;
801 // NSString *rrDatabaseFilename = @"Leucine/Arganine";
802 // if ([[rrfile title] compare:rrDatabaseFilename] == NSOrderedSame) {
803 // NSLog(@"RemoteData.putTestFile: UPDATE");
804 // // This is coordmedic.json file
805 // // if ([self beenTrashed:file]) { continue; }
806 // // if (![self isMyFile:file]) { continue; }
807 // // file not trashed
808 // // file belongs to us
809 // // found_flag = YES;
810 // found_file = file;
811 // }
812 //}
813 /*
814 - (void) postData: (NSData *)newfdata toNewGoogleDriveFile: (GTLDriveFile *) file withDelegate: (id <Z5RemoteDataFetchProtocol>)delegate
815 {
816 
817  GTLUploadParameters *uploadParameters = [GTLUploadParameters uploadParametersWithData:newfdata MIMEType:file.mimeType];
818 
819 
820  GTLQueryDrive *query = [GTLQueryDrive queryForFilesInsertWithObject:file
821  uploadParameters:uploadParameters];
822 
823  // UIAlertView *waitIndicator = [Z5DataController showWaitIndicator:@"Uploading to Google Drive"];
824 
825  [self.driveService executeQuery:query
826  completionHandler:^(GTLServiceTicket *ticket,
827  GTLDriveFile *insertedFile,
828  NSError *error) {
829  // [waitIndicator dismissWithClickedButtonIndex:0 animated:YES];
830  if (error == nil)
831  {
832  [delegate showInsertResult:insertedFile];
833  }
834  else
835  {
836  NSLog(@"RemoteData.postData: An error occurred: %@", [error localizedDescription]);
837  // [Z5DataController showAlert:@"Google Drive" message:@"Sorry, an error occurred!"];
838  }
839  }];
840 }
841  */
842 
843 - (void)surveyDirectory: (UITextField *)result_text
844 {
845  /*
846  NSLog(@"RemoteData: Survey directory");
847  GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
848 
849  NSLog(@"RemoteData.surveyDirectory: query: %@", [query description]);
850 
851  GTLServiceTicket *fileListTicket = [[[[Z5DataController sharedInstance] remoteDataController] driveService] executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
852  GTLDriveFileList *fileList,
853  NSError *error)
854  {
855  // Callbacka
856  NSMutableString *result_out = [[NSMutableString alloc] initWithCapacity:256];
857  for (GTLDriveFile *fil in fileList) {
858  if (![[fil.labels trashed] boolValue]) {
859  NSLog(@"DebugExtraView.surveyDirectory: title: %@", [fil title]);
860  [result_out appendString:[fil title]];
861  [result_out appendString:@"\n"];
862  } else {
863  NSLog(@"DebugExtraView.surveyDirectory: TRASHED: title: %@", [fil title]);
864  }
865  }
866  result_text.text = result_out;
867  }];
868 
869  NSLog(@"RemoteData.surveyDirectory: fileListTicket.statusCode: %ld", (long)[fileListTicket statusCode]);
870  */
871 }
872 
873 /*?
874  * Unknown use
875 - (void) fillMenuItemList
876 {
877  [self.menuItemsList removeAllObjects];
878  NSArray *objects = [[[Z5DataController sharedInstance] localDataController] retrieveAllMenuItems:[NSNumber numberWithInt:1]];
879  // NSLog(@"RemoteData.fillMenuItemList: #menuItems: %ld", (long)[objects count]);
880  for (NSManagedObject *menuItem in objects) {
881  MenuItem *dbMenuItem = (MenuItem *)menuItem;
882  NSLog(@"RemoteData.fillMenuItemList: menuItem into list: %@", [dbMenuItem name]);
883  //[self.menuItemsList addObject:menuItem];
884  }
885  // NSLog(@"RemoteData.fillMenuItemList: count: %lu", (unsigned long)[self.menuItemsList count]);
886  // [self.tableView reloadData];
887 }
888  */
889 
890 #pragma mark -
891 #pragma mark Download file from drive
892 
893 
894 //- (void) downloadFile: (GTLDriveFile *)file withDelegate:(id<Z5RemoteDataFetchProtocol>) delegate
895 //{
896 // // GTLServiceDrive *drive = ...;
897 // // GTLDriveFile *file = ...;
898 // __block NSString *driveFileTitle = [file title];
899 // __block NSString *driveFileId = [file identifier];
900 // GTMHTTPFetcher *fetcher = [self.driveService.fetcherService fetcherWithURLString:file.downloadUrl];
901 //
902 // [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
903 // if (error == nil) {
904 // // NSLog(@"RemoteData.downloadFile: Retrieved file content");
905 // // NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
906 // // NSLog(@"RemoteData.downloadFile: contents: %@", contents);
907 //
908 // [delegate showDataFetch:data fromFile:driveFileTitle withGoogleId:driveFileId];
909 //
910 // } else {
911 // NSLog(@"RemoteDate.downloadFile: An error occurred: %@", error);
912 // }
913 // }];
914 //}
915 
916 
917 #pragma mark Fetch File Details
918 
920  /*
921  _revisionList = nil;
922  _revisionListFetchError = nil;
923  _permissionList = nil;
924  _permissionListFetchError = nil;
925  _childList = nil;
926  _childListFetchError = nil;
927  _parentsList = nil;
928  _parentsListFetchError = nil;
929 
930  _detailsFetchError = nil;
931 
932  GTLServiceDrive *service = self.driveService;
933 
934  GTLDriveFile *selectedFile = [self selectedFileListEntry:1];
935  NSString *fileID = selectedFile.identifier;
936  if (fileID) {
937  // Rather than make separate fetches for each kind of detail for the
938  // selected file, we'll make a single batch query to etch the various
939  // details. Each query in the batch will have its own result or error,
940  // and the batch query execution itself may fail with an error.
941  GTLQueryDrive *revisionQuery = [GTLQueryDrive queryForRevisionsListWithFileId:fileID];
942  revisionQuery.completionBlock = ^(GTLServiceTicket *ticket, GTLDriveRevisionList *obj,
943  NSError *error) {
944  _revisionList = obj;
945  _revisionListFetchError = error;
946  };
947 
948  GTLQueryDrive *permissionQuery = [GTLQueryDrive queryForPermissionsListWithFileId:fileID];
949  permissionQuery.completionBlock = ^(GTLServiceTicket *ticket, GTLDrivePermissionList *obj,
950  NSError *error) {
951  _permissionList = obj;
952  _permissionListFetchError = error;
953  };
954 
955  GTLQueryDrive *childQuery = [GTLQueryDrive queryForChildrenListWithFolderId:fileID];
956  childQuery.completionBlock = ^(GTLServiceTicket *ticket, GTLDriveChildList *obj,
957  NSError *error) {
958  _childList = obj;
959  _childListFetchError = error;
960  };
961 
962  GTLQueryDrive *parentsQuery = [GTLQueryDrive queryForParentsListWithFileId:fileID];
963  parentsQuery.completionBlock = ^(GTLServiceTicket *ticket, GTLDriveParentList *obj,
964  NSError *error) {
965  // Note that we could obtain the parents list for a file item from the
966  // main file list feed, too.
967  _parentsList = obj;
968  _parentsListFetchError = error;
969  };
970  */
971 /*
972  // Combine the separate queries into one batch.
973  GTLBatchQuery *batchQuery = [GTLBatchQuery batchQuery];
974  [batchQuery addQuery:revisionQuery];
975  [batchQuery addQuery:permissionQuery];
976  [batchQuery addQuery:childQuery];
977  [batchQuery addQuery:parentsQuery];
978 
979  _detailsTicket = [service executeQuery:batchQuery
980  completionHandler:^(GTLServiceTicket *ticket,
981  GTLBatchResult *batchResult, NSError *error) {
982  // Callback
983  //
984  // The batch query execution completionHandler runs after the individual
985  // query completion handlers have been called.
986  _detailsTicket = nil;
987  _detailsFetchError = error;
988 
989  [self updateUI];
990  }];
991 
992  [self updateUI];
993  }
994  */
995 }
996 
997 #pragma mark Delete a File
998 
1000  /*
1001  GTLServiceDrive *service = self.driveService;
1002 
1003  GTLDriveFile *selectedFile = [self selectedFileListEntry:1];
1004  NSString *fileID = selectedFile.identifier;
1005  if (fileID) {
1006  GTLQueryDrive *query = [GTLQueryDrive queryForFilesDeleteWithFileId:fileID];
1007  _editFileListTicket = [service executeQuery:query
1008  completionHandler:^(GTLServiceTicket *ticket,
1009  id nilObject,
1010  NSError *error) {
1011  // Callback
1012  _editFileListTicket = nil;
1013  if (error == nil) {
1014  [self displayAlert:@"Deleted"
1015  format:@"Deleted \"%@\"",
1016  selectedFile.title];
1017  [self updateUI];
1018  // [self fetchFileList];
1019  } else {
1020  [self displayAlert:@"Delete Failed"
1021  format:@"%@", error];
1022  }
1023  }];
1024  }
1025  */
1026 }
1027 
1028 #pragma mark - Google product
1029 // From https://developers.google.com/drive/v2/reference/files/list
1030 //- (void)retrieveAllFiles
1031 //{
1032 // [Z5GoogleProvided retrieveAllFilesWithService: [self driveService] completionBlock:^void (NSArray *a2, NSError *e2) {
1033 // if (nil == e2) {
1034 // NSLog(@"RemoteData.retrieveAllFiles: data count: %lu", (unsigned long)[a2 count]);
1035 // }
1036 // }];
1037 //}
1038 
1039 //- (Z2MenuItem *)scanForMenuItemWithFileId:(NSString *)googlefileid
1040 //{
1041 // NSLog(@"RemoteData.scanForZ2MenuItem: huh??");
1042 // return nil;
1043 //}
1044 
1045 #pragma mark - Plus Service
1046 
1047 
1048 @end
void runSigninThenHandler:(void(^ handler)(void))
NSString *const kKeychainItemName
void signInNowWithHandler:(void(^ finishHandler)(void))
NSString * signedInUsername()
void signInSilently()
GIDSignIn * sharedInstance()
void updateUI()
/// - (void) fillMoleculeList;
Interface for remote access, to either open web or google drive.