-
Notifications
You must be signed in to change notification settings - Fork 338
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
Refactor Paywall events so it can be used for customer center #4376
Refactor Paywall events so it can be used for customer center #4376
Conversation
9ce8a40
to
e02864e
Compare
return nil | ||
} | ||
return AnyEncodable(event) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is going to be a case .customerCenter
here, that will create a CustomerCenterEventRequest.Event
(In another PR)
} | ||
|
||
} | ||
|
||
extension PaywallEventsRequest { | ||
protocol FeatureEvent: Encodable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CustomerCenterEventRequest.Event
will also conform to this
// This is a `struct` instead of `enum` so that | ||
// we can use make it conform to Encodable | ||
// swiftlint:disable:next convenience_type | ||
struct PaywallEventRequest { | ||
|
||
enum EventType: String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to be part of the PaywallEventsRequest
but we now need to have different EventType
for PaywallEventRequest
and CustomerCenterRequest
@@ -16,20 +16,39 @@ import Foundation | |||
/// The content of a request to the events endpoints. | |||
struct PaywallEventsRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought about renaming this, but we are still using the api-paywalls
to post all type of events. So I am not sure. I thought about renaming to FeatureEventsRequest
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I think we should rename it or it would be very confusing down the line, and maybe just keep using the old endpoint for now, (or even alias to a new endpoint name in the backend and deprecate the old one... But that can come in a separate PR.
@@ -40,9 +40,14 @@ internal actor PaywallEventStore: PaywallEventStoreType { | |||
|
|||
func store(_ storedEvent: PaywallStoredEvent) async { | |||
do { | |||
Logger.verbose(PaywallEventStoreStrings.storing_event(storedEvent.event)) | |||
if let eventDescription = try? storedEvent.event.prettyPrintedJSON { | |||
Logger.verbose(PaywallEventStoreStrings.storing_event(eventDescription)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improved the logging a bit so it's easier to see what's being stored
e02864e
to
ec57fbe
Compare
79779b0
to
72e8bfd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm mostly concerned about the naming being confusing... not sure if we should perform some renames now or maybe delay it for later.
@@ -16,20 +16,39 @@ import Foundation | |||
/// The content of a request to the events endpoints. | |||
struct PaywallEventsRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I think we should rename it or it would be very confusing down the line, and maybe just keep using the old endpoint for now, (or even alias to a new endpoint name in the backend and deprecate the old one... But that can come in a separate PR.
init?(storedEvent: PaywallStoredEvent) { | ||
guard let eventData = storedEvent.event.value as? [String: Any], | ||
let paywallEvent: PaywallEvent = try? JSONDecoder.default.decode(dictionary: eventData) else { | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we log something in this case? It should ideally never happen.
// This is a `struct` instead of `enum` so that | ||
// we can use make it conform to Encodable | ||
// swiftlint:disable:next convenience_type | ||
struct PaywallEventRequest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I'm wondering... this is not actually a request (which is PaywallEventsRequest
), but a single event... I was wondering whether to rename to PaywallEvent.Event
or soemthing along those lines? Not sure... I think it's a bit confusing right now...
@tonidero agree on the naming concerns. Let me give them more thought |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the decodable stuff still confuses me a bit but I think it makes sense. Just a few questions to make sure I didn't miss something!
|
||
self.event = try container.decode(AnyEncodable.self, forKey: .event) | ||
self.userID = try container.decode(String.self, forKey: .userID) | ||
self.feature = try container.decodeIfPresent(Feature.self, forKey: .feature) ?? .paywalls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would we need to handle unknown feature types here? As in, just making sure that if there is a value, and it's unknown it won't throw an exception and just default to .paywalls
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't it go to ?? .paywalls
? Or maybe we need to try?
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think we might need to use “try?”
struct PaywallStoredEvent { | ||
|
||
var event: PaywallEvent | ||
var event: AnyEncodable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small concern I have over this... If for some reason the event is written partially (say that during the write it crashed or something), this won't catch it and try to send everything? Or would at least fail if it's not a valid structure?
…reate-customer-center-open-event
@@ -196,22 +203,42 @@ class PaywallEventsManagerTests: TestCase { | |||
let event1 = await self.storeRandomEvent() | |||
_ = await self.storeRandomEvent() | |||
|
|||
let task1 = Task<Int, Error> { [manager = self.manager!] in try await manager.flushEvents(count: 1) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test was flaky. It looks like it doesn't flake anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙌 Much cleaner now IMO. Thanks!!
cc @MarkVillacampa since you're also working with paywall events |
just retested yet again that it works for previous stored events and it works perfectly, so merging |
We want to reuse Paywall events for Customer Center, the issue is that the Paywall events system is very types and requires PaywallEvents to be passed around.
Customer Center events will have different properties than Paywalls events, so we need a way to "untype" the code so it stores and posts events of any type.
After some attempts, I figured that if we just stores
AnyEncodable
and if we postAnyEncodable
we can keep storing and posting paywall events the same way, and also create new Customer Center events without being constrained by paywall events types.