From 24fa09b4f7c77578e51d6634ebc6f830ba36ecac Mon Sep 17 00:00:00 2001 From: "John C. Daub" Date: Sat, 23 May 2015 12:57:48 -0500 Subject: [PATCH 1/5] Bumping sample version, for better tracking display --- Example/HEAnalyticsExample/Info.plist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/HEAnalyticsExample/Info.plist b/Example/HEAnalyticsExample/Info.plist index 2341261..af745a8 100644 --- a/Example/HEAnalyticsExample/Info.plist +++ b/Example/HEAnalyticsExample/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.0.0 CFBundleSignature ???? CFBundleVersion - 1 + 2 LSRequiresIPhoneOS UILaunchStoryboardName From 93fe1c1736a29cbb446aaef24dfc1e5ebe808686 Mon Sep 17 00:00:00 2001 From: "John C. Daub" Date: Sat, 23 May 2015 12:58:00 -0500 Subject: [PATCH 2/5] Setting deployment back to 8.0, so I can work with Xcod 6.3.2 --- Example/HEAnalyticsExample.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Example/HEAnalyticsExample.xcodeproj/project.pbxproj b/Example/HEAnalyticsExample.xcodeproj/project.pbxproj index 939b343..abd7dd5 100644 --- a/Example/HEAnalyticsExample.xcodeproj/project.pbxproj +++ b/Example/HEAnalyticsExample.xcodeproj/project.pbxproj @@ -467,6 +467,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = HEAnalyticsExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "HEAnalyticsExample/HEAnalyticsExample-Bridging-Header.h"; @@ -479,6 +480,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = HEAnalyticsExample/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "HEAnalyticsExample/HEAnalyticsExample-Bridging-Header.h"; @@ -498,6 +500,7 @@ "$(inherited)", ); INFOPLIST_FILE = HEAnalyticsExampleTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HEAnalyticsExample.app/HEAnalyticsExample"; @@ -513,6 +516,7 @@ "$(inherited)", ); INFOPLIST_FILE = HEAnalyticsExampleTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HEAnalyticsExample.app/HEAnalyticsExample"; From 05e18c5de251bcfad0cc1f197aa7e37e05644065 Mon Sep 17 00:00:00 2001 From: "John C. Daub" Date: Sat, 23 May 2015 12:58:42 -0500 Subject: [PATCH 3/5] refactor out the app version code from Flurry into the base class, then add it to GAI --- HEAnalytics/HEAnalyticsPlatform.swift | 16 ++++++++++++++++ HEAnalytics/HEAnalyticsPlatformFlurry.swift | 14 -------------- HEAnalytics/HEAnalyticsPlatformGAI.swift | 4 +++- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/HEAnalytics/HEAnalyticsPlatform.swift b/HEAnalytics/HEAnalyticsPlatform.swift index c2c2ebc..4c0c761 100644 --- a/HEAnalytics/HEAnalyticsPlatform.swift +++ b/HEAnalytics/HEAnalyticsPlatform.swift @@ -117,6 +117,22 @@ public class HEAnalyticsPlatform: NSObject { // No need to call `super`. } + + /** + Internal function for obtaining the app version. + + I like using the `CFBundleShortVersionString` as either a semantic or marketing version, such as "x.y.z". The `CFBundleVersion` then is used as a simple forever-incrementing integer build number. We will concatenate the two versions for a more descriptive version that if an analytics SDK supports it, we can use to set it to have a more robust version reporting. + + :returns: an app version string. + */ + internal func appVersion() -> String { + let infoDict = NSBundle.mainBundle().infoDictionary! + let shortVersion = infoDict["CFBundleShortVersionString"] as! String + let bundleVersion = infoDict["CFBundleVersion"] as! String + let fullVersion = shortVersion + "." + bundleVersion + return fullVersion + } + /** A helper for obtaining the UIViewController "title" for use in trackView(). diff --git a/HEAnalytics/HEAnalyticsPlatformFlurry.swift b/HEAnalytics/HEAnalyticsPlatformFlurry.swift index bb30624..f9d9672 100644 --- a/HEAnalytics/HEAnalyticsPlatformFlurry.swift +++ b/HEAnalytics/HEAnalyticsPlatformFlurry.swift @@ -71,20 +71,6 @@ class HEAnalyticsPlatformFlurry: HEAnalyticsPlatform { } - internal func appVersion() -> String { - // Hsoi 2015-04-04 - Flurry uses the CFBUndleVersion to report versions. I tend to like using the - // CFBundleShortVersionString for marketing version (e.g. "major.minor.bugfix") and the CFBundleVersion - // for a simple incrementing build integer/number. So we'll make our own version number here to - // force into Flurry so I can know exactly what I'm working with. - // - // If you'd like a different approach, subclass and override. - let infoDict = NSBundle.mainBundle().infoDictionary! - let shortVersion = infoDict["CFBundleShortVersionString"] as! String - let bundleVersion = infoDict["CFBundleVersion"] as! String - let flurryVersion = shortVersion + "." + bundleVersion - return flurryVersion - } - override var optOut: Bool { didSet { diff --git a/HEAnalytics/HEAnalyticsPlatformGAI.swift b/HEAnalytics/HEAnalyticsPlatformGAI.swift index 7e1b9c9..6a0a3ef 100644 --- a/HEAnalytics/HEAnalyticsPlatformGAI.swift +++ b/HEAnalytics/HEAnalyticsPlatformGAI.swift @@ -79,11 +79,13 @@ class HEAnalyticsPlatformGAI: HEAnalyticsPlatform { GAI.sharedInstance().defaultTracker.allowIDFACollection = allowIDFACollection } + // Hsoi 2015-05-23 - https://groups.google.com/forum/#!topic/ga-mobile-app-analytics/U4nqqBnBhjU + GAI.sharedInstance().defaultTracker.set(kGAIAppVersion, value: self.appVersion()) super.initializePlatform(platformData) } - + override var optOut: Bool { didSet { GAI.sharedInstance().optOut = self.optOut From 86a4d9d74b01768e483a7189c54b9357c3551941 Mon Sep 17 00:00:00 2001 From: "John C. Daub" Date: Sun, 24 May 2015 04:17:42 -0500 Subject: [PATCH 4/5] fix bundle identifier --- Example/HEAnalyticsExample/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/HEAnalyticsExample/Info.plist b/Example/HEAnalyticsExample/Info.plist index af745a8..f8c2a44 100644 --- a/Example/HEAnalyticsExample/Info.plist +++ b/Example/HEAnalyticsExample/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.hsoienterprises.heanalyticssample.$(PRODUCT_NAME:rfc1034identifier) + com.hsoienterprises.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName From eb58f5f24710362d4ccc25d70eda0c7d0b35f60a Mon Sep 17 00:00:00 2001 From: "John C. Daub" Date: Sun, 24 May 2015 04:22:34 -0500 Subject: [PATCH 5/5] update readme with app version info --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ddf8198..38f98fb 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ It enables logic for converting the data-to-track into something the analytics A Developed with -- Xcode 6.4 beta 2 (should work with Xcode 6.3.1) +- Xcode 6.3.2 - Swift 1.2 - iOS 8 @@ -135,6 +135,12 @@ Event tracking is performed by filling out an `HEAnalyticsData` object and passi View tracking can be performed by invoking `HEAnalytics.trackView()`, passing the `UIViewController` you wish to track. Invoking `trackView()` can technically be done anywhere, but makes most sense to be called in your `UIViewController` subclass override of `viewDidAppear()`. To facilitate view tracking, `HEAnalytics` extends `UIViewController` with the `HE_analyticsViewTrackingTitle()` function. This function is intended to provide a stable value for analytics view tracking. By default it returns the `viewController.title` if it is non-nil and non-empty, else returns the name of the `UIViewController` (sub)class. This default behavior is acceptable, but may not always be desired. For example, if your ViewController's title is based upon the contents of the ViewController, that may make it difficult for you to track the view. To counter this, your `UIViewController` subclass can override and implement `HE_analyticsViewTrackingTitle()` and return a known stable title string that is useful for tracking and doesn't interfere with your UI. +## App Version + +If the analytics platform supports setting the app's version, HEAnalytics will do so. The version will be synthesized from the `CFBundleShortVersionString` and the `CFBundleVersion` as "`CFBundleShortVersionString`.`CFBundleVersion`". The intention is the `CFBundleShortVersionString` is a public/marketing/semantic version only bumped for releases, and the `CFBundleVersion` is a forever-incrementing build number (integer) which can be bumped during development/testing/releases. Thus you may have a "2.0.1.55" then a "2.0.1.56" and finally "2.0.1.57" is actually what's released to the public, so next version becomes "3.0.0.58". + +If you wish to have a different approach, you can subclass the relevant `HEAnalyticsPlatform` and override `appVersion()`. + ## Opt-Out Tracking and privacy are important to users. Many analytics platforms offer a means of opting out, and so `HEAnalytics` provides and API for this.