7

I plan to use Google Drive API in my Swift project. I'm trying to add the Drive SDK via CocoaPods (v0.39.0). Below is my Podfile.

platform :ios, '8.0'
use_frameworks!

pod 'Google-API-Client/Drive'

I have the use_frameworks! flag added so that CocoaPods can convert Objective-C pods to Swift frameworks instead of static libraries.

Pod installation is successful. However when I build the project, I get the following error.

Duplicate interface definition for class 'GTMHTTPUploadFetcher'

Deleting DerivedData folder and cleaning the project didn't work.

I also tried without adding the use_frameworks! and then adding the library via a bridging header way. That works without an issue. The thing is all my other dependencies work with it turned on. And unfortunately CocoaPods doesn't support turning that flag for certain pods only.

Is there a workaround to resolve this issue?


As stated in Google's docs, Google engineers supposedly monitor questions tagged with google-drive-sdk so I hope at least they'll see this and fix it soon.

Isuru
  • 30,617
  • 60
  • 187
  • 303

4 Answers4

4

According to Google this error is caused by using a cocoapod by a third party, but they now have an official pod in the project (https://github.com/google/google-api-objectivec-client/blob/master/GoogleAPIClient.podspec) and the problem should be fixed.

See: https://github.com/google/google-api-objectivec-client/issues/103

Use:

pod 'GoogleAPIClient/Drive', '~> 1.0'

and probably also:

pod 'GTMOAuth2' or pod 'Google/SignIn'

emem
  • 5,588
  • 1
  • 24
  • 30
3

I ran into this same problem. My solution was to not install the Google API Client for iOS using CocoaPods because I was using Swift-based pods and I, therefore, could not remove use_frameworks! to attempt to get around the duplicate header issue.

I instead installed the library manually by following the detailed instructions at https://developers.google.com/drive/ios/quickstart?ver=swift for Steps 2, 3, and 4. I followed the instructions but applied them to my existing workspace instead of creating a new workspace.

It's important to note that I had to adjust the paths in User Header Search Paths to match the locations where I actually copied the source code from Google.

I'm copying the instructions here for reference.

Step 2: Download the Google Client Library

Run the following commands to download the library using git:

  • git clone https://github.com/google/google-api-objectivec-client.git
  • git clone https://github.com/google/gtm-oauth2.git
  • git clone https://github.com/google/gtm-session-fetcher.git
  • git clone https://github.com/stig/json-framework.git -b v2.3
  • cp -R gtm-oauth2/Source google-api-objectivec-client/Source/OAuth2
  • cp -R json-framework/Classes google-api-objectivec-client/Source/JSON

Step 3: Prepare the workspace

Open Xcode and create a new workspace named "Quickstart". Using File > Add Files to "Quickstart"..., add the following projects to the workspace from the libraries you cloned in the previous step:

  • google-api-objectivec-client/Source/GTL.xcodeproj
  • gtm-session-fetcher/Source/GTMSessionFetcher.xcodeproj

Select the "GTMSessionFetcher" project and make the following changes:

  • Add a new target of the type iOS > Framework & Library> Cocoa Touch Static Library and name it "GTMSessionFetcherLib".
  • Add all of the .m files in the project's GTMSessionFetcher group to the target's Build Phases > Compile Sources section.

Select the "GTL" project's "GTLTouchStaticLib" target and make the following changes:

  • Add the library GTMSessionFetcher/libGTMSessionFetcherLib.a to Build Phases > Link Binary with Libraries.
  • Add the absolute path to gtm-session-fetcher/Source/ to Build Settings > User Header Search Paths.
  • Add the flag GTM_USE_SESSION_FETCHER=1 to Build Settings > Preprocessor Macros.
  • Delete the "GTL" project's "GTLFramework" target.
  • In the Project navigator, delete GTL project's GTL Source > Common > HTTPFetcher group.

Step 4: Prepare the project

  • Create a new iOS > Application > Single View Application project named "QuickstartApp". Set the Language to Swift , and when saving the project set the Add to and Group fields to "Quickstart".
  • Add the following frameworks and libraries to the project's Build Phases > Link Binary with Libraries section: libGTLTouchStaticLib.a
    • Security.framework
    • SystemConfiguration.framework
  • Change the following Build Settings:
  • Add -ObjC -all_load to Other Linker Flags.
  • Add the absolute path to the following directories to User Header Search Paths:
    • gtm-session-fetcher/Source/
    • google-api-objectivec-client/Source/**
  • Add the flag GTM_USE_SESSION_FETCHER=1 to Preprocessor Macros.
  • Add the file google-api-objectivec-client/Source/OAuth2/Touch/GTMOAuth2ViewTouch.xib to the project's Supporting Files group.
  • Add the following files to the QuickstartApp group:
    • google-api-objectivec-client/Source/Services/Drive/Generated/GTLDrive_Sources.m
    • google-api-objectivec-client/Source/Services/Drive/Generated/GTLDrive.h
  • If not created automatically, create a new header file Bridging-Header.h with the following content:
    • #import "GTMOAuth2ViewControllerTouch.h"
    • #import "GTLDrive.h"
  • Set Build Settings > Objective-C Bridging Header to the absolute path of the bridging header.
Daniel Zhang
  • 5,778
  • 2
  • 23
  • 28
  • Thanks for the response. I just gave it a try and it works. Although it doesn't fix the original issue, since it works, I'm gonna accept it for the time being. Thank you. I can't believe Google is neglecting this. It's an issue that's been around for months! – Isuru Dec 04 '15 at 05:04
  • Thanks @Isuru. I couldn't believe how complicated it was to install. I'm sure it will be easier once they revise the code and your original issue may even be fixed. It's been a longstanding issue, like you said. – Daniel Zhang Dec 04 '15 at 05:30
  • Yeah. It's ridiculously complicated. I expect a little more support from Google for distributing their iOS SDKs since they explicitly said they'll use CocoaPods as the main channel. – Isuru Dec 04 '15 at 08:01
  • @Daniel :- "Select the "GTL" project's "GTLTouchStaticLib" target and make the following changes: Add the library GTMSessionFetcher/libGTMSessionFetcherLib.a to Build Phases > Link Binary with Libraries." i am not finding that GTMSessionFetcher/libGTMSessionFetcherLib.a , please elaborate on this issue ! – dip Dec 21 '15 at 11:46
  • @dip The `GTLTouchStaticLib` **target** should be available under the `GTL` project inside your project. The `libGTMSessionFetcherLib.a` comes from the `GTMSessionFetcher` **project** inside your project. I know it's a difficult install, but the directions provided by Google are valid. – Daniel Zhang Dec 21 '15 at 21:15
  • yes @Daniel, i followed instructions as mentioned on google site, but this line mentioned by you "Select the "GTL" project's "GTLTouchStaticLib" target and make the following changes:" i am not finding any "GTLTouchStaticLib" target under GTL project ! :( – dip Dec 22 '15 at 07:31
  • where can I find the GTLTouchStaticLib in GTLCore.xcodeproj? – pash3r Jan 13 '16 at 08:50
  • I am not finding it either :( – Myoch Feb 29 '16 at 22:49
0

The only workaround I found was that you have to go into those three projects that Google Drive imports and check how the imports are done. Right now its importing headers, not frameworks (the three frameworks depend on each other). You have to just do it manually and it'll work.

I don't have code samples to show you but I know I got it to work last time in this fashion.

KVISH
  • 12,923
  • 17
  • 86
  • 162
0

Simple solution here:

Go to edit scheme -> Select Build -> Build option untick the Parallelize Build

Now run your App

Divyang Desai
  • 7,483
  • 13
  • 50
  • 76
SriMa
  • 197
  • 1
  • 1
  • 12