business@innofied.com

US Toll-Free - +1 866 941 5117

Top
IntegrationofGoogleDiveiniOSapps

Google Drive Integration in iOS apps

Introduction

In present era of versatility , one cannot imagine an iOS app without the integration of third party applications such as Dropbox , Box and Google Drive for accessing their files, whatever may be the type of requirement. If no proper care is  taken for settings, integration for such apps could sometimes become very difficult. Google Drive is one tool that, could give birth to many problems if proper measures are not taken.

Here in this blog we are going to illustrate Google Drive integration in iOS apps.

Registering your application:

For registering your application , you will need a Google account. If you don’t have one , you can sign up for an account over here. After this you need to go to this link for registering your application.

Click on Create Project and start registering your application.

In the pop up opened, give a name for your project and accept ‘Terms of Service ‘of Google for integration. Clicking on ‘Create’ will show you the new application you just created. After that click on your application and from left side select the option “APIs & auth” . You will see a list of APIs for which Google provide support.

From those list of APIs go to the option ‘Drive API’ and turn it on. This would enable the drive API on your application. After that from left bar select the option ‘Credentials’.

You will see a screen like this :

Here, you need to create a client id and Public API access key.

Now click on ‘Create New Client ID’. Clicking on it will open a pop up showing the options for application type. Here you need to select ‘Installed application’. Under ‘installed application type’,  select the option ‘Other’.

Note : We do not select ‘iOS’ option as it is for a feature that doesn’t exist yet. So we are going to use a generic installed application option.

After that clicking on create button will give you the client id and client secret.

Create a Public Access key by providing the bundle identifiers needed for your application under ‘iOS key’ option.

Note : You can add more than one bundle identifier if you want. (since app development and app distribution requires two different bundle ID’s ).

As soon as you create the public key , your app becomes registered for using Google Drive API.

Installing Google Client Library:

For using the Google Drive API you need to first download the client library provided for Google integration. For downloading the client library open terminal, go to the project’s folder directory and paste the following:

svn checkout http://google-api-objectivec-client.googlecode.com/svn/trunk/google-api-objectivec-client-read-only

Configure Xcode project :

For configuring your Xcode project , you need to follow these steps:

  1. Open your project in finder . Open Google Client Library root folder and from there select Source . After opening Source you will find a project ‘GTL.xcodeproject’ like shown in the following image. You need to drag this project into your Project.xcodeproject.


    You will see a workspace is created in your project.

  2. Now, go to  ‘Build Phases’  of your project and add library ‘libGTLTouchStaticLib.a’. Also add Security.framework and SystemConfiguration.framework.

  3. In ‘Build Settings’ , add  “-ObjC -all_load” in ‘other linker flags’.

  4. Go to ‘User header Search Paths’ and under that add directory path for ‘Source’ folder of Google Client Library and set the path from Non-Recursive to Recursive.

  5. Select , GTL project . Under GTL project, go to Build Settings and set ‘skip install’ to YES for GTL Framework and GTL project.

    Note : You can select GTL Framework and GTL project from the ovally marked location and set skip install to YES for both.

  6. Drag ‘GTMOAuth2ViewTouch.xib’ from Google Client Library’s Source/OAuth2/Touch folder into the app’s project Supporting Files folder.
  7. Add the Google Drive service by adding ‘GTLDrive.h’ and ‘GTLDrive_Sources.m’ from the Source/Services/Drive/Generated folder directly to the application project.

Application authorization and making API calls:

Add the following lines of code to your ’ViewController.h’ file.

#import "GTMOAuth2ViewControllerTouch.h"
#import "GTLDrive.h"

@property (nonatomic, retain) GTLServiceDrive *driveService;

In Your ViewController.m file add following lines of code:

static NSString *const kKeychainItemName = @"Your Project name Registered With Google ";
static NSString *const kClientID = @"Your Client ID";
static NSString *const kClientSecret = @"Your client secret";

Now add the following lines of code in same file.m . These codes will ignite the authorization process for your application by Google.

