Fix for Google Analytics pod not working in Swift framework

Recently, I have been working on a mobile app SDK for a client, both in Android and iOS. The Android SDK is packaged as an AAR while the iOS is packaged as a Swift framework.

The SDK uses Google Analytics. The problem arose when using the Google Analytics iOS SDK – it works fine when used in an app but not in a framework. Each paragraph below documents the steps I took, concluding with the fix 😛

Google Analytics was added to the project via CocoaPods – sample of Podfile:

# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'

target 'MySDK' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  pod 'GoogleAnalytics', '~> 3.17'
end

Running the statement var tracker : GAITracker? in a Swift file gave rise to the error “Use of undeclared type ‘GAITracker'”.

Adding the Objective-C bridging headers in MySDK.h gave rise to errors such as “Include of non-modular header inside framework module ‘MySDK’: ‘/path/to/MySDK/Pods/Headers/Public/GoogleAnalytics/GAI.h'” – sample as follows:

//  MySDK.h
#import <UIKit/UIKit.h>

//! Project version number for MySDK.
FOUNDATION_EXPORT double MySDKVersionNumber;

//! Project version string for MySDK.
FOUNDATION_EXPORT const unsigned char MySDKVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <MySDK/PublicHeader.h>

// Bridging headers for Google Analytics
#import <GoogleAnalytics/GAI.h>
#import <GoogleAnalytics/GAIDictionaryBuilder.h>
#import <GoogleAnalytics/GAIEcommerceFields.h>
#import <GoogleAnalytics/GAIEcommerceProduct.h>
#import <GoogleAnalytics/GAIEcommerceProductAction.h>
#import <GoogleAnalytics/GAIEcommercePromotion.h>
#import <GoogleAnalytics/GAIFields.h>
#import <GoogleAnalytics/GAILogger.h>
#import <GoogleAnalytics/GAITrackedViewController.h>
#import <GoogleAnalytics/GAITracker.h>

Tried setting “Allow Non-modular Includes in Framework Modules” to YES under Target > Build Settings as well as removing Google Analytics from Target > Build Settings > Search Paths but to no avail.

Finally, after 3 days of pulling my hair out (figuratively), I came across a comment by @ivanbuhov at https://github.com/NativeScript/ios-runtime/issues/524#issuecomment-193777593 which pointed to a non-working module.modulemap in the Google Analytics pod. The issue was fixed by creating a module.modulemap in Pods/Headers/Public/GoogleAnalytics after running pod install, containing the following:

module GoogleAnalytics {
  header "GAI.h"
  header "GAIDictionaryBuilder.h"
  header "GAIEcommerceFields.h"
  header "GAIEcommerceProduct.h"
  header "GAIEcommerceProductAction.h"
  header "GAIEcommercePromotion.h"
  header "GAIFields.h"
  header "GAILogger.h"
  header "GAITrackedViewController.h"
  header "GAITracker.h"
  export *
}

And yes, the fix works without meddling with the bridging headers or search paths. Till the next problem, adhuc 😛


[UPDATE 15 AUG 2018]

Kinda got tired of manually creating module.modulemap every time after running pod install or pod update. I created and committed a file, module.modulemap.dist, in the root of my Swift framework repository (same directory as the Podfile), with the contents above and added the following post-install script at the end of the Podfile, which simply copies the file over on my behalf 🙂

post_install do |installer|
  system("echo '/* START post install scripts */'")
  system("cp module.modulemap.dist Pods/Headers/Public/GoogleAnalytics/module.modulemap && echo '- Fixed import of GoogleAnalytics module'")
  system("echo '/* END post install scripts */'")
end