13

I am following the Analytics for iOS (developers.google.com/analytics/devguides/collection/ios/v3/?ver=swift) guide and I've got errors in my Swift code Project that I can't fix. I am working with XCode 6.4, Swift and the iOS Deployment Target 8.1.

Step 1

First I installed a Google SDK using CocoaPods. This is the console result after running pod install command:

Updating local specs repositories

CocoaPods 1.0.0.beta.2 is available.
To update use: `gem install cocoapods --pre`
[!] This is a test version we'd love you to try.

For more information see http://blog.cocoapods.org
and the CHANGELOG for this version http://git.io/BaH8pQ.

Analyzing dependencies
Downloading dependencies
Using Google (1.0.7)
Using GoogleAnalytics (3.14.0)
Using GoogleNetworkingUtilities (1.0.0)
Using GoogleSymbolUtilities (1.0.3)
Using GoogleUtilities (1.1.0)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There is 1 dependency from the
Podfile and 5 total pods installed.

Step 2

Then opened, as said in the guide, my app's Project .xcworkspace file.

My Podfile looks like this:

# Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
# use_frameworks!

target 'XXXXXX' do

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.1'
pod 'Google/Analytics', '~> 1.0.0'

end

target 'XXXXXXTests' do

pod 'Google/Analytics', '~> 1.0.0'

end

Where XXXXXX is my Project's name.

Step 3

I got the configuration file GoogleService-Info.plist and included in my Project adding all the targets (2 targets in my project).

Step 4

I created a BridgingHeader by by choosing File > New > File > iOS > Source > Header File. I named it BridgingHeader.h and is in the root of my Project. The content is:

#ifndef XXXXX_BridgingHeader_h
#define XXXXX_BridgingHeader_h

#import "Google/Analytics.h"
#import <Google/Analytics.h>
#include "GAI.h"

#import <CoreData/CoreData.h>
#import <SystemConfiguration/SystemConfiguration.h>

#import "Libraries/GoogleAnalytics/GAI.h"
#import "Libraries/GoogleAnalytics/GAIFields.h"
#import "Libraries/GoogleAnalytics/GAILogger.h"
#import "Libraries/GoogleAnalytics/GAITracker.h"
#import "Libraries/GoogleAnalytics/GAIDictionaryBuilder.h"

#endif

Where "XXXXX" is my Project's name.

Step 5

Now the problems: I tried to include/import the Google Analytics into my AppDelegate.swift but I can't. This is the error:

AppDelegate.swift import Google Analytics

I also tried import "Google/Analytics.h" but another error appears: Expected identifier in import declaration.

  • How can I fix this so XCode doesn't give me errors?
  • Is the BridgingHeader wrong? Do I have to point at this somehow to recognize its inner headers?
  • Do I have to configure something else for the Google Analytics that I am missing right now?

Thank you very much.

oscar
  • 189
  • 1
  • 2
  • 11

5 Answers5

34

There are two options for implementation with Google Analytics using CocoaPods.

  1. pod 'Google/Analytics'
  2. pod 'GoogleAnalytics'

There are pros and cons between them.

pod 'Google/Analytics'

  • need google configuration file(GoogleService-Info.plist)
  • simple bridging header file. Just add #import <Google/Analytics.h> in bridging header file.
  • add import Googlein every file you want to implement google analytics.

pod 'GoogleAnalytics'

  • no google configuration file(GoogleService-Info.plist)
  • more complex bridging header file.

I prefer to use pod 'GoogleAnalytics' but I'll explain how to solve this issue using pod 'Google/Analytics' because the google official site recommends pod 'Google/Analytics'.

  1. bridging header

You just need one line of code for google analytics.

#import <Google/Analytics.h>

Don't forget to set target-build setting for Objective-C-Bridging-Header. You have to provide correct path to enable Objective-C-Bridging-Header.

Set Target-Build Setting-Objective-C-Bridging-Header $(SRCROOT)/$(PRODUCT_NAME)/projectName_Bridging_Header.h

  1. AppDelegate.swift
import Google

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?)
-> Bool { self.setupGoogleAnalytics()
..
     self.setupGoogleAnalytics()
..
 }

