From 44e0ce7d98422b8b5a11a34cf6079fd725b01ea1 Mon Sep 17 00:00:00 2001 From: Andrey Sokolov Date: Tue, 3 Oct 2023 11:52:49 +0400 Subject: [PATCH] AMP-85465 Swift v2 codegen: use SDK BaseEvent --- .../project.pbxproj | 4 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- .../AmpliSwiftSampleAppTests/AmpliTests.swift | 4 +- .../Shared/Ampli/Ampli.swift | 415 ++++++++---------- 4 files changed, 178 insertions(+), 249 deletions(-) diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj index cbdc4868..03e95787 100644 --- a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj @@ -648,8 +648,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/amplitude/Amplitude-Swift"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.7.1; + branch = "AMP-67635-objc-support-properties"; + kind = branch; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 715dabb1..f78a7f60 100644 --- a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/amplitude/Amplitude-Swift", "state" : { - "revision" : "4f9c21758a511f4e59226a6bfbcd025f61adc1a0", - "version" : "0.7.1" + "branch" : "AMP-67635-objc-support-properties", + "revision" : "5b6b7c917edde1cb8bf59ee7383442c8a4cd2759" } }, { diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift index 19716382..f64ef0bb 100644 --- a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift @@ -85,7 +85,7 @@ class AmpliTests: XCTestCase { func testTrackEventWithAllTypes() throws { let userId = "test-user-id"; let deviceId = "test-device-id"; - let eventOptions = EventOptions(deviceId: deviceId) + let eventOptions = EventOptions(userId: userId, deviceId: deviceId) initAmpliWithNewInstance("testTrackEventWithAllTypes") let eventCollector = EventCollectorPlugin() @@ -99,7 +99,7 @@ class AmpliTests: XCTestCase { requiredInteger: 10, requiredNumber: 2.0, requiredString: "required string" - ).options(userId: userId), + ), options: eventOptions ) ampli.flush() diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift index 00f42719..56991838 100644 --- a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift @@ -33,95 +33,46 @@ let AmpliObservePlan = Plan( versionId: "a61c3908-ca4d-4c8d-8f81-54ad3ba17b9c" ) -public class Event { - public let eventType: String - public let eventProperties: [String:Any]? - public let options: EventOptions? - - init(eventType: String, eventProperties: [String:Any?]?, options: EventOptions?) { - self.eventType = eventType - self.eventProperties = eventProperties?.compactMapValues { $0 } - self.options = options - } -} - -public class GenericEvent : Event { - private let eventFactory: (_ eventProperties: [String: Any?]?, _ options: EventOptions?) -> E - - init(eventType: String, eventProperties: [String:Any?]?, options: EventOptions?, eventFactory: @escaping (_ eventProperties: [String: Any?]?, _ options: EventOptions?) -> E) { - self.eventFactory = eventFactory - super.init(eventType: eventType, eventProperties: eventProperties, options: options) - } - - public func options(_ options: EventOptions) -> E { - return self.eventFactory(self.eventProperties, options) - } - - public func options(deviceId: String? = nil, userId: String? = nil) -> E { - return self.options(EventOptions(userId: userId, deviceId: deviceId)) - } -} - -public class Identify : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { - super.init( - eventType: "$identify", - eventProperties: eventProperties, - options: options, - eventFactory: Identify.init - ) - } - +public class Identify: AmplitudeSwift.Identify { /** Identify properties. - Parameter requiredNumber: Description for identify requiredNumber - Parameter optionalArray: Description for identify optionalArray */ - public convenience init( + public init( requiredNumber: Double, optionalArray: [String]? = nil ) { - self.init([ + super.init(); + let userProperties: [String: Any?] = [ "optionalArray": optionalArray, "requiredNumber": requiredNumber - ]) + ] + for (property, value) in (userProperties.compactMapValues { $0 }) { + self.set(property: property, value: value) + } } } -public class EventNoProperties : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { - super.init( - eventType: "Event No Properties", - eventProperties: eventProperties, - options: options, - eventFactory: EventNoProperties.init - ) - } - +public class EventNoProperties : BaseEvent { /** Event w no properties description Owner: Test codegen */ - public convenience init() { - self.init(nil) - } -} - -public class EventObjectTypes : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + public init() { super.init( - eventType: "Event Object Types", - eventProperties: eventProperties, - options: options, - eventFactory: EventObjectTypes.init + eventType: "Event No Properties" ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventObjectTypes : BaseEvent { /** Event with Object and Object Array @@ -130,33 +81,31 @@ public class EventObjectTypes : GenericEvent { - Parameter requiredObject: Property Object Type - Parameter requiredObjectArray: Property Object Array Type */ - public convenience init( + public init( requiredObject: Any, requiredObjectArray: [Any] ) { - self.init([ - "requiredObject": requiredObject, - "requiredObjectArray": requiredObjectArray - ]) + super.init( + eventType: "Event Object Types", + eventProperties: [ + "requiredObject": requiredObject, + "requiredObjectArray": requiredObjectArray + ].compactMapValues { $0 } + ) + } + + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) } } -public class EventWithAllProperties : GenericEvent { +public class EventWithAllProperties : BaseEvent { public enum RequiredEnum: String { case enum1 = "Enum1" case enum2 = "Enum2" } - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { - super.init( - eventType: "Event With All Properties", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithAllProperties.init - ) - } - /** Event w all properties description @@ -170,7 +119,7 @@ public class EventWithAllProperties : GenericEvent { - Parameter requiredString: Event 2 Property - String - Parameter optionalString: Event 2 Property - Optional String * * Examples: * Some string, or another */ - public convenience init( + public init( requiredArray: [String], requiredBoolean: Bool, requiredEnum: EventWithAllProperties.RequiredEnum, @@ -179,30 +128,27 @@ public class EventWithAllProperties : GenericEvent { requiredString: String, optionalString: String? = nil ) { - self.init([ - "optionalString": optionalString, - "requiredArray": requiredArray, - "requiredBoolean": requiredBoolean, - "requiredConst": "some-const-value", - "requiredEnum": requiredEnum.rawValue, - "requiredInteger": requiredInteger, - "requiredNumber": requiredNumber, - "requiredString": requiredString - ]) - } -} - -public class EventWithArrayTypes : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { super.init( - eventType: "Event With Array Types", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithArrayTypes.init + eventType: "Event With All Properties", + eventProperties: [ + "optionalString": optionalString, + "requiredArray": requiredArray, + "requiredBoolean": requiredBoolean, + "requiredConst": "some-const-value", + "requiredEnum": requiredEnum.rawValue, + "requiredInteger": requiredInteger, + "requiredNumber": requiredNumber, + "requiredString": requiredString + ].compactMapValues { $0 } ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventWithArrayTypes : BaseEvent { /** Description for event with Array Types @@ -214,52 +160,56 @@ public class EventWithArrayTypes : GenericEvent { - Parameter requiredObjectArray: Description for required object array - Parameter requiredStringArray: description for required string array */ - public convenience init( + public init( requiredBooleanArray: [Bool], requiredEnumArray: [String], requiredNumberArray: [Double], requiredObjectArray: [Any], requiredStringArray: [String] ) { - self.init([ - "requiredBooleanArray": requiredBooleanArray, - "requiredEnumArray": requiredEnumArray, - "requiredNumberArray": requiredNumberArray, - "requiredObjectArray": requiredObjectArray, - "requiredStringArray": requiredStringArray - ]) - } -} - -public class EventWithConstTypes : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { super.init( - eventType: "Event With Const Types", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithConstTypes.init + eventType: "Event With Array Types", + eventProperties: [ + "requiredBooleanArray": requiredBooleanArray, + "requiredEnumArray": requiredEnumArray, + "requiredNumberArray": requiredNumberArray, + "requiredObjectArray": requiredObjectArray, + "requiredStringArray": requiredStringArray + ].compactMapValues { $0 } ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventWithConstTypes : BaseEvent { /** Description for event with const types Owner: Test codegen */ - public convenience init() { - self.init([ - "Boolean Const": true, - "Integer Const": 10, - "Number Const": 2.2, - "String Const": "String-Constant", - "String Const WIth Quotes": "\"String \"Const With\" Quotes\"", - "String Int Const": 0 - ]) + public init() { + super.init( + eventType: "Event With Const Types", + eventProperties: [ + "Boolean Const": true, + "Integer Const": 10, + "Number Const": 2.2, + "String Const": "String-Constant", + "String Const WIth Quotes": "\"String \"Const With\" Quotes\"", + "String Int Const": 0 + ].compactMapValues { $0 } + ) + } + + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) } } -public class EventWithEnumTypes : GenericEvent { +public class EventWithEnumTypes : BaseEvent { public enum OptionalEnum: String { case optionalEnum1 = "optional enum 1" @@ -271,15 +221,6 @@ public class EventWithEnumTypes : GenericEvent { case requiredEnum2 = "required enum 2" } - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { - super.init( - eventType: "Event With Enum Types", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithEnumTypes.init - ) - } - /** Description for event with enum types @@ -288,28 +229,25 @@ public class EventWithEnumTypes : GenericEvent { - Parameter requiredEnum: Description for optional enum - Parameter optionalEnum: Description for required enum */ - public convenience init( + public init( requiredEnum: EventWithEnumTypes.RequiredEnum, optionalEnum: EventWithEnumTypes.OptionalEnum? = nil ) { - self.init([ - "optional enum": optionalEnum?.rawValue, - "required enum": requiredEnum.rawValue - ]) - } -} - -public class EventWithOptionalArrayTypes : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { super.init( - eventType: "Event With Optional Array Types", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithOptionalArrayTypes.init + eventType: "Event With Enum Types", + eventProperties: [ + "optional enum": optionalEnum?.rawValue, + "required enum": requiredEnum.rawValue + ].compactMapValues { $0 } ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventWithOptionalArrayTypes : BaseEvent { /** Description for event with optional array types @@ -321,34 +259,31 @@ public class EventWithOptionalArrayTypes : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { super.init( - eventType: "Event With Optional Properties", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithOptionalProperties.init + eventType: "Event With Optional Array Types", + eventProperties: [ + "optionalBooleanArray": optionalBooleanArray, + "optionalEnumArray": optionalEnumArray, + "optionalJSONArray": optionalJsonArray, + "optionalNumberArray": optionalNumberArray, + "optionalStringArray": optionalStringArray + ].compactMapValues { $0 } ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventWithOptionalProperties : BaseEvent { /** Event w optional properties description @@ -360,34 +295,33 @@ public class EventWithOptionalProperties : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + ] + super.init( - eventType: "Event With Template Properties", - eventProperties: eventProperties, - options: options, - eventFactory: EventWithTemplateProperties.init + eventType: "Event With Optional Properties", + eventProperties: eventProperties.compactMapValues { $0 } ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventWithTemplateProperties : BaseEvent { /** Event with template properties description @@ -398,22 +332,30 @@ public class EventWithTemplateProperties : GenericEvent { +public class EventWithDifferentCasingTypes : BaseEvent { public enum EnumWithSpace: String { case enumWithSpace = "enum with space" @@ -431,15 +373,6 @@ public class EventWithDifferentCasingTypes : GenericEvent { - - private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { super.init( - eventType: "EventMaxIntForTest", - eventProperties: eventProperties, - options: options, - eventFactory: EventMaxIntForTest.init + eventType: "event withDifferent_CasingTypes", + eventProperties: [ + "enum with space": enumWithSpace.rawValue, + "enum_snake_case": enumSnakeCase.rawValue, + "enumCamelCase": enumCamelCase.rawValue, + "EnumPascalCase": enumPascalCase.rawValue, + "property with space": propertyWithSpace, + "property_with_snake_case": propertyWithSnakeCase, + "propertyWithCamelCase": propertyWithCamelCase, + "PropertyWithPascalCase": propertyWithPascalCase + ].compactMapValues { $0 } ) } + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) + } +} + +public class EventMaxIntForTest : BaseEvent { /** Event to test schema validation @@ -495,12 +425,19 @@ public class EventMaxIntForTest : GenericEvent { - Parameter intMax10: property to test schema validation */ - public convenience init( + public init( intMax10: Int ) { - self.init([ - "intMax10": intMax10 - ]) + super.init( + eventType: "EventMaxIntForTest", + eventProperties: [ + "intMax10": intMax10 + ].compactMapValues { $0 } + ) + } + + required public init(from decoder: Decoder) throws { + try super.init(from: decoder) } } @@ -598,20 +535,26 @@ public class Ampli { } } - public func track(_ event: Event, options: EventOptions? = nil) -> Void { + public func track(_ event: BaseEvent, options: EventOptions? = nil) -> Void { if !isInitializedAndEnabled() { return } - let eventOptions = getEventOptions(event.options, options) - amplitude?.track(eventType: event.eventType, eventProperties: event.eventProperties, options: eventOptions) + amplitude?.track(event: event, options: options) } - public func identify(_ userId: String?, _ event: Identify, options: EventOptions? = nil) -> Void { + public func identify(_ userId: String?, _ identify: Identify, options: EventOptions? = nil) -> Void { if !isInitializedAndEnabled() { return } - let eventOptions = getEventOptions(event.options, options, userId) - amplitude?.identify(userProperties: event.eventProperties, options: eventOptions) + var eventOptions = options + if userId != nil { + eventOptions = EventOptions() + if let options = options { + eventOptions!.mergeEventOptions(eventOptions: options) + } + eventOptions!.userId = userId + } + amplitude?.identify(identify: identify, options: eventOptions) } public func flush() -> Void { @@ -907,18 +850,4 @@ public class Ampli { intMax10: intMax10 )) } - - private func getEventOptions(_ options: EventOptions?, _ overrideOptions: EventOptions?, _ overrideUserId: String? = nil) -> EventOptions { - let eventOptions = EventOptions() - if let options = options { - eventOptions.mergeEventOptions(eventOptions: options) - } - if let overrideOptions = overrideOptions { - eventOptions.mergeEventOptions(eventOptions: overrideOptions) - } - if let overrideUserId = overrideUserId { - eventOptions.userId = overrideUserId - } - return eventOptions - } }