6 Commits

Author SHA1 Message Date
239deb2b91 RES-32 Ajouter la possibilité désactiver des traqueurs spécifiques
Some checks failed
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit
2025-02-12 10:49:06 +01:00
9a05ce29b8 Disable tag for previews
Some checks failed
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit
2024-12-17 16:30:22 +01:00
2ec4ebcc66 Fix plugin swiftlint
Some checks failed
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit
2024-11-04 14:00:27 +01:00
6ea31a8030 Fix some error when value and replaceIn
Some checks failed
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit
2024-07-18 11:36:21 +02:00
df173406d4 Update README.md
Some checks failed
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit
2024-07-18 11:36:11 +02:00
922ed56959 Add parameter defaultValue and value and add replaceIn parameter in another parameter
Some checks failed
gitea-openium/resgen.swift/pipeline/pr-master There was a failure building this commit
2024-07-18 08:24:23 +02:00
14 changed files with 451 additions and 133 deletions

View File

@ -1,32 +1,5 @@
{ {
"pins" : [ "pins" : [
{
"identity" : "collectionconcurrencykit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
"state" : {
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
"version" : "0.2.0"
}
},
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
"state" : {
"revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0",
"version" : "1.8.2"
}
},
{
"identity" : "sourcekitten",
"kind" : "remoteSourceControl",
"location" : "https://github.com/jpsim/SourceKitten.git",
"state" : {
"revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
"version" : "0.34.1"
}
},
{ {
"identity" : "swift-argument-parser", "identity" : "swift-argument-parser",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
@ -37,39 +10,12 @@
} }
}, },
{ {
"identity" : "swift-syntax", "identity" : "swiftlintplugin",
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git", "location" : "https://github.com/lukepistrol/SwiftLintPlugin",
"state" : { "state" : {
"revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036", "revision" : "5a65f4074975f811da666dfe31a19850950b1ea4",
"version" : "509.0.2" "version" : "0.56.2"
}
},
{
"identity" : "swiftlint",
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/SwiftLint.git",
"state" : {
"revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee",
"version" : "0.54.0"
}
},
{
"identity" : "swiftytexttable",
"kind" : "remoteSourceControl",
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
"state" : {
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
"version" : "0.9.0"
}
},
{
"identity" : "swxmlhash",
"kind" : "remoteSourceControl",
"location" : "https://github.com/drmohundro/SWXMLHash.git",
"state" : {
"revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
"version" : "7.0.2"
} }
}, },
{ {

View File

@ -10,7 +10,7 @@ let package = Package(
// Dependencies declare other packages that this package depends on. // Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"), .package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
.package(url: "https://github.com/jpsim/Yams.git", from: "5.0.1"), .package(url: "https://github.com/jpsim/Yams.git", from: "5.0.1"),
.package(url: "https://github.com/realm/SwiftLint.git", .upToNextMajor(from: "0.54.0")), .package(url: "https://github.com/lukepistrol/SwiftLintPlugin", exact: "0.56.2"),
], ],
targets: [ targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets are the basic building blocks of a package. A target can define a module or a test suite.
@ -22,7 +22,9 @@ let package = Package(
.product(name: "ArgumentParser", package: "swift-argument-parser"), .product(name: "ArgumentParser", package: "swift-argument-parser"),
"Yams" "Yams"
], ],
plugins: [.plugin(name: "SwiftLintPlugin", package: "SwiftLint")] plugins: [
.plugin(name: "SwiftLint", package: "SwiftLintPlugin")
]
), ),
// Helper targets // Helper targets

View File

