-
Notifications
You must be signed in to change notification settings - Fork 13
Add trackConversion for sending conversion events #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f087cbd
f22c7b9
6f85081
3cbb756
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,22 @@ import Combine | |
| import UIKit | ||
| import os.log | ||
|
|
||
| /** | ||
| The category of a conversion event. The raw value of each case is the string sent to Parse.ly | ||
| over the wire and must match the values accepted by the Parse.ly conversions backend. | ||
| Use `.custom` for conversions that don't fit one of the named categories. | ||
|
|
||
| @See: https://docs.parse.ly/api/api-endpoints/api-conversions-endpoint/ | ||
| */ | ||
| public enum ConversionType: String { | ||
| case newsletterSignup = "newsletter_signup" | ||
| case leadCapture = "lead_capture" | ||
| case linkClick = "link_click" | ||
| case subscription = "subscription" | ||
| case purchase = "purchase" | ||
| case custom = "custom" | ||
| } | ||
|
|
||
| public class Parsely { | ||
|
|
||
| public var apikey = "" | ||
|
|
@@ -95,6 +111,74 @@ public class Parsely { | |
| track.pageview(url: url, urlref: urlref, metadata: metadata, extra_data: extraData, idsite: _siteId) | ||
| } | ||
|
|
||
| /** | ||
| Track a conversion event (e.g. newsletter signup, subscription, purchase). | ||
|
|
||
| - Parameter url: The url at which the conversion occurred | ||
| - Parameter conversionType: One of the supported conversion categories. Use `.custom` for | ||
| conversions that don't fit the named categories. | ||
| - Parameter conversionLabel: A customer-defined identifier for this conversion | ||
| (e.g. "weekly_plan", "homepage_cta"). Required and must be non-empty — the Parse.ly | ||
| conversions backend drops events without a label, so calls with an empty label are | ||
| skipped before they are enqueued and an error is logged. | ||
| - Parameter urlref: The url of the page that linked to the conversion page | ||
| - Parameter metadata: Metadata for the page on which the conversion occurred | ||
| - Parameter extraData: A dictionary of additional information to send with the event. | ||
| Reserved keys `_conversion_type` and `_conversion_label` will be overwritten. | ||
| - Parameter siteId: The Parsely site ID for which the conversion event should be counted | ||
| */ | ||
| public func trackConversion( | ||
| url: String, | ||
| conversionType: ConversionType, | ||
| conversionLabel: String, | ||
| urlref: String = "", | ||
| metadata: ParselyMetadata? = nil, | ||
| extraData: Dictionary<String, Any>? = nil, | ||
| siteId: String = "" | ||
| ) { | ||
| eventProcessor.async { | ||
| self._trackConversion( | ||
| url: url, | ||
| conversionType: conversionType, | ||
| conversionLabel: conversionLabel, | ||
| urlref: urlref, | ||
| metadata: metadata, | ||
| extraData: extraData, | ||
| siteId: siteId | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| private func _trackConversion( | ||
| url: String, | ||
| conversionType: ConversionType, | ||
| conversionLabel: String, | ||
| urlref: String, | ||
| metadata: ParselyMetadata?, | ||
| extraData: Dictionary<String, Any>?, | ||
| siteId: String | ||
| ) { | ||
| guard !conversionLabel.isEmpty else { | ||
| os_log("conversionLabel cannot be empty. Parse.ly's conversions backend drops events without a label, so this call is being skipped.", | ||
| log: OSLog.tracker, type: .error) | ||
| return | ||
| } | ||
| var _siteId = siteId | ||
| if _siteId == "" { | ||
| _siteId = self.apikey | ||
| } | ||
| os_log("Tracking Conversion", log: OSLog.tracker, type: .debug) | ||
| track.conversion( | ||
|
Comment on lines
+152
to
+171
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @randyriback I think this is a legit concern. However, I'm not sure logging an error and failing silently would be a good experience for the users. I'd love to require a Maybe we can accept the ambiguity for the time being and follow up at some point with a better SDK design. One that throws errors or that has DTOs with validation in the What do you think?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, Gio! Implemented Copilot's suggestion. Added a guard in _trackConversion-- if conversionLabel is empty, the SDK logs an .error via os_log and returns before enqueuing — same shape as the existing empty-idsite guard in Track.swift. Updated the doc on the public method to reflect this, and added testTrackConversionWithEmptyLabelDoesNotEnqueue Skipped the NonEmpty route per your concern about caller ergonomics. Happy to tackle the broader DTO-with-validation refactor as a follow-up if/when we want to do it across all tracking methods. |
||
| url: url, | ||
| urlref: urlref, | ||
| conversionType: conversionType.rawValue, | ||
| conversionLabel: conversionLabel, | ||
| metadata: metadata, | ||
| extra_data: extraData, | ||
| idsite: _siteId | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| Start tracking engaged time for a given url. Once called, heartbeat events will be sent periodically for this url | ||
| until engaged time tracking is stopped. Stops tracking engaged time for any urls currently being tracked for engaged | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.