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

