diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5a91fc9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# Apply to all files +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# Ruby specific rules +[{*.rb,Fastfile,Gemfile}] +indent_style = space +indent_size = 2 + +[*.{swift,h,m}] +indent_style = space +indent_size = 4 diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index e715ef5..1e176e3 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -34,11 +34,4 @@ jobs: with: xcode-version: ${{ matrix.xcode }} - name: Build and Test - run: | - xcodebuild test \ - -project Demo/ParselyDemo.xcodeproj \ - -scheme ParselyDemo \ - -sdk iphonesimulator \ - -destination 'platform=iOS Simulator,name=iPhone 14,OS=latest' \ - | xcpretty \ - && exit ${PIPESTATUS[0]} + run: make test diff --git a/.gitignore b/.gitignore index 58f360b..a08e021 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,7 @@ xcuserdata/* # Ruby tooling vendor/bundle + + +# SwiftLint Remote Config Cache +.swiftlint/RemoteConfigCache \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..81eecbd --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,7 @@ +swiftlint_version: 0.57.0 + +parent_config: https://raw.githubusercontent.com/Automattic/swiftlint-config/b497131f8d0fddbf3b23278cfc4ef8d86c9bcb20/.swiftlint.yml +remote_timeout: 10.0 + +excluded: + - .build diff --git a/Demo/ParselyDemo/FirstViewController.swift b/Demo/ParselyDemo/FirstViewController.swift index ef520bc..986d290 100644 --- a/Demo/ParselyDemo/FirstViewController.swift +++ b/Demo/ParselyDemo/FirstViewController.swift @@ -6,27 +6,31 @@ class FirstViewController: UIViewController { let delegate = UIApplication.shared.delegate as! AppDelegate @IBAction func didTouchButton(_ sender: Any) { - os_log("didTouchButton", log: OSLog.default, type: .debug) + log("didTouchButton") let demoMetas = ParselyMetadata(authors: ["Yogi Berr"]) delegate.parsely.trackPageView(url: "http://parsely.com/path/cool-blog-post/1?qsarg=nawp&anotherone=yup", metadata: demoMetas, extraData: ["product-id": "12345"], siteId: "subdomain.parsely-test.com") } @IBAction func didStartEngagement(_ sender: Any) { - os_log("didStartEngagement", log: OSLog.default, type: .debug) + log("didStartEngagement") delegate.parsely.startEngagement(url: "http://parsely.com/very-not-real", urlref:"http://parsely.com/not-real", extraData: ["product-id": "12345"], siteId: "engaged.parsely-test.com") } @IBAction func didStopEngagement(_ sender: Any) { - os_log("didStopEngagement", log: OSLog.default, type: .debug) + log("didStopEngagement") delegate.parsely.stopEngagement() } @IBAction func didStartVideo(_ sender: Any) { - os_log("didStartVideo", log: OSLog.default, type: .debug) + log("didStartVideo") let demoMetas = ParselyMetadata(authors: ["Yogi Berr"], duration: TimeInterval(10)) delegate.parsely.trackPlay(url: "http://parsely.com/path/cool-blog-post/1?qsarg=nawp&anotherone=yup", urlref: "not-a-real-urlref", videoID: "videoOne", duration: TimeInterval(6000), metadata: demoMetas, extraData: ["product-id": "12345", "ts": "should be overwritten"]) } @IBAction func didPauseVideo(_ sender: Any) { - os_log("didStopVideo", log: OSLog.default, type: .debug) + log("didStopVideo") delegate.parsely.trackPause() } + + private func log(_ message: String) { + os_log("[Parsely Demo App] %@", log: OSLog.default, type: .debug, message) + } } diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e48ec50 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +# TODO: Use newer Sim. Sticking with it at the moment because we know it works in the existing GitHub action setup. +SIMULATOR_NAME ?= iPhone 14 +SIMULATOR_OS ?= latest +XCODE_PATH ?= /Applications/Xcode.app + +# Convenience to open the lib and demo project with Xcode, given it's not in the root. +open: + open -a $(XCODE_PATH) ./Demo/ParselyDemo.xcodeproj + +# TODO: Move off xcpretty to xcbeautify. Sticking with it at the moment because we know it works in the existing GitHub action setup. +test: + set -o pipefail \ + && xcodebuild test \ + -project Demo/ParselyDemo.xcodeproj \ + -scheme ParselyDemo \ + -sdk iphonesimulator \ + -destination 'platform=iOS Simulator,name=$(SIMULATOR_NAME),OS=$(SIMULATOR_OS)' \ + | xcpretty + +# TODO: Add automation to set up SwiftLint +format: + swiftlint --fix --format diff --git a/Sources/Sampler.swift b/Sources/Sampler.swift index 2eae593..4bffb44 100644 --- a/Sources/Sampler.swift +++ b/Sources/Sampler.swift @@ -147,18 +147,28 @@ class Sampler { os_log("No accumulator found for %s, skipping sendHeartbeat", log: OSLog.tracker, type:.debug, key) return } + let now = Date() let incSecs: TimeInterval = trackedData.accumulatedTime if incSecs > 0 { - os_log("Sending heartbeat for %s", log: OSLog.tracker, type:.debug, key) + os_log( + "Sending heartbeat for %s. Timestamp: %s.", + log: OSLog.tracker, + type:.debug, + key, + now.description + ) heartbeatFn(data: trackedData, enableHeartbeats: true) } trackedData.accumulatedTime = 0 - let totalTrackedTime: TimeInterval = Date().timeIntervalSince(trackedData.firstSampleTime!); - trackedData.heartbeatTimeout = self.getHeartbeatInterval( + let totalTrackedTime: TimeInterval = now.timeIntervalSince(trackedData.firstSampleTime!) + trackedData.heartbeatTimeout = getHeartbeatInterval( existingTimeout: trackedData.heartbeatTimeout!, - totalTrackedTime: totalTrackedTime) + totalTrackedTime: totalTrackedTime + ) updateAccumulator(acc: trackedData) heartbeatInterval = trackedData.heartbeatTimeout! + + os_log("Send heartbeat completed. New heartbeat timeout %.2f seconds.", trackedData.heartbeatTimeout!) } @objc internal func sendHeartbeats() -> Void { diff --git a/Sources/Track.swift b/Sources/Track.swift index 9292c73..31f06e3 100644 --- a/Sources/Track.swift +++ b/Sources/Track.swift @@ -22,8 +22,7 @@ class Track { parselyTracker.startFlushTimer(); pixel.beacon(event: event) - os_log("Sending an event from Track", log: OSLog.tracker, type:.debug) - dump(event.toDict()) + os_log_sending_event(event) } func pageview(url: String, urlref: String = "", metadata: ParselyMetadata?, extra_data: Dictionary?, idsite: String) { @@ -82,3 +81,10 @@ class Track { videoManager.sendHeartbeats() } } + +/// Utility to log sending event with a dump of the event. +private func os_log_sending_event(_ event: Event, log: OSLog = .tracker, type: OSLogType = .debug) { + var eventDump = "" + dump(event.toDict(), to: &eventDump) + os_log("Sending an event from Track:\n%@", log: log, type: type, eventDump) +}