-(void)showGoogleDriveForChoosingFile
{
    [self setValuesForGoogleDriveAccess];

    if (![self isAuthorized])
    {
        isAuthorized=NO;
        GTMOAuth2ViewControllerTouch *authController=  [self createAuthController];
    }
    else
    {
        isAuthorized=YES;
    }
}
//-------------------------------------------------------------------------------------

-(void)setValuesForGoogleDriveAccess
{
    // Initialize the drive service & load existing credentials from the keychain if available
    self.driveService = [[GTLServiceDrive alloc] init];

    self.driveService.authorizer = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
                                                                                         clientID:kClientID
                                                                                     clientSecret:kClientSecret];

}

//-------------------------------------------------------------------------------------

-(BOOL)isAuthorized
{
    return [((GTMOAuth2Authentication *)self.driveService.authorizer) canAuthorize];
}

//-------------------------------------------------------------------------------------

-(GTMOAuth2ViewControllerTouch *)createAuthController
{    

    GTMOAuth2ViewControllerTouch *authController;
    authController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
                                                                clientID:kClientID
                                                            clientSecret:kClientSecret
                                                        keychainItemName:kKeychainItemName
                                                                delegate:self
                                                        finishedSelector:@selector(viewController:finishedWithAuth:error:)];

    [self presentViewController:authController animated:YES completion:Nil];
    return authController;
}
//-------------------------------------------------------------------------------------

-(void)viewController:(GTMOAuth2ViewControllerTouch *)viewController
      finishedWithAuth:(GTMOAuth2Authentication *)authResult
                 error:(NSError *)error
{    
    if (error != nil)
    {
        [self dismissViewControllerAnimated:YES completion:Nil];

        isAuthorized=NO;
        UIAlertView *alertForNoAuthentication=[[UIAlertView alloc]initWithTitle:@"Authentication Error" message:error.localizedDescription delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:Nil, nil];
        [alertForNoAuthentication show];
        self.driveService.authorizer = nil;
    }
    else
    {
        [self dismissViewControllerAnimated:YES completion:Nil];

        UIAlertView *alertForNoAuthentication=[[UIAlertView alloc]initWithTitle:@"Authentication successful" message:@"authortiozation done" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:Nil, nil];
        [alertForNoAuthentication show];

        isAuthorized=YES;

        self.driveService.authorizer = authResult;
    }
}

As soon as you run your app and fire up Google integration you will see the following screen on your device screen followed by another screen after entering the proper credentials.

Once you click on ‘Accept’  your authorization is complete and you can access files from Google Drive account within your app.

Add the following lines to the file where you want to access Google files. These lines of codes will show you the files for your root directory.

-(void)loadDriveFiles
{

    fileFetchStatusFailure = NO;

    //for more info about fetching the files check this link
    GTLQueryDrive *query = [GTLQueryDrive queryForFilesList];
    query.q = [NSString stringWithFormat:@"'%@' IN parents", @"root"];

    // queryTicket can be used to track the status of the request.
    [self.driveService executeQuery:query
                  completionHandler:^(GTLServiceTicket *ticket,
                                      GTLDriveFileList *files, NSError *error)
     {
         NSLog(@"error: %@", error.localizedDescription);
         GTLBatchQuery *batchQuery = [GTLBatchQuery batchQuery];

         //incase there is no files under this folder then we can avoid the fetching process

         if(error)
         {
             UIAlertView *alertForError=[[UIAlertView alloc]initWithTitle:@"ERROR" message:error.localizedDescription delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:Nil, nil];

             [alertForError show];

         }
         else
         {
             //an array to store files : driveFiles
             driveFiles = [[NSMutableArray alloc] init];
             [driveFiles addObjectsFromArray:files.items];

             if (driveFiles.count == 0)
             {
                 UIAlertView *noDataAlert=[[UIAlertView alloc]initWithTitle:@"NO FILE" message:@"No Files in google drive" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:Nil, nil];

                 [noDataAlert show];

             }
             else
             {
                 for (GTLDriveFile *driveFile in driveFiles)
                 {
                     //if you are showing files in a tableview
                     [tableViewForFiles reloadData];
                 }
             }
         }

         //finally execute the batch query. Since the file reterive process is much faster because it will get all file metadata info at once
         [self.driveService executeQuery:batchQuery
                       completionHandler:^(GTLServiceTicket *ticket,
                                           GTLDriveFile *file,
                                           NSError *error) {
                       }];

     }];
}

