Skip to content

Commit

Permalink
feat(capture): add a signature with timestamp parameter (#228)
Browse files Browse the repository at this point in the history
* feat(capture): add a signature with timestamp parameter

* chore: Update CHANGELOG.md

* chore: lint
  • Loading branch information
ioannisj authored Nov 5, 2024
1 parent f72202c commit 03065f7
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 67 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Next

- fix crash when loading dynamic colors from storyboards ([#229](https://github.com/PostHog/posthog-ios/pull/229))
- add option to pass a custom timestamp when calling capture() ([#228](https://github.com/PostHog/posthog-ios/pull/228))

## 3.13.3 - 2024-10-25

Expand Down
39 changes: 30 additions & 9 deletions PostHog/PostHogSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,14 @@ let maxRetryDelay = 30.0
}
}

private func isOptOutState() -> Bool {
if config.optOut {
hedgeLog("PostHog is in OptOut state.")
return true
}
return false
}

@objc public func capture(_ event: String) {
capture(event, distinctId: nil, properties: nil, userProperties: nil, userPropertiesSetOnce: nil, groups: nil)
}
Expand Down Expand Up @@ -502,14 +510,6 @@ let maxRetryDelay = 30.0
capture(event, distinctId: nil, properties: properties, userProperties: userProperties, userPropertiesSetOnce: userPropertiesSetOnce, groups: nil)
}

private func isOptOutState() -> Bool {
if config.optOut {
hedgeLog("PostHog is in OptOut state.")
return true
}
return false
}

@objc(captureWithEvent:properties:userProperties:userPropertiesSetOnce:groups:)
public func capture(_ event: String,
properties: [String: Any]? = nil,
Expand All @@ -527,6 +527,24 @@ let maxRetryDelay = 30.0
userProperties: [String: Any]? = nil,
userPropertiesSetOnce: [String: Any]? = nil,
groups: [String: String]? = nil)
{
capture(event,
distinctId: distinctId,
properties: properties,
userProperties: userProperties,
userPropertiesSetOnce: userPropertiesSetOnce,
groups: groups,
timestamp: nil)
}

@objc(captureWithEvent:distinctId:properties:userProperties:userPropertiesSetOnce:groups:timestamp:)
public func capture(_ event: String,
distinctId: String? = nil,
properties: [String: Any]? = nil,
userProperties: [String: Any]? = nil,
userPropertiesSetOnce: [String: Any]? = nil,
groups: [String: String]? = nil,
timestamp: Date? = nil)
{
if !isEnabled() {
return
Expand All @@ -552,6 +570,8 @@ let maxRetryDelay = 30.0
}
}

let eventTimestamp = timestamp ?? Date()

let eventDistinctId = distinctId ?? getDistinctId()

// if the user isn't identified but passed userProperties, userPropertiesSetOnce or groups,
Expand All @@ -571,7 +591,8 @@ let maxRetryDelay = 30.0
let posthogEvent = PostHogEvent(
event: event,
distinctId: eventDistinctId,
properties: sanitizedProperties
properties: sanitizedProperties,
timestamp: eventTimestamp
)

// Session Replay has its own queue
Expand Down
140 changes: 82 additions & 58 deletions PostHogObjCExample/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,64 +53,88 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
userPropertiesSetOnce:userPropertiesSetOnce
];

// NSLog(@"getDistinctId: %@", [[PostHogSDK shared] getDistinctId]);
// NSLog(@"getAnonymousId: %@", [[PostHogSDK shared] getAnonymousId]);
//
// NSMutableDictionary *props = [NSMutableDictionary dictionary];
// props[@"state"] = @"running";
//
// NSMutableDictionary *userProps = [NSMutableDictionary dictionary];
// userProps[@"userAge"] = @50;
//
// NSMutableDictionary *userPropsOnce = [NSMutableDictionary dictionary];
// userPropsOnce[@"userAlive"] = @YES;
//
// NSMutableDictionary *groupProps = [NSMutableDictionary dictionary];
// groupProps[@"groupName"] = @"theGroup";
//
// NSMutableDictionary *registerProps = [NSMutableDictionary dictionary];
// props[@"loggedIn"] = @YES;
// [[PostHogSDK shared] registerProperties:registerProps];
// [[PostHogSDK shared] unregisterProperties:@"test2"];
//
// [[PostHogSDK shared] identify:@"my_new_id"];
// [[PostHogSDK shared] identifyWithDistinctId:@"my_new_id" userProperties:userProps];
// [[PostHogSDK shared] identifyWithDistinctId:@"my_new_id" userProperties:userProps userPropertiesSetOnce:userPropsOnce];
//
//
// [[PostHogSDK shared] optIn];
// [[PostHogSDK shared] optOut];
// NSLog(@"isOptOut: %d", [[PostHogSDK shared] isOptOut]);
// NSLog(@"isFeatureEnabled: %d", [[PostHogSDK shared] isFeatureEnabled:@"myFlag"]);
// NSLog(@"getFeatureFlag: %@", [[PostHogSDK shared] getFeatureFlag:@"myFlag"]);
// NSLog(@"getFeatureFlagPayload: %@", [[PostHogSDK shared] getFeatureFlagPayload:@"myFlag"]);
//
// [[PostHogSDK shared] reloadFeatureFlags];
// [[PostHogSDK shared] reloadFeatureFlagsWithCallback:^(){
// NSLog(@"called");
// }];
//
// [[PostHogSDK shared] capture:@"theEvent"];
// [[PostHogSDK shared] captureWithEvent:@"theEvent" properties:props];
// [[PostHogSDK shared] captureWithEvent:@"theEvent" properties:props userProperties:userProps];
// [[PostHogSDK shared] captureWithEvent:@"theEvent" properties:props userProperties:userProps userPropertiesSetOnce:userPropsOnce];
// [[PostHogSDK shared] captureWithEvent:@"theEvent" distinctId:@"custom_distinct_id" properties:props userProperties:userProps userPropertiesSetOnce:userPropsOnce groupProperties:groupProps];
//
// [[PostHogSDK shared] groupWithType:@"theType" key:@"theKey"];
// [[PostHogSDK shared] groupWithType:@"theType" key:@"theKey" groupProperties:groupProps];
//
// [[PostHogSDK shared] alias:@"theAlias"];
//
// [[PostHogSDK shared] screen:@"theScreen"];
// [[PostHogSDK shared] screenWithTitle:@"theScreen" properties:props];

// [[PostHogSDK shared] flush];
// [[PostHogSDK shared] reset];
// [[PostHogSDK shared] close];

// PostHogSDK *postHog = [PostHogSDK with:config];
//
// [postHog capture:@"theCapture"];
NSLog(@"getDistinctId: %@", [[PostHogSDK shared] getDistinctId]);
NSLog(@"getAnonymousId: %@", [[PostHogSDK shared] getAnonymousId]);

NSMutableDictionary *props = [NSMutableDictionary dictionary];
props[@"state"] = @"running";

NSMutableDictionary *userProps = [NSMutableDictionary dictionary];
userProps[@"userAge"] = @50;

NSMutableDictionary *userPropsOnce = [NSMutableDictionary dictionary];
userPropsOnce[@"userAlive"] = @YES;

NSMutableDictionary *groupProps = [NSMutableDictionary dictionary];
groupProps[@"groupName"] = @"theGroup";

NSMutableDictionary *registerProps = [NSMutableDictionary dictionary];
props[@"loggedIn"] = @YES;
[[PostHogSDK shared] registerProperties:registerProps];
[[PostHogSDK shared] unregisterProperties:@"test2"];

[[PostHogSDK shared] identify:@"my_new_id"];
[[PostHogSDK shared] identifyWithDistinctId:@"my_new_id" userProperties:userProps];
[[PostHogSDK shared] identifyWithDistinctId:@"my_new_id" userProperties:userProps userPropertiesSetOnce:userPropsOnce];


[[PostHogSDK shared] optIn];
[[PostHogSDK shared] optOut];
NSLog(@"isOptOut: %d", [[PostHogSDK shared] isOptOut]);
NSLog(@"isFeatureEnabled: %d", [[PostHogSDK shared] isFeatureEnabled:@"myFlag"]);
NSLog(@"getFeatureFlag: %@", [[PostHogSDK shared] getFeatureFlag:@"myFlag"]);
NSLog(@"getFeatureFlagPayload: %@", [[PostHogSDK shared] getFeatureFlagPayload:@"myFlag"]);

[[PostHogSDK shared] reloadFeatureFlags];
[[PostHogSDK shared] reloadFeatureFlagsWithCallback:^(){
NSLog(@"called");
}];

[[PostHogSDK shared] capture:@"theEvent"];

[[PostHogSDK shared] captureWithEvent:@"theEvent"
properties:props];

[[PostHogSDK shared] captureWithEvent:@"theEvent"
properties:props
userProperties:userProps];

[[PostHogSDK shared] captureWithEvent:@"theEvent"
properties:props
userProperties:userProps
userPropertiesSetOnce:userPropsOnce];

[[PostHogSDK shared] captureWithEvent:@"theEvent"
distinctId:@"custom_distinct_id"
properties:props
userProperties:userProps
userPropertiesSetOnce:userPropsOnce
groups:groupProps];

[[PostHogSDK shared] captureWithEvent:@"theEvent"
distinctId:@"custom_distinct_id"
properties:props
userProperties:userProps
userPropertiesSetOnce:userPropsOnce
groups:groupProps
timestamp:[NSDate date]];


[[PostHogSDK shared] groupWithType:@"theType" key:@"theKey"];
[[PostHogSDK shared] groupWithType:@"theType" key:@"theKey" groupProperties:groupProps];

[[PostHogSDK shared] alias:@"theAlias"];

[[PostHogSDK shared] screen:@"theScreen"];
[[PostHogSDK shared] screenWithTitle:@"theScreen" properties:props];

[[PostHogSDK shared] flush];
[[PostHogSDK shared] reset];
[[PostHogSDK shared] close];

PostHogSDK *postHog = [PostHogSDK with:config];

[postHog capture:@"theCapture"];

return YES;
}
Expand Down
35 changes: 35 additions & 0 deletions PostHogTests/PostHogSDKTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,41 @@ class PostHogSDKTest: QuickSpec {

sut.close()
}

it("captures an event with a custom timestamp") {
let sut = self.getSut()
let eventDate = Date().addingTimeInterval(-60 * 30)

sut.capture("test event",
properties: ["foo": "bar"],
userProperties: ["userProp": "value"],
userPropertiesSetOnce: ["userPropOnce": "value"],
groups: ["groupProp": "value"],
timestamp: eventDate)

let events = getBatchedEvents(server)

expect(events.count) == 1

let event = events.first!
expect(event.event) == "test event"

expect(event.properties["foo"] as? String) == "bar"

let set = event.properties["$set"] as? [String: Any] ?? [:]
expect(set["userProp"] as? String) == "value"

let setOnce = event.properties["$set_once"] as? [String: Any] ?? [:]
expect(setOnce["userPropOnce"] as? String) == "value"

let groupProps = event.properties["$groups"] as? [String: String] ?? [:]
expect(groupProps["groupProp"]) == "value"

expect(toISO8601String(event.timestamp)).to(equal(toISO8601String(eventDate)))

sut.reset()
sut.close()
}
}
}

Expand Down

0 comments on commit 03065f7

Please sign in to comment.