@ -192,12 +192,41 @@ You can use parameters in generate methods.
1. `name`: name of the parameter 1. `name`: name of the parameter
2. `type`: type of the parameter (Int, String, Bool, Double) 2. `type`: type of the parameter (Int, String, Bool, Double)
3. `value`: value of the parameter
4. `defaultValue`: defaultValue of the parameter
3. `replaceIn` *(optional)* 3. `replaceIn` *(optional)*
**Value**
If you want to send another parameter with a static value. For example, you want to send to which screen the event is triggered.
You can add the parameter 'screenName' for example and its 'value' is 'Home'. With this, you do not need to specify the value in the function call.
**DefaultValue**
If you want ta add a parameter in the call of the function but you want to make it optionnal with a default value you need to use this property.
Example:
```
events:
id: id_of_tag
name: _TITLE_
tags: ios,droid
parameters:
- name: title
type: String
defaultValue: someTitle
```
The generated method will be:
```
logIdOfTag(title: String = "someTitle")
```
**Replace in** **Replace in**
This is section is equivalent of `%s | %d | %f | %@`. You can put the content of the parameter in *name*, *path*, *action*, *category*. This is section is equivalent of `%s | %d | %f | %@`. You can put the content of the parameter in *name*, *path*, *action*, *category*.
You need to put `_` + `NAME OF THE PARAMETER` + `_` in the target and which target you want in the value of `replaceIn`. (name need to be in uppercase) You need to put `_` + `NAME OF THE PARAMETER` + `_` in the target and which target you want in the value of `replaceIn`. (name need to be in uppercase).
You can't use `value`and `replaceIn`in thge same time.
Example: Example:
``` ```
@ -218,6 +247,23 @@ The generated method will be:
logIdOfTag(title: String) logIdOfTag(title: String)
``` ```
You can also want to replace a parameter in an other parameter. You can do this with the `replaceIn` property. The condition is that the parameter which will use the `replaceIn`need to have the `value`property
Example:
```
events:
id: id_of_tag
name: title
tags: ios,droid
parameters:
- name: something
type: String
value: test _TEXT_
- name: text
type: String
replaceIn: something
```
## Images ## Images
Images generator will generate images assets along with extensions to access those images easily. Images generator will generate images assets along with extensions to access those images easily.

View File