func setupGoogleAnalytics() {

    // Configure tracker from GoogleService-Info.plist.
    let configureError:NSError?
    GGLContext.sharedInstance().configureWithError(&configureError)
    assert(configureError == nil, "Error configuring Google services: \(configureError)")

    let gai = GAI.sharedInstance()
    gai.trackUncaughtExceptions = true  // report uncaught exceptions
    gai.logger.logLevel = GAILogLevel.Verbose  // remove before app release
}
  1. SomeViewController.swift
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    if let default_tracker = GAI.sharedInstance().defaultTracker {
        #if DEBUG

            print("default tracker")

        #endif
    }

    //        let tracker = GAI.sharedInstance().defaultTracker
    let tracker = GAI.sharedInstance().trackerWithTrackingId("tracking_ID")
    tracker.set(kGAIScreenName, value: screenName)
    let builder = GAIDictionaryBuilder.createScreenView()
    tracker.send(builder.build() as [NSObject : AnyObject])

}

Why do I use trackerWithTrackingId instead of defaultTracker property? You could got an error if you use defaultTracker :

fatal error: unexpectedly found nil while unwrapping an Optional value

defaultTracker property's initial value is nil, but it will be set after trackerWithTrackingId method is called. But it doesn't work perfectly sometimes. To avoid this issue, I recommend that use trackerWithTrackingId method directly.

I make the sample project using pod 'GoogleAnalytics'. You can get an idea from it. Good luck.

Test Env

GoogleAnalytics 3.14

Xcode 7.2.1

sangjoon moon
  • 720
  • 7
  • 8
  • I want to use GoogleAnalytics in my framework target. The problem is that framework target doesn't support bridging header, and both the pods above do not work for me. Do you have any recommendation to make it work? – user1615898 Apr 03 '17 at 04:36
  • 1
    @user1615898, I think that you have two options: 1) use firebase analytics. It doesn't need to create bridging header. 2) you can set up Google Analytics manually with Google Analytics Services SDK. More info and instructions are here: https://developers.google.com/analytics/devguides/collection/ios/v3/sdk-download – sangjoon moon Apr 06 '17 at 13:52
9

In Podfile

pod 'Google/Analytics'

In YourFantasticProjectName-Bridging-Header.h

#import "Google/Analytics.h"

You don't need this

GGLContext.sharedInstance().configureWithError(&configureError)

You need to have a proper tracker

let gai = GAI.sharedInstance()
let tracker = gai.tracker(withTrackingId: "UA-12345678-1")

In order for live view to work in GA dashboard, you must track screen using GAIDictionaryBuilder and correct key kGAIScreenName

tracker.set(kGAIScreenName, value: "this is my screen")
let event = GAIDictionaryBuilder.createScreenView()
tracker?.send(event!.build() as! [NSObject: Any])

In the same vein, to track events, you need to use GAIDictionaryBuilder as it will create dictionary with correct GA keys, and GA likes correct keys

let event = GAIDictionaryBuilder.createEvent(withCategory: "category", action: "action", label: "level", value: NSNumber(value: 120))
tracker?.send(event!.build() as! [NSObject: Any])

It seems to work in the simulator too

onmyway133
  • 45,645
  • 31
  • 257
  • 263
8

I faced the same problem. I could not import the "Google/Analytics.h" header as Xcode generate error. Because "Google/Analytics.h" header is not available in the 'GoogleAnalytics sdk' as mentioned in Google's Official page.

So, i just used following line

#import "GAI.h"

Hope it will work just fine. Environment Xcode: 8.2 iOS :10.2

Rubaiyat Jahan Mumu
  • 3,887
  • 1
  • 33
  • 35
3

For swift 3:

    var configureError:NSError? = nil
    GGLContext.sharedInstance().configureWithError(&configureError)
    assert(configureError == nil, "Error configuring Google services: \(configureError)")
    let gai = GAI.sharedInstance()
    gai?.trackUncaughtExceptions = true
    gai?.logger.logLevel = GAILogLevel.verbose
Patricio Bravo
  • 406
  • 6
  • 8
1

I think it's better to send error to crashlytics, but continue executing an app:

func configureGoogleAnalytics() {
    var configureError: NSError? = nil
    GGLContext.sharedInstance().configureWithError(&configureError)
    if configureError != nil {
        Crashlytics.sharedInstance().recordError(configureError!)
    }
}

Also check this answer for newest way to add analytics.

Nike Kov
  • 12,630
  • 8
  • 75
  • 122