Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
239deb2b91 | |||
9a05ce29b8 | |||
2ec4ebcc66 | |||
6ea31a8030 | |||
df173406d4 | |||
922ed56959 | |||
ab91c1c277 | |||
aa64ce5cf7 | |||
23bf3c3a82 |
@ -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"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
83
README.md
83
README.md
@ -133,7 +133,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppTags+GreatApp.swift`)
|
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppTags+GreatApp.swift`)
|
||||||
7. `--static-members` *(optional)*: generate static properties or not
|
7. `--static-members` *(optional)*: generate static properties or not
|
||||||
|
|
||||||
> ⚠️ If extension name is not set or is `Tags`, it will generate the following typaloas `typealias Tags = String`.
|
> ⚠️ If extension name is not set or is `Tags`, it will generate the following typealias `typealias Tags = String`.
|
||||||
|
|
||||||
|
|
||||||
## Analytics
|
## Analytics
|
||||||
@ -141,7 +141,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
Analytics will generate all you need to analyze UX with Matomo or Firebase Analytics. Input files are formatted in YAML. This command will generate a manager for each target and an AnalyticsManager. This is this one you will need to use. And it will generate a method for all tags you have declared in the YAML file. Next, you will need to use the `configure()` method of AnalyticsManager and if you want to use matomo to set up the `siteId` and the `url` of the site.
|
Analytics will generate all you need to analyze UX with Matomo or Firebase Analytics. Input files are formatted in YAML. This command will generate a manager for each target and an AnalyticsManager. This is this one you will need to use. And it will generate a method for all tags you have declared in the YAML file. Next, you will need to use the `configure()` method of AnalyticsManager and if you want to use matomo to set up the `siteId` and the `url` of the site.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
swift run -c release ResgenSwift analytics $FORCE_FLAG "./Tags/analytics.yml" \
|
||||||
--target "matomo firebase" \
|
--target "matomo firebase" \
|
||||||
--extension-output-path "./Analytics/Generated" \
|
--extension-output-path "./Analytics/Generated" \
|
||||||
--extension-name "AppAnalytics" \
|
--extension-name "AppAnalytics" \
|
||||||
@ -159,7 +159,7 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppAnalytics+GreatApp.swift`)
|
6. `--extension-suffix` *(optional)* : additional text which is added to filename (ex: `AppAnalytics+GreatApp.swift`)
|
||||||
7. `--static-members` *(optional)*: generate static properties or not
|
7. `--static-members` *(optional)*: generate static properties or not
|
||||||
|
|
||||||
> ⚠️ If extension name is not set or is `Analytics`, it will generate the following typaloas `typealias Analytics = String`.
|
> ⚠️ If extension name is not set or is `Analytics`, it will generate the following typealias `typealias Analytics = String`.
|
||||||
|
|
||||||
### YAML
|
### YAML
|
||||||
|
|
||||||
@ -186,19 +186,83 @@ swift run -c release ResgenSwift strings tags $FORCE_FLAG "./Tags/tags.txt" \
|
|||||||
7. `comments` *(optional)*
|
7. `comments` *(optional)*
|
||||||
8. `parameters` *(optional)*
|
8. `parameters` *(optional)*
|
||||||
|
|
||||||
**Parameters**
|
**Parameters**
|
||||||
|
|
||||||
You can use parameters in generate methods.
|
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:
|
||||||
|
```
|
||||||
|
events:
|
||||||
|
id: id_of_tag
|
||||||
|
name: _TITLE_
|
||||||
|
tags: ios,droid
|
||||||
|
parameters:
|
||||||
|
- name: title
|
||||||
|
type: String
|
||||||
|
replaceIn: name
|
||||||
|
```
|
||||||
|
|
||||||
|
In this sample, we want to add the parameter `title` in the field `name`. So, we need to place `_TITLE_` in the field `name`.
|
||||||
|
|
||||||
|
The generated method will be:
|
||||||
|
```
|
||||||
|
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
|
||||||
|
|
||||||
@ -287,6 +351,15 @@ tags:
|
|||||||
extensionName: String?
|
extensionName: String?
|
||||||
extensionSuffix: String?
|
extensionSuffix: String?
|
||||||
staticMembers: Bool?
|
staticMembers: Bool?
|
||||||
|
|
||||||
|
analytics:
|
||||||
|
-
|
||||||
|
inputFile: String
|
||||||
|
target: String
|
||||||
|
extensionOutputPath: String
|
||||||
|
extensionName: String?
|
||||||
|
extensionSuffix: String?
|
||||||
|
staticMembers: Bool?
|
||||||
```
|
```
|
||||||
|
|
||||||
### Multiple configurations
|
### Multiple configurations
|
||||||
|
@ -6,13 +6,20 @@ 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
|
// MARK: - Matomo
|
||||||
@ -47,8 +54,11 @@ class MatomoAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
|
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
|
|
||||||
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")
|
||||||
@ -64,8 +74,6 @@ class MatomoAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
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,
|
||||||
@ -74,32 +82,27 @@ class MatomoAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
url: 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(
|
||||||
|
name: String,
|
||||||
|
path: String,
|
||||||
|
params: [String: Any]?
|
||||||
|
) {
|
||||||
var parameters = [
|
var parameters = [
|
||||||
AnalyticsParameterScreenName: name as NSObject
|
AnalyticsParameterScreenName: name as NSObject
|
||||||
]
|
]
|
||||||
|
|
||||||
Analytics.logEvent(
|
if path.isEmpty == false {
|
||||||
AnalyticsEventScreenView,
|
parameters["path"] = path + "/iOS" as NSObject
|
||||||
parameters: parameters
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logEvent(
|
|
||||||
name: String,
|
|
||||||
action: String,
|
|
||||||
category: String,
|
|
||||||
params: [String: Any]?
|
|
||||||
) {
|
|
||||||
var parameters: [String:NSObject] = [
|
|
||||||
"action": action as NSObject,
|
|
||||||
"category": category as NSObject,
|
|
||||||
]
|
|
||||||
|
|
||||||
if let supplementaryParameters = params {
|
if let supplementaryParameters = params {
|
||||||
for (newKey, newValue) in supplementaryParameters {
|
for (newKey, newValue) in supplementaryParameters {
|
||||||
@ -114,10 +117,49 @@ class FirebaseAnalyticsManager: AnalyticsManagerProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Analytics.logEvent(
|
Analytics.logEvent(
|
||||||
name.replacingOccurrences(of: [" "], with: "_"),
|
AnalyticsEventScreenView,
|
||||||
parameters: parameters
|
parameters: parameters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func logEvent(
|
||||||
|
name: String,
|
||||||
|
action: String,
|
||||||
|
category: String,
|
||||||
|
params: [String: Any]?
|
||||||
|
) {
|
||||||
|
var parameters: [String:NSObject] = [
|
||||||
|
AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject
|
||||||
|
]
|
||||||
|
|
||||||
|
if category.isEmpty == false {
|
||||||
|
parameters["AnalyticsParameterItemCategory"] = category as NSObject
|
||||||
|
}
|
||||||
|
|
||||||
|
if action.isEmpty == false {
|
||||||
|
parameters["action"] = action 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(
|
||||||
|
AnalyticsEventSelectContent,
|
||||||
|
parameters: parameters
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func setEnable(_ enable: Bool) {
|
||||||
|
Analytics.setAnalyticsCollectionEnabled(enable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Manager
|
// MARK: - Manager
|
||||||
@ -127,31 +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 enableAnalytics(_ analytics: [TargetType] = TargetType.allCases) {
|
||||||
|
setAnalytics(enable: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disableAnalytics(_ analytics: [TargetType] = TargetType.allCases) {
|
||||||
|
setAnalytics(enable: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func configure(siteId: String, url: String) {
|
func configure(siteId: String, url: String) {
|
||||||
managers.append(
|
managers[TrackerType.matomo] = MatomoAnalyticsManager(
|
||||||
MatomoAnalyticsManager(
|
siteId: siteId,
|
||||||
siteId: siteId,
|
url: url
|
||||||
url: url
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
managers.append(FirebaseAnalyticsManager())
|
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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,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,
|
||||||
@ -175,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: "s1_def_one/\(title)"
|
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: "s2_def_one/"
|
path: "s2_def_one/",
|
||||||
|
params: nil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -54,10 +54,11 @@ 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 "matomo 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" \
|
||||||
|
--static-members true
|
||||||
|
|
||||||
#echo "\n-------------------------\n"
|
#echo "\n-------------------------\n"
|
||||||
#
|
#
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -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(
|
||||||
|
name: String,
|
||||||
|
path: String,
|
||||||
|
params: [String: Any]?
|
||||||
|
) {
|
||||||
var parameters = [
|
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,17 @@ enum FirebaseGenerator {
|
|||||||
params: [String: Any]?
|
params: [String: Any]?
|
||||||
) {
|
) {
|
||||||
var parameters: [String:NSObject] = [
|
var parameters: [String:NSObject] = [
|
||||||
"action": action as NSObject,
|
AnalyticsParameterItemName: name.replacingOccurrences(of: " ", with: "_") as NSObject
|
||||||
"category": category 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 {
|
||||||
if parameters.contains(where: { (key: String, value: NSObject) in
|
if parameters.contains(where: { (key: String, value: NSObject) in
|
||||||
@ -71,13 +99,21 @@ enum FirebaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Analytics.logEvent(
|
Analytics.logEvent(
|
||||||
name.replacingOccurrences(of: [" "], with: "_"),
|
AnalyticsEventSelectContent,
|
||||||
parameters: parameters
|
parameters: parameters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static var enable: String {
|
||||||
|
"""
|
||||||
|
func setEnable(_ enable: Bool) {
|
||||||
|
Analytics.setAnalyticsCollectionEnabled(enable)
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
private static var footer: String {
|
private static var footer: String {
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 paramsString = params.map { parameter in
|
let defaultValue: String
|
||||||
"\(parameter.name): \(parameter.type)"
|
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)"
|
||||||
|
return "\(parameter.name): \(parameter.type.rawValue)\(defaultValueString)"
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
@ -150,7 +171,7 @@ class AnalyticsDefinition {
|
|||||||
replaceIn()
|
replaceIn()
|
||||||
return """
|
return """
|
||||||
static func \(getFuncName())\(getParameters()) {
|
static func \(getFuncName())\(getParameters()) {
|
||||||
\(getlogFunction())
|
AnalyticsManager.shared.\(getlogFunction())
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
@ -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?
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
Sources/ResgenSwift/Analytics/Model/ParameterType.swift
Normal file
15
Sources/ResgenSwift/Analytics/Model/ParameterType.swift
Normal 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"
|
||||||
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +174,14 @@ class AnalyticsFileParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
definition.action = action
|
definition.action = action
|
||||||
|
} else {
|
||||||
|
if let category = event.category {
|
||||||
|
definition.category = category
|
||||||
|
}
|
||||||
|
|
||||||
|
if let action = event.action {
|
||||||
|
definition.action = action
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return definition
|
return definition
|
||||||
|
@ -55,7 +55,7 @@ struct ConfigurationArchitecture: Codable {
|
|||||||
|
|
||||||
func getClass(generateStaticProperty: Bool = true) -> String {
|
func getClass(generateStaticProperty: Bool = true) -> String {
|
||||||
guard children?.isEmpty == false else {
|
guard children?.isEmpty == false else {
|
||||||
return "final class \(classname): Sendable {}"
|
return "class \(classname) {}"
|
||||||
}
|
}
|
||||||
|
|
||||||
let classDefinition = [
|
let classDefinition = [
|
||||||
|
@ -36,7 +36,7 @@ enum ImagesError: Error {
|
|||||||
return "error: [\(Images.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
return "error: [\(Images.toolName)] Getting file attributes of \(filename) failed with error: \(errorDescription)"
|
||||||
|
|
||||||
case .rsvgConvertNotFound:
|
case .rsvgConvertNotFound:
|
||||||
return "error: [\(Images.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install librsvg')"
|
return "error: [\(Images.toolName)] Can't find rsvg-convert (can be installed with 'brew remove imagemagick && brew install imagemagick --with-librsvg')"
|
||||||
|
|
||||||
case .writeFile(let subErrorDescription, let filename):
|
case .writeFile(let subErrorDescription, let filename):
|
||||||
return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
return "error: [\(Images.toolName)] An error occured while writing content to \(filename): \(subErrorDescription)"
|
||||||
|
@ -73,7 +73,7 @@ struct ParsedImage {
|
|||||||
Images.exit(withError: error)
|
Images.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(decoding: data, as: UTF8.self)
|
return String(data: data, encoding: .utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateImageContent(isVector: Bool) -> AssetContent {
|
func generateImageContent(isVector: Bool) -> AssetContent {
|
||||||
|
@ -137,7 +137,9 @@ class StringsFileGenerator {
|
|||||||
|
|
||||||
let json = try encoder.encode(rootObject)
|
let json = try encoder.encode(rootObject)
|
||||||
|
|
||||||
return String(decoding: json, as: UTF8.self)
|
if let jsonString = String(data: json, encoding: .utf8) {
|
||||||
|
return jsonString
|
||||||
|
}
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
debugPrint("Failed to encode: \(error)")
|
debugPrint("Failed to encode: \(error)")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user