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