Below mentioned codes are another function that gets files from a particular folder. The only thing required for this is the folderID whose files have to be fetched.

void)printFilesInFolderWithService:(GTLServiceDrive *)service
                            folderId:(NSString *)folderId andName:(NSString *)name{

    // The service can be set to automatically fetch all pages of the result. More
    // information can be found on https://code.google.com/p/google-api-objectivec-client/wiki/Introduction#Result_Pages.
    service.shouldFetchNextPages = YES;

    [driveFiles removeAllObjects];

    GTLQueryDrive *query =
    [GTLQueryDrive queryForChildrenListWithFolderId:folderId];
    // queryTicket can be used to track the status of the request.
    GTLServiceTicket *queryTicket =
    [service executeQuery:query
        completionHandler:^(GTLServiceTicket *ticket,
                            GTLDriveChildList *children, NSError *error) {
            if (error == nil) {
                for (GTLDriveChildReference *child in children) {
                    NSLog(@"File Id: %@", child.identifier);

                    GTLQuery *query = [GTLQueryDrive queryForFilesGetWithFileId:child.identifier];

                    // queryTicket can be used to track the status of the request.
                    [self.driveService executeQuery:query
                                  completionHandler:^(GTLServiceTicket *ticket,
                                                      GTLDriveFile *file,
                                                      NSError *error) {

                                      NSLog(@"nfile name = %@", file.originalFilename);
                                      [driveFiles addObject:file];

                                      if (children.items.count==driveFiles.count)
                                      {
                                          [tableViewForFiles reloadData];
                                      }
                                  }];
                }
            } else {
                NSLog(@"An error occurred: %@", error);
            }
        }];
}

 

You can get the link of a file from the properties ‘embedLink’ and ‘webContentLink’ of ‘GTLDriveFile’. After that you can do anything you want from those files .

Maximum problems occur while archiving the app and instead of giving iOS App Archive it gives Xcode Generic Archive. But with above set of instructions, you will never get any problem while archiving also.

You can find sample code for the Google Drive integration in GitHub.

This is it. If you face any difficulty regarding the integration at any point, feel free to comment . Any suggestions for improvements will be appreciated. Hope it helps.

Where to go from here

Now you have integrated Google Drive in your project. There are some other cloud services offering storage and they are quite popular too. Read Integration of Dropbox in iOS applications and Integration of Box in iOS apps.

Manish Kumar