@ -1,27 +1,121 @@
// Generated by ResgenSwift.Analytics 1.2 // Generated by ResgenSwift.Analytics 1.2
import MatomoTracker
import FirebaseAnalytics import FirebaseAnalytics
// MARK: - Protocol // MARK: - Protocol
protocol AnalyticsManagerProtocol { protocol AnalyticsManagerProtocol {
func logScreen(name: String, path: String) func logScreen(
name: String,
path: String,
params: [String: Any]?
)
func logEvent( func logEvent(
name: String, name: String,
action: String, action: String,
category: String, category: String,
params: [String: Any]? params: [String: Any]?
) )
func setEnable(_ enable: Bool)
}
// MARK: - Matomo
class MatomoAnalyticsManager: AnalyticsManagerProtocol {
// MARK: - Properties
private var tracker: MatomoTracker
// MARK: - Init
init(siteId: String, url: String) {
debugPrint("[Matomo service] Server URL: \(url)")
debugPrint("[Matomo service] Site ID: \(siteId)")
tracker = MatomoTracker(
siteId: siteId,
baseURL: URL(string: url)!
)
#if DEBUG
tracker.dispatchInterval = 5
#endif
#if DEBUG
tracker.logger = DefaultLogger(minLevel: .verbose)
#endif
debugPrint("[Matomo service] Configured with content base: \(tracker.contentBase?.absoluteString ?? "-")")
debugPrint("[Matomo service] Opt out: \(tracker.isOptedOut)")
}
// MARK: - Methods
func logScreen(
name: String,
path: String,
params: [String: Any]?
) {
guard let trackerUrl = tracker.contentBase?.absoluteString else { return }
let urlString = URL(string: "\(trackerUrl)" + "/" + "\(path)" + "iOS")
tracker.track(
view: [name],
url: urlString
)
}
func logEvent(
name: String,
action: String,
category: String,
params: [String: Any]?
) {
tracker.track(
eventWithCategory: category,
action: action,
name: name,
number: nil,
url: nil
)
}
func setEnable(_ enable: Bool) {
tracker.isOptedOut = !enable
}
} }
// MARK: - Firebase // MARK: - Firebase
class FirebaseAnalyticsManager: AnalyticsManagerProtocol { class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
func logScreen(name: String, path: String) { func logScreen(
let parameters = [ name: String,
path: String,
params: [String: Any]?
) {
var parameters = [
AnalyticsParameterScreenName: name as NSObject AnalyticsParameterScreenName: name as NSObject
] ]
if path.isEmpty == false {
parameters["path"] = path + "/iOS" as NSObject
}
if let supplementaryParameters = params {
for (newKey, newValue) in supplementaryParameters {
if parameters.contains(where: { (key: String, value: NSObject) in
key == newKey
}) {
continue
}
parameters[newKey] = newValue as? NSObject
}
}
Analytics.logEvent( Analytics.logEvent(
AnalyticsEventScreenView, AnalyticsEventScreenView,
parameters: parameters parameters: parameters
@ -35,10 +129,16 @@ class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
params: [String: Any]? params: [String: Any]?
) { ) {
var parameters: [String:NSObject] = [ var parameters: [String:NSObject] = [
AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject, AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject
AnalyticsParameterItemCategory: category as NSObject,
"action": action as NSObject,
] ]
if category.isEmpty == false {
parameters["AnalyticsParameterItemCategory"] = category as NSObject
}
if action.isEmpty == false {
parameters["action"] = action as NSObject
}
if let supplementaryParameters = params { if let supplementaryParameters = params {
for (newKey, newValue) in supplementaryParameters { for (newKey, newValue) in supplementaryParameters {
@ -57,6 +157,9 @@ class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
parameters: parameters parameters: parameters
) )
} }
func setEnable(_ enable: Bool) {
Analytics.setAnalyticsCollectionEnabled(enable)
}
} }
// MARK: - Manager // MARK: - Manager
@ -66,25 +169,57 @@ class AnalyticsManager {
// MARK: - Properties // MARK: - Properties
var managers: [AnalyticsManagerProtocol] = [] var managers: [TargetType: AnalyticsManagerProtocol] = []
private var isEnabled: Bool = true private var isEnabled: Bool {
if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
false
} else {
true
}
}
// MARK: - Methods // MARK: - Methods
func setAnalyticsEnabled(_ enable: Bool) { private func setAnalytics(enable: Bool) {
isEnabled = enable managers.forEach { (key, value) in
if analytics.contains(where: { type in
type == key
}) {
value.setEnable(enable)
}
}
} }
func configure() { func enableAnalytics(_ analytics: [TargetType] = TargetType.allCases) {
managers.append(FirebaseAnalyticsManager()) setAnalytics(enable: true)
}
func disableAnalytics(_ analytics: [TargetType] = TargetType.allCases) {
setAnalytics(enable: false)
}
func configure(siteId: String, url: String) {
managers[TrackerType.matomo] = MatomoAnalyticsManager(
siteId: siteId,
url: url
)
managers[TrackerType.firebase] = FirebaseAnalyticsManager()
} }
private func logScreen(name: String, path: String) { private func logScreen(
name: String,
path: String,
params: [String: Any]?
) {
guard isEnabled else { return } guard isEnabled else { return }
managers.forEach { manager in managers.values.forEach { manager in
manager.logScreen(name: name, path: path) manager.logScreen(
name: name,
path: path,
params: params
)
} }
} }
@ -96,7 +231,7 @@ class AnalyticsManager {
) { ) {
guard isEnabled else { return } guard isEnabled else { return }
managers.forEach { manager in managers.values.forEach { manager in
manager.logEvent( manager.logEvent(
name: name, name: name,
action: action, action: action,
@ -108,31 +243,39 @@ class AnalyticsManager {
// MARK: - section_one // MARK: - section_one
func logScreenS1DefOne(title: String) { static func logScreenS1DefOne(title: String) {
logScreen( AnalyticsManager.shared.logScreen(
name: "s1 def one \(title)", name: "s1 def one \(title)",
path: "" path: "s1_def_one/\(title)",
params: nil
) )
} }
func logEventS1DefTwo(title: String, count: String) { static func logEventS1DefTwo(
logEvent( title: String,
count: String,
test2: String = "test"
) {
AnalyticsManager.shared.logEvent(
name: "s1 def two", name: "s1 def two",
action: "test", action: "test",
category: "test", category: "test",
params: [ params: [
"title": title, "title": title,
"count": count "count": count,
"test": "test",
"test2": test2
] ]
) )
} }
// MARK: - section_two // MARK: - section_two
func logScreenS2DefOne() { static func logScreenS2DefOne() {
logScreen( AnalyticsManager.shared.logScreen(
name: "s2 def one", name: "s2 def one",
path: "" path: "s2_def_one/",
params: nil
) )
} }
} }

View File

@ -22,6 +22,12 @@ categories:
type: String type: String
- name: count - name: count
type: String type: String
- name: test
type: String
value: test
- name: test2
type: String
defaultValue: test
- id: section_two - id: section_two
screens: screens:

View File

@ -54,7 +54,7 @@ FORCE_FLAG="$1"
# Analytics # Analytics
swift run -c release ResgenSwift analytics $FORCE_FLAG "./Tags/sampleTags.yml" \ swift run -c release ResgenSwift analytics $FORCE_FLAG "./Tags/sampleTags.yml" \
--target "firebase" \ --target "firebase matomo" \
--extension-output-path "./Tags/Generated" \ --extension-output-path "./Tags/Generated" \
--extension-name "Analytics" \ --extension-name "Analytics" \
--extension-suffix "GenAllScript" \ --extension-suffix "GenAllScript" \

View File

@ -59,14 +59,18 @@ class AnalyticsGenerator {
\(Self.getImport()) \(Self.getImport())
\(Self.getAnalyticsProtocol()) \(Self.getAnalyticsProtocol())
\(Self.getTrackerTypeEnum())
// MARK: - Manager // MARK: - Manager
class AnalyticsManager { class AnalyticsManager {
static var shared = AnalyticsManager() static var shared = AnalyticsManager()
// MARK: - Properties // MARK: - Properties
var managers: [AnalyticsManagerProtocol] = [] var managers: [TrackerType: AnalyticsManagerProtocol] = [:]
\(Self.getEnabledContent()) \(Self.getEnabledContent())
@ -76,14 +80,49 @@ class AnalyticsGenerator {
""" """
} }
private static func getTrackerTypeEnum() -> String {
var result: [String] = []
TrackerType.allCases.forEach { type in
result.append(" case \(type)")
}
return """
// MARK: - Traker Type
enum TrackerType: CaseIterable {
\(result.joined(separator: "\n"))
}
"""
}
private static func getEnabledContent() -> String { private static func getEnabledContent() -> String {
""" """
private var isEnabled: Bool = true private var isEnabled: Bool {
if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
false
} else {
true
}
}
// MARK: - Methods // MARK: - Methods
func setAnalyticsEnabled(_ enable: Bool) { private func setAnalytics(enable: Bool, _ analytics: [TrackerType]) {
isEnabled = enable managers.forEach { (key, value) in
if analytics.contains(where: { type in
type == key
}) {
value.setEnable(enable)
}
}
}
func enableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) {
setAnalytics(enable: true, analytics)
}
func disableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) {
setAnalytics(enable: false, analytics)
} }
""" """
} }
@ -103,11 +142,19 @@ class AnalyticsGenerator {
private static func getPrivateLogFunction() -> String { private static func getPrivateLogFunction() -> String {
""" """
private func logScreen(name: String, path: String) { private func logScreen(
name: String,
path: String,
params: [String: Any]?
) {
guard isEnabled else { return } guard isEnabled else { return }
managers.forEach { manager in managers.values.forEach { manager in
manager.logScreen(name: name, path: path) manager.logScreen(
name: name,
path: path,
params: params
)
} }
} }
@ -119,7 +166,7 @@ class AnalyticsGenerator {
) { ) {
guard isEnabled else { return } guard isEnabled else { return }
managers.forEach { manager in managers.values.forEach { manager in
manager.logEvent( manager.logEvent(
name: name, name: name,
action: action, action: action,
@ -144,16 +191,14 @@ class AnalyticsGenerator {
if targets.contains(TrackerType.matomo) { if targets.contains(TrackerType.matomo) {
content.append(""" content.append("""
managers.append( managers[TrackerType.matomo] = MatomoAnalyticsManager(
MatomoAnalyticsManager( siteId: siteId,
siteId: siteId, url: url
url: url
)
) )
""") """)
} }
if targets.contains(TrackerType.firebase) { if targets.contains(TrackerType.firebase) {
content.append(" managers.append(FirebaseAnalyticsManager())") content.append(" managers[TrackerType.firebase] = FirebaseAnalyticsManager()")
} }
return [ return [
@ -169,13 +214,20 @@ class AnalyticsGenerator {
// MARK: - Protocol // MARK: - Protocol
protocol AnalyticsManagerProtocol { protocol AnalyticsManagerProtocol {
func logScreen(name: String, path: String) func logScreen(
name: String,
path: String,
params: [String: Any]?
)
func logEvent( func logEvent(
name: String, name: String,
action: String, action: String,
category: String, category: String,
params: [String: Any]? params: [String: Any]?
) )
func setEnable(_ enable: Bool)
} }
""" """

View File

@ -14,6 +14,7 @@ enum FirebaseGenerator {
FirebaseGenerator.header, FirebaseGenerator.header,
FirebaseGenerator.logScreen, FirebaseGenerator.logScreen,
FirebaseGenerator.logEvent, FirebaseGenerator.logEvent,
FirebaseGenerator.enable,
FirebaseGenerator.footer FirebaseGenerator.footer
] ]
.joined(separator: "\n") .joined(separator: "\n")
@ -31,11 +32,31 @@ enum FirebaseGenerator {
private static var logScreen: String { private static var logScreen: String {
""" """
func logScreen(name: String, path: String) { func logScreen(
let parameters = [ name: String,
path: String,
params: [String: Any]?
) {
var parameters = [
AnalyticsParameterScreenName: name as NSObject AnalyticsParameterScreenName: name as NSObject
] ]
if path.isEmpty == false {
parameters["path"] = path + "/iOS" as NSObject
}
if let supplementaryParameters = params {
for (newKey, newValue) in supplementaryParameters {
if parameters.contains(where: { (key: String, value: NSObject) in
key == newKey
}) {
continue
}
parameters[newKey] = newValue as? NSObject
}
}
Analytics.logEvent( Analytics.logEvent(
AnalyticsEventScreenView, AnalyticsEventScreenView,
parameters: parameters parameters: parameters
@ -54,10 +75,16 @@ enum FirebaseGenerator {
params: [String: Any]? params: [String: Any]?
) { ) {
var parameters: [String:NSObject] = [ var parameters: [String:NSObject] = [
AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject, AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject
AnalyticsParameterItemCategory: category as NSObject,
"action": action as NSObject,
] ]
if category.isEmpty == false {
parameters["AnalyticsParameterItemCategory"] = category as NSObject
}
if action.isEmpty == false {
parameters["action"] = action as NSObject
}
if let supplementaryParameters = params { if let supplementaryParameters = params {
for (newKey, newValue) in supplementaryParameters { for (newKey, newValue) in supplementaryParameters {
@ -79,6 +106,14 @@ enum FirebaseGenerator {
""" """
} }
private static var enable: String {
"""
func setEnable(_ enable: Bool) {
Analytics.setAnalyticsCollectionEnabled(enable)
}
"""
}
private static var footer: String { private static var footer: String {
""" """
} }

View File

@ -15,6 +15,7 @@ enum MatomoGenerator {
MatomoGenerator.setup, MatomoGenerator.setup,
MatomoGenerator.logScreen, MatomoGenerator.logScreen,
MatomoGenerator.logEvent, MatomoGenerator.logEvent,
MatomoGenerator.enable,
MatomoGenerator.footer MatomoGenerator.footer
] ]
.joined(separator: "\n") .joined(separator: "\n")
@ -66,8 +67,11 @@ enum MatomoGenerator {
private static var logScreen: String { private static var logScreen: String {
""" """
func logScreen(name: String, path: String) { func logScreen(
guard !tracker.isOptedOut else { return } name: String,
path: String,
params: [String: Any]?
) {
guard let trackerUrl = tracker.contentBase?.absoluteString else { return } guard let trackerUrl = tracker.contentBase?.absoluteString else { return }
let urlString = URL(string: "\\(trackerUrl)" + "/" + "\\(path)" + "iOS") let urlString = URL(string: "\\(trackerUrl)" + "/" + "\\(path)" + "iOS")
@ -88,8 +92,6 @@ enum MatomoGenerator {
category: String, category: String,
params: [String: Any]? params: [String: Any]?
) { ) {
guard !tracker.isOptedOut else { return }
tracker.track( tracker.track(
eventWithCategory: category, eventWithCategory: category,
action: action, action: action,
@ -98,6 +100,15 @@ enum MatomoGenerator {
url: nil url: nil
) )
} }
"""
}
private static var enable: String {
"""
func setEnable(_ enable: Bool) {
tracker.isOptedOut = !enable
}
""" """
} }

View File

@ -48,17 +48,23 @@ class AnalyticsDefinition {
} }
private func getParameters() -> String { private func getParameters() -> String {
var params = parameters
var result: String var result: String
if type == .screen { let paramsString = parameters.compactMap { parameter -> String? in
params = params.filter { param in guard parameter.value.isEmpty else { return nil }
!param.replaceIn.isEmpty
let defaultValue: String
switch parameter.type {
case .bool:
defaultValue = "\(parameter.defaultValue.lowercased())"
case .int, .double:
defaultValue = "\(parameter.defaultValue)"
case .string:
defaultValue = "\"\(parameter.defaultValue)\""
} }
}
let defaultValueString = parameter.defaultValue.isEmpty ? "" : " = \(defaultValue)"
let paramsString = params.map { parameter in return "\(parameter.name): \(parameter.type.rawValue)\(defaultValueString)"
"\(parameter.name): \(parameter.type)"
} }
if paramsString.count > 2 { if paramsString.count > 2 {
@ -84,7 +90,10 @@ class AnalyticsDefinition {
case "path": path = path.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))") case "path": path = path.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))")
case "category": category = category.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))") case "category": category = category.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))")
case "action": action = action.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))") case "action": action = action.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))")
default: break default:
if let param = parameters.first(where: { $0.name == rep }), param.value.isEmpty == false {
param.value = param.value.replacingFirstOccurrence(of: "_\(parameter.name.uppercased())_", with: "\\(\(parameter.name))")
}
} }
} }
} }
@ -99,7 +108,18 @@ class AnalyticsDefinition {
} }
supplementaryParams.forEach { param in supplementaryParams.forEach { param in
params.append("\"\(param.name)\": \(param.name)") if param.value.isEmpty {
params.append("\"\(param.name)\": \(param.name)")
} else {
switch param.type {
case .bool:
params.append("\"\(param.name)\": \(param.value.lowercased())")
case .int, .double:
params.append("\"\(param.name)\": \(param.value)")
case .string:
params.append("\"\(param.name)\": \"\(param.value)\"")
}
}
} }
if params.count > 1 { if params.count > 1 {
@ -113,14 +133,15 @@ class AnalyticsDefinition {
[\(params.joined(separator: ", "))] [\(params.joined(separator: ", "))]
""" """
} else { } else {
result = "[:]" result = "nil"
} }
if type == .screen { if type == .screen {
return """ return """
logScreen( logScreen(
name: "\(name)", name: "\(name)",
path: "\(path)" path: "\(path)",
params: \(result)
) )
""" """
} else { } else {

View File

@ -41,5 +41,7 @@ struct AnalyticsDefinitionEventDTO: Codable {
struct AnalyticsParameterDTO: Codable { struct AnalyticsParameterDTO: Codable {
var name: String var name: String
var type: String var type: String
var value: String?
var defaultValue: String?
var replaceIn: String? var replaceIn: String?
} }

View File

@ -9,13 +9,17 @@ import Foundation
class AnalyticsParameter { class AnalyticsParameter {
var name: String var name: String
var type: String var type: ParameterType
var value: String
var defaultValue: String
var replaceIn: [String] = [] var replaceIn: [String] = []
// MARK: - Init // MARK: - Init
init(name: String, type: String) { init(name: String, type: ParameterType, value: String, defaultValue: String) {
self.name = name self.name = name
self.type = type self.type = type
self.value = value
self.defaultValue = defaultValue
} }
} }

View File

@ -0,0 +1,15 @@
//
// File.swift
//
//
// Created by Loris Perret on 17/07/2024.
//
import Foundation
enum ParameterType: String {
case string = "String"
case int = "Int"
case double = "Double"
case bool = "Bool"
}

View File

@ -30,25 +30,58 @@ class AnalyticsFileParser {
} }
private static func getParameters(from parameters: [AnalyticsParameterDTO]) -> [AnalyticsParameter] { private static func getParameters(from parameters: [AnalyticsParameterDTO]) -> [AnalyticsParameter] {
parameters.map { dtoParameter in func verify(value: String?, for type: ParameterType) {
guard let value, value.isEmpty == false else { return }
switch type {
case .int:
if Int(value) == nil {
let error = AnalyticsError.invalidParameter("type of \(value) is not \(type)")
print(error.description)
Analytics.exit(withError: error)
}
case .bool:
if Bool(value.lowercased()) == nil {
let error = AnalyticsError.invalidParameter("type of \(value) is not \(type)")
print(error.description)
Analytics.exit(withError: error)
}
case .double:
if Double(value) == nil {
let error = AnalyticsError.invalidParameter("type of \(value) is not \(type)")
print(error.description)
Analytics.exit(withError: error)
}
case .string:
break
}
}
return parameters.map { dtoParameter in
// Type // Type
let type = dtoParameter.type.uppercasedFirst() let type = dtoParameter.type.uppercasedFirst()
guard guard let typeEnum = ParameterType(rawValue: type) else {
type == "String" ||
type == "Int" ||
type == "Double" ||
type == "Bool"
else {
let error = AnalyticsError.invalidParameter("type of \(dtoParameter.name)") let error = AnalyticsError.invalidParameter("type of \(dtoParameter.name)")
print(error.description) print(error.description)
Analytics.exit(withError: error) Analytics.exit(withError: error)
} }
if dtoParameter.value != nil, dtoParameter.replaceIn != nil {
let error = AnalyticsError.invalidParameter("you can't set 'value' and 'replaceIn' for \(dtoParameter.name)")
print(error.description)
Analytics.exit(withError: error)
}
verify(value: dtoParameter.value, for: typeEnum)
verify(value: dtoParameter.defaultValue, for: typeEnum)
let parameter = AnalyticsParameter( let parameter = AnalyticsParameter(
name: dtoParameter.name, name: dtoParameter.name,
type: type type: typeEnum,
value: dtoParameter.value ?? "",
defaultValue: dtoParameter.defaultValue ?? ""
) )
if let replaceIn = dtoParameter.replaceIn { if let replaceIn = dtoParameter.replaceIn {
@ -103,6 +136,8 @@ class AnalyticsFileParser {
Analytics.exit(withError: error) Analytics.exit(withError: error)
} }
definition.path = path
} else if let path = screen.path {
definition.path = path definition.path = path
} }