简体   繁体   中英

ios Google Analytics campaign tracking

i set up Google Analytics for my iOS-App and it is basically working fine (Screen Tracking, Purchases,...), except the install Campaign tracking is not ok. I saw a similar question here which is not solved: Google analytics iOS campaign tracking testing on development

This is the guide i used to implement (is in Objective-C): https://developers.google.com/analytics/devguides/collection/ios/v3/campaigns#general-campaigns

I see in my Google Analytics Dashboard the referrer installs, but no campaign installs.

This is a test Url

https://click.google-analytics.com/redirect?tid=UA-51157298-2&url=https%3A%2F%2Fitunes.apple.com%2Fat%2Fapp%2Fbikersos-motorrad-unfall-sos%2Fid980886530&aid=com.BikerApps.BikerSOS&idfa=%{idfa}&cs=test_source&cm=test_medium&cn=test_campaign&cc=test_campaign_content&ck=test_term

which i generated here: https://developers.google.com/analytics/devguides/collection/ios/v3/campaigns#url-builder

My Code which should track the install is the following:

AppDelegate:

//Method where app parses any URL parameters used in the launch
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

    //Track google Analytics URL
    GAService.shared.trackURL(url)

    //some other handlers here ....
    return true/false
}

GAService Singleton:

@objc public class GAService : NSObject {
private let trackID : String = "UA-xxxxxx-x"

var trackGoogleAnalytics : Bool = Constants.Analytics.trackGoogleAnalytics
private let UTM_SOURCE_KEY : String = "xxx"
private let UTM_MEDIUM_KEY : String = "xxx"
private let UTM_CAMPAIGN_KEY : String = "xxx"
var trackUncaughtExceptions : Bool = true
var tracker : GAITracker? = nil

static let shared = GAService()

var UtmSource : String {
    get {
        if let utm = UserDefaults.standard.string(forKey: UTM_SOURCE_KEY) {
            return utm
        }
        return ""
    }
    set {
        if UserDefaults.standard.string(forKey: UTM_SOURCE_KEY) == nil {
            UserDefaults.standard.set(newValue, forKey: UTM_SOURCE_KEY)
            UserDefaults.standard.synchronize()
        }
    }
}
var UtmCampaign : String {
    get {
        if let utm = UserDefaults.standard.string(forKey: UTM_CAMPAIGN_KEY) {
            return utm
        }
        return ""
    }
    set {
        if UserDefaults.standard.string(forKey: UTM_CAMPAIGN_KEY) == nil {
            UserDefaults.standard.set(newValue, forKey: UTM_CAMPAIGN_KEY)
            UserDefaults.standard.synchronize()
        }
    }
}
var UtmMedium : String {
    get {
        if let utm = UserDefaults.standard.string(forKey: UTM_MEDIUM_KEY) {
            return utm
        }
        return ""
    }
    set {
        if UserDefaults.standard.string(forKey: UTM_MEDIUM_KEY) == nil {
            UserDefaults.standard.set(newValue, forKey: UTM_MEDIUM_KEY)
            UserDefaults.standard.synchronize()
        }
    }
}
private override init() {
    super.init()

    if(trackGoogleAnalytics) {
        tracker = GAI.sharedInstance().tracker(withTrackingId: trackID)
        tracker!.allowIDFACollection = true

        GAI.sharedInstance().trackUncaughtExceptions = trackUncaughtExceptions
        GAI.sharedInstance().logger.logLevel = GAILogLevel.error
        GAI.sharedInstance().dispatchInterval = 1
    }
}

public func trackURL(_ url : URL){
    let urlString = url.absoluteString
    // setCampaignParametersFromUrl: parses Google Analytics campaign ("UTM")
    // parameters from a string url into a Map that can be set on a Tracker.
    let hitParams : GAIDictionaryBuilder = GAIDictionaryBuilder()

    // Set campaign data on the map, not the tracker directly because it only
    // needs to be sent once.
    hitParams.setCampaignParametersFromUrl(urlString)

    // Campaign source is the only required campaign field. If previous call
    // did not set a campaign source, use the hostname as a referrer instead.
    if((hitParams.get(kGAICampaignSource) != nil) && (url.host ?? "").length() != 0) {
        hitParams.set("referrer", forKey: kGAICampaignMedium)
        hitParams.set(url.host, forKey: kGAICampaignSource)
    }
    let hitParamsDict : [AnyHashable : Any] =  hitParams.build() as Dictionary as [AnyHashable : Any]

    if(hitParamsDict.count > 0) {
        // A screen name is required for a screen view.
        let source : String? = hitParams.get(kGAICampaignSource)
        let medium : String? = hitParams.get(kGAICampaignMedium)
        let campaign : String? =  hitParams.get(kGAICampaignName)
        if(source != nil || medium != nil || campaign != nil) {
            tracker?.set(kGAIScreenName, value: "openUrl")
            GAService.shared.UtmSource = source ?? ""
            GAService.shared.UtmMedium = medium ?? ""
            GAService.shared.UtmCampaign = campaign ?? ""
        }

        // SDK Version 3.08 and up.
        //[tracker send:[[[GAIDictionaryBuilder createScreenView] setAll:hitParamsDict] build]];
        let sendDict : [AnyHashable : Any] =  GAIDictionaryBuilder.createScreenView().setAll(hitParamsDict).build() as Dictionary as [AnyHashable : Any]
        tracker?.send(sendDict)
        tracker?.set(kGAIScreenName, value: nil)
    }
}

As i have to set a screenName for such a tracking i defined openUrl as a constant and set it to nil afterwards i sent the dictionary.

I hope anybody can see what i'm doing wrong

thank you in advance

I think that Google Analytics docs are very poor on this subject. If you look carefully in what is written in the main guide for "Campaign Measurement" it says "After an app has been installed, it may be launched by referrals from ad campaigns, websites, or other apps" and Google gives an example with custom url scheme which is handled.

Hopefully, there is another guide https://developers.google.com/analytics/solutions/mobile-campaign-deep-link which describes how to use deep linking for campaign measurement.

So, if you want to track campaign measurement you must use either Universal Links mechanism or custom url scheme for your application.

Universal Links mechanism is the preferred way if you have backend and hence can decide where to redirect user: in iTunes or in application.

Assume, you have a site link https://example.com/openapp which redirects user to iTunes Connect. You should insert you Universal Link address ( https://example.com/openapp ) in the generator https://developers.google.com/analytics/devguides/collection/ios/v3/campaigns#url-builder .

I used it with deep link where I decide the navigation:

let tracker1 = GAI.sharedInstance().tracker(withTrackingId: "...")
            let hitParams = GAIDictionaryBuilder()
            hitParams.setCampaignParametersFromUrl(path)
            let medium = self.getQueryStringParameter(url: path, param: "utm_medium")

            hitParams.set(medium, forKey: kGAICampaignMedium)
            hitParams.set(path, forKey: kGAICampaignSource)

            let hitParamsDict = hitParams.build()

            tracker1?.allowIDFACollection = true

            tracker1?.set(kGAIScreenName, value: "...")
            tracker1?.send(GAIDictionaryBuilder.createScreenView().setAll(hitParamsDict as? [AnyHashable : Any]).build() as? [AnyHashable : Any])

// this is for url utm_medium parameter

/*
func getQueryStringParameter(url: String, param: String) -> String? {
    guard let url = URLComponents(string: url) else { return nil }
    return url.queryItems?.first(where: { $0.name == param })?.value
}*/

then I saw the source on google analytics.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM