Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7053587
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T03:31:24+00:00 2026-05-28T03:31:24+00:00

Has anyone integrated google docs into their iOS app? Having gone through the example

  • 0

Has anyone integrated google docs into their iOS app? Having gone through the example code, the API for Google Docs is far more complicated than I would have expected, and the examples are all MacOS. Yes there is iOS support, but there is a distinct lack of example code on how to use it, and the documentation is somewhat lacking.

I did find an interface class on the web, but it was based on an older, deprecated version of the Google Docs API, and it doesn’t compile with XCode 4.2.

What I’m after is a relatively straight forward interface that allows:

  1. Logging in/out from a google docs account.
  2. Getting a list of documents within that account (optionally of a specific type), possibly with the ability to navigate a folder structure.
  3. Being able to download a specific document to local storage.
  4. Being able to upload a specific document to google docs.

I’ve started writing such an interface, but so far it’s way more involved than I had allowed for. If anyone has any suggestions, or samples that they can direct me to, I’d really appreciate it.

My preference is for the wrapper to be OS neutral; meaning I want to be able to use the same interface in both MacOS and iOS. Again, this is what I’ve started writing, but I can’t help feeling that I must be reinventing the wheel here.

Thanks

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T03:31:24+00:00Added an answer on May 28, 2026 at 3:31 am

    OK, so in the absence of any answers from others, I bit the bullet and wrote a wrapper myself.

    I now have single wrapper that works for both Mac OS and iOS that dramatically simplifies the interface with Google Docs.

    Below is all of the code for the actual interface. I should point out that this class acts as a singleton, and you need to customise it slightly for each project by updating the lines:

    #define GOOGLE_DATA_CLIENT_ID @"<client id>.apps.googleusercontent.com"
    #define GOOGLE_DATA_SECRET @"<google data secret>"
    #define GOOGLE_DATA_USERNAME @"googleDocsUsername"
    #define GOOGLE_DATA_PASSWORD @"googleDocsPassword"
    

    with the appropriate values you get from Google.

    I also point out that the class stores passwords via NSUserDefaults, and uses a separate utility class to do this in an encrypted fashion. Rather than clog this answer here with all of that extra code, I’ve created a repository in bitbucket at:

    https://bitbucket.org/pkclsoft/gdatainterface

    which contains an entire XCode project that builds two targets, one for Mac OS and one for iOS. Ive used those both in an app that is in the app store now with great results. It may be that whilst this project builds for me you have to tweak it for your purposes. The project contains a complete set of the Google SDK that builds and runs with my code. I included it to try and reduce the risk of incompatibilities with newer versions of the SDK for anyone grabbing it.

    Here is the interface spec as it currently stands:

    //
    //  GDataInterface.h
    //  GDataInterface
    //
    //  Some of the code in this class is from the original GData sample code, but it has been
    //  enhanced somewhat and made to work on both iOS and MacOS transparently.
    //
    //  Created by Peter Easdown on 19/12/11.
    //  Copyright (c) 2011 PKCLsoft. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #if TARGET_OS_IPHONE
    #import "GDataDocs.h"
    #import <UIKit/UIKit.h>
    #else
    #import "GData/GData.h"
    #endif
    
    @interface GDataInterfaceTypes
    
    // This handler is used by methods that have no explicit result.  The boolean value indicates
    // the success or failure of the the methods action.
    //
    typedef void (^CompletionHandler)(BOOL successful);
    
    // This handler is called to update a progress indicator as a file is uploaded.
    //
    typedef void (^UploadProgressHandler)(double min, double max, double value);
    
    // This handler is called to update a progress indicator as a file is downloaded.
    //
    typedef void (^DownloadProgressHandler)(double min, double max, double value);
    
    @end
    
    @interface GDataInterface : NSObject {
    
    #if TARGET_OS_IPHONE
        // Needed so that when authenticating under iOS, we can push the google authentication
        // view, and later pop it.
        //
        UIViewController *rootController_;
    #endif
    
        GDataFeedDocList *mDocListFeed;
        GDataServiceTicket *mDocListFetchTicket;
        NSError *mDocListFetchError;
    
        GDataFeedDocRevision *mRevisionFeed;
        GDataServiceTicket *mRevisionFetchTicket;
        NSError *mRevisionFetchError;
    
        GDataEntryDocListMetadata *mMetadataEntry;
    
        GDataServiceTicket *mUploadTicket;
    
        id uploadWindow;
        CompletionHandler uploadCompletionHandler;
    
        NSString *username_;
        NSString *password_;
    
    }
    
    // This handler is used when a list of documents has been requested.  The results parameter
    // will be nil if the request failed.  If successful, then it will contain an array of 
    // GDataEntryDocBase objects.
    //
    typedef void (^RetrievalCompletionHandler)(GDataFeedDocList* results, BOOL successful);
    
    // This handler is used when a document has been downloaded.  If something prevented the 
    // download from succeeding, then error parameter will be non-nil.
    //
    typedef void (^DocumentDownloadCompletionHandler)(NSData* fileContents, BOOL successful);
    
    // Initializer that provides the username and password.
    //
    - (id) initWithUsername:(NSString*)username andPassword:(NSString*)password;
    
    // Returns the shared instance of the class.  There will only ever be a single instance
    // of this class.
    //
    + (GDataInterface*) sharedInstance;
    
    // Returns YES if currently signed in.
    //
    - (BOOL) isSignedIn;
    
    // Signs in or out depending on current state, and executes the options completion handler
    // block.  The window parameter is used to specify the root viewController object used when
    // displaying login windows via GData, or error dialogs.
    //
    - (void) signInOrOutWithCompletionHandler:(CompletionHandler)handler forWindow:(id)window;
    
    // Will retrieve a list of documents using the cached connection, and call the specified
    // handler block, providing the list of documents, and a success/fail indication.
    //
    - (void) retrieveDocumentListWithCompletionHandler:(RetrievalCompletionHandler)handler;
    
    // Will download the file at the specified URL.  This is not Google Docs specific and will work
    // for any URL.  Be careful not to try and retrieve large files and the result is stored
    // in memory.
    //
    - (void) downloadURL:(NSURL*)url withProgressHandler:(DownloadProgressHandler)progressHandler andCompletionHandler:(DocumentDownloadCompletionHandler)handler;
    
    // Will download the specified google docs document.
    //
    - (void) downloadDocument:(GDataEntryDocBase*)document withProgressHandler:(DownloadProgressHandler)progressHandler andCompletionHandler:(DocumentDownloadCompletionHandler)handler;
    
    // Uploads the document entry, optionally updating it with a new revision.
    //
    - (void) uploadEntry:(GDataEntryDocBase*)docEntry asNewRevision:(BOOL)newRevision forWindow:(id)window withProgressHandler:(UploadProgressHandler)progressHandler andCompletionHandler:(CompletionHandler)handler;
    
    // Uploads the specified file to the authenticated google docs account.
    //
    - (void)uploadFileAtPath:(NSString *)path forWindow:(id)window withProgressHandler:(UploadProgressHandler)progressHandler andCompletionHandler:(CompletionHandler)handler;
    
    // More for internal use than anything else.  Used to determine the mime type based on the google docs class
    // and/or file extension.
    //
    - (void)getMIMEType:(NSString **)mimeType andEntryClass:(Class *)class forExtension:(NSString *)extension;
    
    // Getter and Setter for username,
    //
    - (void) setUsername:(NSString*)newUsername;
    - (NSString*) username;
    
    // Getter and Setter for password.  The password will be encrypted before storing it in user preferances.
    //
    - (void) setPassword:(NSString*)newPassword;
    - (NSString*) password;
    
    // Returns the username that google is given for signing in.
    //
    - (NSString *)signedInUsername;
    
    // Returns a static instance of the docs service.
    //
    + (GDataServiceGoogleDocs *)docsService;
    
    @end
    

    And here is the implementation:

    //
    //  GDataInterface.m
    //  GDataInterface
    //
    //  Created by Peter Easdown on 19/12/11.
    //  Copyright (c) 2011 PKCLsoft. All rights reserved.
    //
    
    #import "GDataInterface.h"
    #import "Util.h"
    #if TARGET_OS_IPHONE
    #import "GTMOAuth2ViewControllerTouch.h"
    #import "GData.h"
    #else
    #import "GData/GTMOAuth2WindowController.h"
    //#import "GDataServiceGoogleSpreadsheet.h"
    #endif
    
    #define GOOGLE_DATA_CLIENT_ID @"<client id>.apps.googleusercontent.com"
    #define GOOGLE_DATA_SECRET @"<google data secret>"
    #define GOOGLE_DATA_USERNAME @"googleDocsUsername"
    #define GOOGLE_DATA_PASSWORD @"googleDocsPassword"
    
    @interface GDataInterface (PrivateMethods)
    
    - (GDataServiceTicket *) uploadTicket;
    - (void) setUploadTicket:(GDataServiceTicket *)ticket;
    
    - (GDataFeedDocList *)docListFeed;
    - (void)setDocListFeed:(GDataFeedDocList *)feed;
    - (NSError *)docListFetchError;
    - (void)setDocListFetchError:(NSError *)error;
    - (GDataServiceTicket *)docListFetchTicket;
    - (void)setDocListFetchTicket:(GDataServiceTicket *)ticket;
    
    @end
    
    @implementation GDataInterface
    
    static NSString *const kKeychainItemName = @"GDataInterface: Google Docs";
    
    // Initializer that provides the username and password.
    //
    - (id) initWithUsername:(NSString*)username andPassword:(NSString*)password {
        self = [super init];
    
        if (self != nil) {
            username_ = [username retain];
            password_ = [password retain];
            [[GDataInterface docsService] setUserCredentialsWithUsername:username_ password:password_];
        }
    
        return self;
    }
    
    - (void) setUsername:(NSString*)newUsername {
        username_ = [newUsername retain];
        [[GDataInterface docsService] setUserCredentialsWithUsername:newUsername password:password_];
    }
    
    - (NSString*) username {
        return username_;
    }
    
    - (void) setPassword:(NSString*)newPassword {
        password_ = [newPassword retain];
        [[GDataInterface docsService] setUserCredentialsWithUsername:username_ password:newPassword];
        [Util setPassword:newPassword forKey:GOOGLE_DATA_PASSWORD];
    }
    
    - (NSString*) password {
        return password_;
    }
    
    
    static GDataInterface *shared_instance_;
    
    // Returns the shared instance of the class.  There will only ever be a single instance
    // of this class.
    //
    + (GDataInterface*) sharedInstance {
        if (shared_instance_ == nil) {
            shared_instance_ = [[GDataInterface alloc] initWithUsername:[[NSUserDefaults standardUserDefaults] valueForKey:GOOGLE_DATA_USERNAME] andPassword:[Util getPassword:GOOGLE_DATA_PASSWORD]];
    
            // Load the OAuth token from the keychain, if it was previously saved
            NSString *clientID = GOOGLE_DATA_CLIENT_ID;
            NSString *clientSecret = GOOGLE_DATA_SECRET;
    
            GTMOAuth2Authentication *auth;
    
    #if TARGET_OS_IPHONE
            auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName clientID:clientID clientSecret:clientSecret];
    #else
            auth = [GTMOAuth2WindowController authForGoogleFromKeychainForName:kKeychainItemName
                                                                      clientID:clientID
                                                                  clientSecret:clientSecret];
    #endif
    
            [[GDataInterface docsService] setAuthorizer:auth];
        }
    
        return shared_instance_;
    }
    
    - (NSString *)signedInUsername {
        // Get the email address of the signed-in user
        GTMOAuth2Authentication *auth = [[GDataInterface docsService] authorizer];
        BOOL isSignedIn = auth.canAuthorize;
    
        if (isSignedIn) {
            return auth.userEmail;
        } else {
            return nil;
        }
    }
    
    - (BOOL) isSignedIn {
        return ([self signedInUsername] != nil);
    }
    
    - (void)runSigninThenInvokeHandler:(CompletionHandler)handler forWindow:(id)window {
        // Applications should have client ID and client secret strings
        // hardcoded into the source, but the sample application asks the
        // developer for the strings
        NSString *clientID = GOOGLE_DATA_CLIENT_ID;
        NSString *clientSecret = GOOGLE_DATA_SECRET;
    
        // Show the OAuth 2 sign-in controller
        NSString *scope = [GTMOAuth2Authentication scopeWithStrings:
                           [GDataServiceGoogleDocs authorizationScope],
                           [GDataServiceGoogleSpreadsheet authorizationScope],
                           nil];
    
    #if TARGET_OS_IPHONE
        NSAssert((window != nil), @"window must be a non-nil navigation controller");
    
        GTMOAuth2ViewControllerTouch *viewController;
        viewController = [GTMOAuth2ViewControllerTouch 
                          controllerWithScope:scope
                          clientID:clientID 
                          clientSecret:clientSecret 
                          keychainItemName:kKeychainItemName
                          completionHandler:^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error) {
    
                              [rootController_ dismissModalViewControllerAnimated:YES];
                              [rootController_ release];
                              rootController_ = nil;
    
                              // callback
                              if (error == nil) {
                                  [[GDataInterface docsService] setAuthorizer:auth];
    
                                  username_ = [self signedInUsername];
    
                                  handler(YES);
                              } else {
                                  NSLog(@"Authentication error: %@", error);
                                  NSData *responseData = [[error userInfo] objectForKey:@"data"]; // kGTMHTTPFetcherStatusDataKey
                                  if ([responseData length] > 0) {
                                      // show the body of the server's authentication failure response
                                      NSString *str = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];
                                      NSLog(@"%@", str);
                                  }
                                  handler(NO);
                              }
                          }];
    
        // Optional: display some html briefly before the sign-in page loads
        NSString *html = @"<html><body bgcolor=silver><div align=center>Loading sign-in page...</div></body></html>";
        viewController.initialHTMLString = html;
    
        // For iOS, window is a navigation controller.
        //
        rootController_ = [(UIViewController*)window retain];
        [rootController_ presentModalViewController:viewController animated:YES];
    
    #else
        NSBundle *frameworkBundle = [NSBundle bundleForClass:[GTMOAuth2WindowController class]];
        GTMOAuth2WindowController *windowController;
        windowController = [GTMOAuth2WindowController controllerWithScope:scope
                                                                 clientID:clientID
                                                             clientSecret:clientSecret
                                                         keychainItemName:kKeychainItemName
                                                           resourceBundle:frameworkBundle];
    
        [windowController signInSheetModalForWindow:window
                                  completionHandler:^(GTMOAuth2Authentication *auth, NSError *error) {
                                      // callback
                                      if (error == nil) {
                                          [[GDataInterface docsService] setAuthorizer:auth];
                                          username_ = [auth userEmail];
                                          handler(YES);
                                      } else {
                                          handler(NO);
                                      }
                                  }];
    #endif
    }
    
    - (void) signInOrOutWithCompletionHandler:(CompletionHandler)handler forWindow:(id)window {
        if (![self isSignedIn]) {
            // Sign in
            [self runSigninThenInvokeHandler:handler forWindow:window];
        } else {
            // Sign out
            GDataServiceGoogleDocs *service = [GDataInterface docsService];
    
    #if TARGET_OS_IPHONE
            [GTMOAuth2ViewControllerTouch removeAuthFromKeychainForName:kKeychainItemName];
    #else
            [GTMOAuth2WindowController removeAuthFromKeychainForName:kKeychainItemName];
    #endif
    
            [service setAuthorizer:nil];
            handler(YES);
        }
    }
    
    - (void) retrieveDocumentListWithCompletionHandler:(RetrievalCompletionHandler)handler {
    
        [self setDocListFeed:nil];
        [self setDocListFetchError:nil];
        [self setDocListFetchTicket:nil];
    
        GDataServiceGoogleDocs *service = [GDataInterface docsService];
        GDataServiceTicket *ticket;
    
        // Fetching a feed gives us 25 responses by default.  We need to use
        // the feed's "next" link to get any more responses.  If we want more than 25
        // at a time, instead of calling fetchDocsFeedWithURL, we can create a
        // GDataQueryDocs object, as shown here.
    
        NSURL *feedURL = [GDataServiceGoogleDocs docsFeedURL];
    
        GDataQueryDocs *query = [GDataQueryDocs documentQueryWithFeedURL:feedURL];
        [query setMaxResults:1000];
        [query setShouldShowFolders:NO];
    
        ticket = [service fetchFeedWithQuery:query
                           completionHandler:^(GDataServiceTicket *ticket, GDataFeedBase *feed, NSError *error) {
                               // callback
                               [self setDocListFeed:(GDataFeedDocList *)feed];
                               [self setDocListFetchError:error];
                               [self setDocListFetchTicket:nil];
    
                               if (handler != nil) {
                                   handler((GDataFeedDocList *)feed, (error == nil));
                               }
                           }];
    
        [self setDocListFetchTicket:ticket];
    }
    
    - (void) downloadDocument:(GDataEntryDocBase*)document withProgressHandler:(DownloadProgressHandler)progressHandler andCompletionHandler:(DocumentDownloadCompletionHandler)handler {
    
        // the content src attribute is used for downloading
        NSURL *exportURL = [[document content] sourceURL];
    
        if (exportURL != nil) {
            GDataQuery *query = [GDataQuery queryWithFeedURL:exportURL];
            [query addCustomParameterWithName:@"exportFormat"
                                        value:@"txt"];
            NSURL *downloadURL = [query URL];
            // Read the document's contents asynchronously from the network
    
            // requestForURL:ETag:httpMethod: sets the user agent header of the
            // request and, when using ClientLogin, adds the authorization header
            NSURLRequest *request = [[GDataInterface docsService] requestForURL:downloadURL
                                                                           ETag:nil
                                                                     httpMethod:nil];
    
            GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
            [fetcher setAuthorizer:[[GDataInterface docsService] authorizer]];
    
            __block double maxSize = 10240.0;
    
            if (progressHandler != nil) {            
                [fetcher setReceivedDataBlock:^(NSData *dataReceivedSoFar) {
                    if ([[fetcher response] expectedContentLength] > 0) {
                        maxSize = [[fetcher response] expectedContentLength];
                    } else if ([dataReceivedSoFar length] > maxSize) {
                        maxSize += 5120.0;
                    }
    
                    progressHandler(0.0, maxSize, (double)[dataReceivedSoFar length]);
                }];
            }
    
            [fetcher setCommentWithFormat:@"downloading \"%@\"", [[document title] stringValue]];
            [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
                if (progressHandler != nil) {
                    // Update the progress handler with a "complete" progress.
                    //
                    progressHandler(0.0, (double)[data length], (double)[data length]);
                }
    
                // callback
                if (error == nil) {
                    // Successfully downloaded the document
                    //                
                    if (handler != nil) {
                        handler(data, YES);
                    }
                } else {
                    if (handler != nil) {
                        handler(nil, NO);
                    }
                }
            }];
        }
    }
    
    - (void) downloadURL:(NSURL*)url withProgressHandler:(DownloadProgressHandler)progressHandler andCompletionHandler:(DocumentDownloadCompletionHandler)handler {
    
        NSURL *downloadURL = [url copy];
        // Read the document's contents asynchronously from the network
    
        NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
    
        GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
    
        __block double maxSize = 10240.0;
    
        if (progressHandler != nil) {            
            [fetcher setReceivedDataBlock:^(NSData *dataReceivedSoFar) {
                if ([[fetcher response] expectedContentLength] > 0) {
                    maxSize = [[fetcher response] expectedContentLength];
                } else if ([dataReceivedSoFar length] > maxSize) {
                    maxSize += 5120.0;
                }
    
                progressHandler(0.0, maxSize, (double)[dataReceivedSoFar length]);
            }];
        }
    
        [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
            if (progressHandler != nil) {
                progressHandler(0.0, (double)[data length], (double)[data length]);
            }
    
            // callback
            if (error == nil) {
                // Successfully downloaded the document
                //                
                if (handler != nil) {
                    handler(data, YES);
                }
            } else {
                if (handler != nil) {
                    handler(nil, NO);
                }
            }
        }];
    
        // Block, waiting for 60 seconds for the download.
        //
        [fetcher waitForCompletionWithTimeout:60.0];
    
        if ([fetcher isFetching] == YES) {
            // OK, so this looks like we've timed out waiting for the download to complete.  Cancel the 
            // fetch.
            //
            [fetcher stopFetching];
    
            if (handler != nil) {
                handler(nil, NO);
            }
        }
    }
    
    #pragma mark Upload
    
    - (void)getMIMEType:(NSString **)mimeType andEntryClass:(Class *)class forExtension:(NSString *)extension {
    
        // Mac OS X's UTI database doesn't know MIME types for .doc and .xls
        // so GDataEntryBase's MIMETypeForFileAtPath method isn't helpful here
    
        struct MapEntry {
            NSString *extension;
            NSString *mimeType;
            NSString *className;
        };
    
        static struct MapEntry sMap[] = {
            { @"csv", @"text/csv", @"GDataEntryStandardDoc" },
            { @"doc", @"application/msword", @"GDataEntryStandardDoc" },
            { @"docx", @"application/vnd.openxmlformats-officedocument.wordprocessingml.document", @"GDataEntryStandardDoc" },
            { @"ods", @"application/vnd.oasis.opendocument.spreadsheet", @"GDataEntrySpreadsheetDoc" },
            { @"odt", @"application/vnd.oasis.opendocument.text", @"GDataEntryStandardDoc" },
            { @"pps", @"application/vnd.ms-powerpoint", @"GDataEntryPresentationDoc" },
            { @"ppt", @"application/vnd.ms-powerpoint", @"GDataEntryPresentationDoc" },
            { @"rtf", @"application/rtf", @"GDataEntryStandardDoc" },
            { @"sxw", @"application/vnd.sun.xml.writer", @"GDataEntryStandardDoc" },
            { @"txt", @"text/plain", @"GDataEntryStandardDoc" },
            { @"xls", @"application/vnd.ms-excel", @"GDataEntrySpreadsheetDoc" },
            { @"xlsx", @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", @"GDataEntrySpreadsheetDoc" },
            { @"jpg", @"image/jpeg", @"GDataEntryStandardDoc" },
            { @"jpeg", @"image/jpeg", @"GDataEntryStandardDoc" },
            { @"png", @"image/png", @"GDataEntryStandardDoc" },
            { @"bmp", @"image/bmp", @"GDataEntryStandardDoc" },
            { @"gif", @"image/gif", @"GDataEntryStandardDoc" },
            { @"html", @"text/html", @"GDataEntryStandardDoc" },
            { @"htm", @"text/html", @"GDataEntryStandardDoc" },
            { @"tsv", @"text/tab-separated-values", @"GDataEntryStandardDoc" },
            { @"tab", @"text/tab-separated-values", @"GDataEntryStandardDoc" },
            { @"pdf", @"application/pdf", @"GDataEntryPDFDoc" },
            { nil, nil, nil }
        };
    
        NSString *lowerExtn = [extension lowercaseString];
    
        for (int idx = 0; sMap[idx].extension != nil; idx++) {
            if ([lowerExtn isEqual:sMap[idx].extension]) {
                *mimeType = sMap[idx].mimeType;
                *class = NSClassFromString(sMap[idx].className);
                return;
            }
        }
    
        *mimeType = nil;
        *class = nil;
        return;
    }
    
    - (void) uploadEntry:(GDataEntryDocBase*)docEntry asNewRevision:(BOOL)newRevision forWindow:(id)window withProgressHandler:(UploadProgressHandler)progressHandler andCompletionHandler:(CompletionHandler)handler {
    
        uploadWindow = [window retain];
        uploadCompletionHandler = [handler copy];
    
        NSURL *uploadURL;
    
        if (newRevision == YES) {
            GDataQueryDocs *query = [GDataQueryDocs queryWithFeedURL:[[docEntry 
                                                                       uploadEditLink] URL]]; 
            [query setShouldCreateNewRevision:YES]; 
            uploadURL = [query URL];
        } else {
            uploadURL = [GDataServiceGoogleDocs docsUploadURL];
        }
    
        // make service tickets call back into our upload progress selector
        GDataServiceGoogleDocs *service = [GDataInterface docsService];
        [service setServiceUploadProgressHandler:^(GDataServiceTicketBase *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength) {
            if (progressHandler != nil) {
                progressHandler(0.0, (double)dataLength, (double)numberOfBytesRead);
            }
        }];
    
        // insert the entry into the docList feed
        //
        // to update (replace) an existing entry by uploading a new file,
        // use the fetchEntryByUpdatingEntry:forEntryURL: with the URL from
        // the entry's uploadEditLink
        GDataServiceTicket *ticket;
    
        if (newRevision == YES) {        
            ticket = [service fetchEntryByUpdatingEntry:docEntry 
                                            forEntryURL:uploadURL 
                                               delegate:self 
                                      didFinishSelector:@selector(uploadFileTicket:finishedWithEntry:error:)];
        } else {
            ticket = [service fetchEntryByInsertingEntry:docEntry
                                              forFeedURL:uploadURL
                                                delegate:self
                                       didFinishSelector:@selector(uploadFileTicket:finishedWithEntry:error:)];
        }
    
        [ticket setUploadProgressHandler:^(GDataServiceTicketBase *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength) {
            // progress callback
            if (progressHandler != nil) {
                progressHandler(0.0, (double)dataLength, (double)numberOfBytesRead);
            }
        }];
    
        // we turned automatic retry on when we allocated the service, but we
        // could also turn it on just for this ticket
    
        [self setUploadTicket:ticket];
        [service setServiceUploadProgressHandler:nil];
    }
    
    - (void)uploadFileAtPath:(NSString *)path forWindow:(id)window withProgressHandler:(UploadProgressHandler)progressHandler andCompletionHandler:(CompletionHandler)handler {
    
        NSString *errorMsg = nil;
    
        // make a new entry for the file
    
        NSString *mimeType = nil;
        Class entryClass = nil;
    
        NSString *extn = [path pathExtension];
        [self getMIMEType:&mimeType andEntryClass:&entryClass forExtension:extn];
    
        if (!mimeType) {
            // for other file types, see if we can get the type from the Mac OS
            // and use a generic file document entry class
            mimeType = [GDataUtilities MIMETypeForFileAtPath:path
                                             defaultMIMEType:nil];
            entryClass = [GDataEntryFileDoc class];
        }
    
        if (mimeType && entryClass) {
    
            GDataEntryDocBase *newEntry = [entryClass documentEnt
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Has anyone integrated with Google Latitude (or any Google API, for that matter) with
Has anyone integrated ELMAH into their SharePoint environment? I suppose it's possible as it's
I am trying to integrate the code from this demo: http://code.google.com/p/gwt-spring-starter-app/ into my main
Google News has API, described here: http://code.google.com/apis/newssearch/v1/index.html But it is a JavaScript API (client
Has anyone integrated Socialize (getsocialize.com) with PhoneGap? I'm working on a PhoneGap app, and
Has anyone integrated an iPhone application with a Shibboleth Identity Provider? Googling did not
Has anyone run into this error message before when using a timer on an
Has anyone integrated BeautifulSoup with ASP.NET/C# (possibly using IronPython or otherwise)? Is there a
Has anyone managed to run wcf successfully in 2.0 integrated mode on IIS7 when
Has anyone integrated a local copy of gitorious with Hudson? Specifically, linking the sha1

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.