Manish Kumar is an iOS developer at Kolkata, who enjoys building innovative applications. Besides he also loves playing football and listening to songs. He loves challenges and sharing his work in open source community. Lots of iOS objective C development work is going on in Innofied. You can reach us at contact@innofied.com

  • Pingback: Box Integration in iOS apps Innofied()

  • Pingback: Integration of Dropbox in iOS applications Innofied()

  • Rudrarajsinh Chavda

    hey Manish …. can you please help me out for how to download photos from the drive in our application ?

    • Manish Kumar

      Hello Rudrarajsinh. I am afraid that I haven’t implemented that part yet. Let me have a look at that and come back as soon as possible.

      • Rudrarajsinh Chavda

        Thank you Manish for replying …. i am waiting . also one more thing can you please help me out how to fetches images from google drive ?

        • Manish Kumar

          Hello Rudrarajsinh. Here is the solution:

          
              NSString *downloadUrl = selectedFile.downloadUrl;
          NSLog(@"nngoogle drive file download url link = %@", downloadUrl);
              GTMHTTPFetcher *fetcher =
          [self.driveService.fetcherService fetcherWithURLString:downloadUrl];
              //async call to download the file data
              [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
                  if (error == nil) {
                      NSLog(@"nfile %@ downloaded successfully from google drive", selectedFile.title);
                      NSLog(@"selected file.mime type : %@", selectedFile.mimeType);
                  } else {
                      NSLog(@"An error occurred: %@", error);
                  }
          }];
          

          In the completion handler of the fetcher call you will get data of the image and using that you can create UIImage and after that use it in your way.

          I have tested the code and is working fine for me. if you still find any issues please let me know.

          • Rudrarajsinh Chavda

            Thank you brother .. but i have little confused so can you please tell me what is the use of ” selectedfile” and which is declared .

          • Manish Kumar

            The term “selectedFile” refers to the file that has been selected from Google Drive either by iteration or by clicking on the file.

          • Rudrarajsinh Chavda

            but how to retrieve file from specific folder i am not able to do. can you please make demo for me

          • Manish Kumar

            Go to this GitHub url : https://github.com/manishatinnofied/GoogleDriveTestIntegration

            I have uploaded a sample project. In the sample project there is example to view files in a particular folder and also to download an image. If you face any difficultty please let me know..

          • Rudrarajsinh Chavda

            Thank you brother …. let me checked …

          • Rudrarajsinh Chavda

            Thanks a lot brother ,,,,, its working …

          • Manish Kumar

            You are welcome Rudrarahsinh.

          • modi akhil

            how can i write this using SWIFT?

          • Manish Kumar

            Hi Modi… I haven’t actually implemented it in Swift till now. Will upload a sample project of that as soon as implement it.

          • modi akhil

            ok thanks for time 🙂

          • Dhananjaya Rana

            but for high length video this code is crashing. any other solution for high length video.

    • Manish Kumar
        if([file.fileExtension isEqualToString:@"jpg"]||[file.fileExtension isEqualToString:@"jpeg"]||[file.fileExtension isEqualToString:@"png"]||[file.fileExtension isEqualToString:@"gif"]||[file.fileExtension isEqualToString:@"tiff"]||[file.fileExtension isEqualToString:@"bmp"]){
                  
                  //download the image and show it on view
                  NSString *downloadUrl = file.downloadUrl;
                  NSLog(@"nn google drive file download url link = %@", downloadUrl);
                  GTMHTTPFetcher *fetcher =
                  [self.driveService.fetcherService fetcherWithURLString:downloadUrl];
                  //async call to download the file data
                  [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
                      if (error == nil) {
                          //TODO: Do whatever you want to do with image
                      } else {
                          NSLog(@"An error occurred: %@", error);
                      }
                  }];
              }
      
      • Rudrarajsinh Chavda

        Thanks a lot brother …

      • Jignesh Radadiya

        I have some issue to use this code for google drive implementation.
        I can’t download url property in file and one more thing i’m doing this with GTMSessionFetcher.
        Please help me how to download pdf file from google drive.

  • vikrant tanwar

    I have downloaded project by GitHub link but In this project GtlFramework missing. So how we can solve this problem.I got stuck on this issue from last 2 days. Please help me .

  • Cheng

    Thanks buddy, your tutorial is very clear and awesome. It help me a lot!!

    • Manish Kumar

      @disqus_jqYZHXai2H:disqus You’re welcome.

  • Rohit Rananaware

    Hi Manish ..can you please help me out for how to fetches particular images name from google drive ?

    • Manish Kumar

      Hi Rohit.. You want to fetch name of images only? No other files?

      • Rohit Rananaware

        yes i want fetch name images only and display on table view

        • Manish Kumar

          What you can do is after fetching the files from drive you can filter the images according to the extension or mime-type. In the sample project above I have made mime-type as well as extension check for all file types to show them in table view.

          • Rohit Rananaware

            ok thanks..

  • Rohit Rananaware

    hi manish can i handle file start downloading and end downloding

    • Manish Kumar

      How you want to handle that? May I know the purpose of this functionality.

      • Rohit Rananaware

        download file display progress view

        • Manish Kumar

          I don’t think they have any method to show progress view.

          • Rohit Rananaware

            start retrive image on google drive and save in data base after complit totoal process and dipsplay on callection view

          • Manish Kumar

            I think you need a completion handler for file download. Am I right?

          • Rohit Rananaware

            yes

          • Manish Kumar

            I haven’t implemented API for file download from Google Drive.

          • Manish Kumar

            In GoogleFileViewController.m go to function

            -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

            . There you can see file download implemented.

          • Rohit Rananaware

            Hi Manish
            I have create folder on google drive i want to save images inside the folder…i have save image on google drive not in folder .
            please suggest me

          • Manish Kumar

            Hello Rohit. I haven’t worked on this API and will take some time to look into this. I will try this out and will let you know if done.

          • Rohit Rananaware

            ok

  • Abhishek Shrivastava

    hi amit , i wanna start iOS shopping app just like flipkart, can u send me Reference tutorial of this type of project

    • Manish Kumar

      For now, i don’t have any reference tutorial of this type, but in future if I work on any such tutorial, you will surely get to know about that.

      • Abhishek Shrivastava

        ok thanks for reply manish

  • Kim Yu

    hey Manish …. can you please help me out for how to filter the drive file that deleted in recycle bin,i use the query.includeDeleted = NO,but it does not work ,can you help me ,thank you

    • Manish Kumar

      Hey Kim, let me check that out for a while.

    • Manish Kumar

      Do you want the trash files not to be included in the file list from drive?

      • Kim Yu

        yeah

        • Manish Kumar

          Hey Kim. Please download the sample project referenced in the blog. Go to GoogleFileViewController.m. In function

           -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

          you can find the check for trashed file.

          • Kim Yu

            i download the sample project and run,my drive file has nine files and recycle bin has one file ,but when i run the sample project,the table view show all the files ,ten files,i do not want the deleted file show,i am new hand ,please help me check it out ,thanks

          • Manish Kumar

            Hey Kim. Just Go to the function in my previous comment. There you will find a check for trash files that I have implemented in the first if condition. Apply the same if condition while adding the files to the datasource array.
            Just go to the function

            -(void)loadDriveFilesForForMyDrive

            and in place of the line

             [driveFiles addObjectsFromArray:files.items];

            add the following lines:

            
            for (GTLDriveFile *file in files.items){
                  if (file.labels.trashed.boolValue == NO){
                         [driveFiles addObject:file];
                   }
            }
            
          • Kim Yu

            Thank you very much,it worked.I have another question ,I got the image download url,and use the function
            [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
            if (error == nil)
            In there ,I use image = UIImage imageWithData:data
            } else {
            NSLog(@”An error occurred: %@”, error);
            }
            }];
            Those images in cells when I scroll the cell the image also changes ,I wander why?Can you help me

          • Manish Kumar

            I haven’t tried this out.. Will have to search a bit.

          • Kim Yu

            ok thanks for reply

          • Manish Kumar

            Hey Kim, I found no method where I could resize the Auth screen frame size. I think for now you have to go by the default size of the auth view.

          • Kim Yu

            ok,got it,Thanks very much

          • Manish Kumar

            You’re welcome Kim.

          • Kim Yu

            Excuse me,I Have a another question want to ask you ,Can I get all the folders number at once,if you know ,please show me,Thanks.

          • Manish Kumar

            Hello Kim, I searched for API providing folders number but couldn’t find any.

          • Kim Yu

            I had solve it,I also want to know how can we get the google drive file thumbnail image ,because I found it get the metadata will be very slowly.

          • Kim Yu

            Hey Manish.Excuse me,I want show Google Drive images in my APP,I tried this :alternateLink,downloadUrl,thumbnailLink.Seems they are not the original image ,But I want get the original image ,How? Please help me ,Thanks.

          • Kim Yu

            hey Manish ,I found run you demo when get into next folder and tap back button ,app crash this days,I do not know why,can you help me find it.

          • Kim Yu

            hey Manish,Excuse me,I got a problem,I create a app for google drive ,I use the downloadStr to download the image,I got the image,but I changed another google drive Email,I can’t download the image,shows “HTTPStatus Code=401″can you help me ?Thanks

          • Manish Kumar

            “but I changed another google drive Email”, what do you mean by this?

          • Kim Yu

            It’s means another user,in my app,I use downloadurl to fetch the image, I can download the image,and change another user Email,can’t download the image,same app and authorized already.

          • Manish Kumar

            I think it has got something to do with session maintainance of the google drive login that I have not implemented in the above app.

  • yatharth

    hey manish .. it would be a great help if you could provide the code to integrate google drive in an iOS App using swift 2.0 on Xcode version 7.0 …

    • Manish Kumar

      Hey Yatharth. I am working on a requirement, and not free now. But I will surely do that as soon as I am done with it.

      • Kim Yu

        ok thanks for reply manish

  • jeet

    Manish your tutorial not downloading the docx file, please give me some idea to do this ,
    BTW thanks for the tutorial

    • Manish Kumar

      Hello Jeet.
      I have implemented only download for PDF file through a file extension check. If you remove the check or include the docx file extension in the check, it will also download the docx file and save it inside the application.

  • Dhananjaya Rana

    I am trouble to fetching high length video from google drive. can you help me to fetching the high length videos?

    • Manish Kumar

      You want to download or play them online?

      • Dhananjaya Rana

        i want to download high length video. actually i am trying below code but it crashed

        GTMHTTPFetcher *fetcher = [driveService.fetcherService fetcherWithURLString:downloadURL];

        [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error)
        {
        if (error == nil) {

        }
        }

      • Dhananjaya Rana

        You have any idea for downloading the videos from google drive?

        • Manish Kumar

          I haven’t done that yet, but below you can see a code that is used for downloading image. You can use the same and see if it works.

          • Dhananjaya Rana

            thanx Manish, let me try actually below code giving memory issue for large video.

  • Ronak

    Crash When around 100 files in google drive [ i dont no why but i debug and print the file.title and show that file.title = (null) ] so crashed.

    • Manish Kumar

      It may be that, i haven’t checked for null titles, please put a check there for file title and it’s other properties.

  • Mahesh patel

    hello, how we get file and folder thumbnail ?

  • Rakhi goel

    Hi Guys…I am little stuck to create a client secret on “https://console.cloud.google.com” as I try to create using credential tab, I am able to create only API key and Client-id.

    Please help !!

  • Benjamin Lochard

    Would you be able to help me? I am having issues with navigation. When i try to go back a folder, it crashes.

    *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil’

  • Michael Ross

    Hey Manish,

    Great tutorial. Thanks so much for your help. I am having a code 400 error.

    Code So far:
    //File selected from tableview
    self.selectedFile = selectedFile;
    //URL generation
    NSString *url = [NSString stringWithFormat:@”https://www.googleapis.com/drive/v3/files/%@?alt=media”,
    self.selectedFile.identifier];
    //Forming Fetcher
    GTMSessionFetcher *fetcher = [self.service.fetcherService fetcherWithURLString:url];
    //Making Request
    [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {

    if (error == nil) {

    NSLog(@”Retrieved file content”);
    // Do something with data

    } else {

    NSLog(@”An error occurred: %@”, error);
    }

    }];

    Error returned again is code 400. Sign in works without difficulty as does tableview request and population. Any ideas how to troubleshoot this? Any help is appreciated.

    • Manish Kumar

      Hi Michael,
      I was not able to find this issue. Can you please explain the scenario of the issue. What type of files you are downloading when this issue is happening?

      • Ejaz Khan

        @manishatinnofied:disqus.
        Hi,

        i am unable to download file using Google drive V3 api.The code you have provided in the tutorial is V2 api.i am getting the same error as Michael.please help.