何ができるのか?
Swiftalyticsというライブラリを使い、Google Analyticsのスクリーントラッキングをファイル1つで管理できるようにします。
ViewControllerには手を触れずにトラッキングできるのが良さげです。
環境
- Xcode 7.2.1
- OS X 10.11.3
手順
SwiftalyticsとGoogle Analytics設定
XcodeのProjectに下記のPodfileを追加します。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'Swiftalytics', '~> 0.2'
pod 'GoogleAnalytics'
pod setupでライブラリをインストールします。
$pod setup
次にBridge-Header.h
にGoogleAnalyticsのヘッダを追加します。
# import <GoogleAnalytics/GAI.h>
# import <GoogleAnalytics/GAIFields.h>
# import <GoogleAnalytics/GAILogger.h>
# import <GoogleAnalytics/GAIDictionaryBuilder.h>
Swiftalytics用のクラスを作成します。
Swiftalyticsのサンプルを参考にしながら下記のようなクラスを追加します。
ポイントはMethodSwizzlingを利用してswiftalytics_viewDidAppear
→viewDidAppear
の順に処理が呼ばれるようになっているところでしょうか。
これにより、UIViewControllerの実装には手を加えずにviewDidAppear
の直前にswiftalytics_viewDidAppear
を差し込むことができるようになります。
import UIKit
import Swiftalytics
struct ScreenTracking {
static func setup() {
FirstViewController.self >> "First Screen"
SecondViewController.self >> "Second Screen"
}
}
extension UIViewController {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
// make sure this isn't a subclass
if self !== UIViewController.self {
return
}
dispatch_once(&Static.token) {
let originalSelector = Selector("viewDidAppear:")
let swizzledSelector = Selector("swiftalytics_viewDidAppear:")
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
func swiftalytics_viewDidAppear(animated: Bool) {
swiftalytics_viewDidAppear(animated)
if let name = Swiftalytics.trackingNameForViewController(self) {
print("\(name)")
let tracker = GAI.sharedInstance().defaultTracker
tracker.set(kGAIScreenName, value: name)
let builder = GAIDictionaryBuilder.createScreenView()
tracker.send(builder.build() as [NSObject: AnyObject])
}
}
}
postfix operator << {}
private postfix func << <T: UIViewController>(trackClassFunction: (T -> () -> String)) {
Swiftalytics.setTrackingNameForViewController(trackClassFunction)
}
private func >> <T: UIViewController>(left: T.Type, @autoclosure right: () -> String) {
Swiftalytics.setTrackingNameForViewController(left, name: right)
}
private func >> <T: UIViewController>(left: T.Type, right: TrackingNameType) {
Swiftalytics.setTrackingNameForViewController(left, trackingType: right)
}
private func >> <T: UIViewController>(left: T.Type, right: (T -> String)) {
Swiftalytics.setTrackingNameForViewController(left, nameFunction: right)
}
didFinishLaunchingWithOptions
を編集
AppDelegate.swiftのdidFinishLaunchingWithOptions
に先ほど作成したScreenTrackingのsetup()とGoogleAnalyticsの設定を追加します。
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
ScreenTracking.setup()
// Configure tracker from GoogleService-Info.plist.
let gai = GAI.sharedInstance()
gai.trackUncaughtExceptions = true
gai.dispatchInterval = 20
gai.logger.logLevel = .Verbose
gai.trackerWithTrackingId("GA-xxxxxx") // 適宜変更してください
return true
}
実行すると、画面が切り替わるたびにswiftalytics_viewDidAppear
が呼ばれ、トラッキングの処理が実行されると思います。
サンプルプロジェクト
サンプルコードを用意しました。
https://github.com/takezou621/SwiftalyticsGASample