Add MainActor on AnalysticsManager shared property (#24)
All checks were successful
openium/resgen.swift/pipeline/head This commit looks good

Reviewed-on: #24
This commit was merged in pull request #24.
This commit is contained in:
2026-01-05 14:31:39 +01:00
parent 6debae8162
commit 0118492162
4 changed files with 70 additions and 64 deletions

2
Jenkinsfile vendored
View File

@@ -1,6 +1,6 @@
library "openiumpipeline" library "openiumpipeline"
env.DEVELOPER_DIR="/Applications/Xcode-26.0.0.app/Contents/Developer" env.DEVELOPER_DIR="/Applications/Xcode-26.2.0.app/Contents/Developer"
// env.SIMULATOR_DEVICE_TYPES="iPhone-14-Pro" // env.SIMULATOR_DEVICE_TYPES="iPhone-14-Pro"
// env.SLACK_CHANNEL = "prj-skdevkit" // env.SLACK_CHANNEL = "prj-skdevkit"
env.IS_PACKAGE_SWIFT=1 env.IS_PACKAGE_SWIFT=1

View File

@@ -104,6 +104,7 @@ enum AnalyticsGenerator {
\(visibility) class AnalyticsManager { \(visibility) class AnalyticsManager {
@MainActor
\(visibility) static var shared = AnalyticsManager() \(visibility) static var shared = AnalyticsManager()
private init() {} private init() {}
@@ -144,7 +145,7 @@ enum AnalyticsGenerator {
) -> String { ) -> String {
""" """
private var isDebugMode: Bool = false private var isDebugMode: Bool = false
private var isEnabled: Bool { private var isEnabled: Bool {
if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
false false
@@ -152,7 +153,7 @@ enum AnalyticsGenerator {
true true
} }
} }
private let logger = Logger(subsystem: "resgen", category: "analytics") private let logger = Logger(subsystem: "resgen", category: "analytics")
// MARK: - Enable Methods // MARK: - Enable Methods
@@ -198,18 +199,18 @@ enum AnalyticsGenerator {
private static func getPrivateLogFunction() -> String { private static func getPrivateLogFunction() -> String {
""" """
// MARK: - Private Log Methods // MARK: - Private Log Methods
private func formattedParams(_ params: [String: Any]?) -> String { private func formattedParams(_ params: [String: Any]?) -> String {
guard let params = params, !params.isEmpty else { return "-" } guard let params = params, !params.isEmpty else { return "-" }
let formattedParams = params.map { key, value in let formattedParams = params.map { key, value in
" \\(key): \\(value)" " \\(key): \\(value)"
} }
.joined(separator: "\\n") .joined(separator: "\\n")
return "\\n" + formattedParams return "\\n" + formattedParams
} }
private func logScreen( private func logScreen(
name: String, name: String,
path: String, path: String,
@@ -219,11 +220,11 @@ enum AnalyticsGenerator {
if isDebugMode { if isDebugMode {
logger.log("Analytics disabled") logger.log("Analytics disabled")
} }
return return
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
🖥️ Screen: 🖥️ Screen:
@@ -232,7 +233,7 @@ enum AnalyticsGenerator {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logScreen( manager.logScreen(
name: name, name: name,
path: path, path: path,
@@ -240,7 +241,7 @@ enum AnalyticsGenerator {
) )
} }
} }
private func logEvent( private func logEvent(
name: String, name: String,
action: String, action: String,
@@ -251,11 +252,11 @@ enum AnalyticsGenerator {
if isDebugMode { if isDebugMode {
logger.log("Analytics disabled") logger.log("Analytics disabled")
} }
return return
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
📊 Event: 📊 Event:
@@ -265,7 +266,7 @@ enum AnalyticsGenerator {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logEvent( manager.logEvent(
name: name, name: name,
action: action, action: action,

View File

@@ -16,12 +16,14 @@ struct GenerateOptions: ParsableArguments {
@Argument(help: "Configuration file.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) @Argument(help: "Configuration file.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
var configurationFile: String var configurationFile: String
@Option(help: "Project directory. It will be added to every relative path (path that does not start with `/`", @Option(
transform: { help: "Project directory. It will be added to every relative path (path that does not start with `/`",
if $0.last == "/" { transform: {
return $0 if $0.last == "/" {
return $0
}
return $0 + "/"
} }
return $0 + "/" )
})
var projectDirectory: String var projectDirectory: String
} }

View File

@@ -35,22 +35,22 @@ final class AnalyticsGeneratorTests: XCTestCase {
private func protocolString(visibility: ExtensionVisibility) -> String { private func protocolString(visibility: ExtensionVisibility) -> String {
""" """
// MARK: - Protocol // MARK: - Protocol
\(visibility) protocol AnalyticsManagerProtocol { \(visibility) protocol AnalyticsManagerProtocol {
func logScreen( func logScreen(
name: String, name: String,
path: String, path: String,
params: [String: Any]? 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) func setEnable(_ enable: Bool)
} }
""" """
@@ -94,7 +94,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
parameters: parameters parameters: parameters
) )
} }
func logEvent( func logEvent(
name: String, name: String,
action: String, action: String,
@@ -260,6 +260,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
internal class AnalyticsManager { internal class AnalyticsManager {
@MainActor
internal static var shared = AnalyticsManager() internal static var shared = AnalyticsManager()
private init() {} private init() {}
@@ -267,7 +268,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
// MARK: - Properties // MARK: - Properties
var managers: [TrackerType: AnalyticsManagerProtocol] = [:] var managers: [TrackerType: AnalyticsManagerProtocol] = [:]
private var isDebugMode: Bool = false private var isDebugMode: Bool = false
private var isEnabled: Bool { private var isEnabled: Bool {
@@ -277,7 +278,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
true true
} }
} }
private let logger = Logger(subsystem: "resgen", category: "analytics") private let logger = Logger(subsystem: "resgen", category: "analytics")
// MARK: - Enable Methods // MARK: - Enable Methods
@@ -306,15 +307,15 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
// MARK: - Private Log Methods // MARK: - Private Log Methods
private func formattedParams(_ params: [String: Any]?) -> String { private func formattedParams(_ params: [String: Any]?) -> String {
guard let params = params, !params.isEmpty else { return "-" } guard let params = params, !params.isEmpty else { return "-" }
let formattedParams = params.map { key, value in let formattedParams = params.map { key, value in
" \\(key): \\(value)" " \\(key): \\(value)"
} }
.joined(separator: "\\n") .joined(separator: "\\n")
return "\\n" + formattedParams return "\\n" + formattedParams
} }
@@ -331,7 +332,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
🖥️ Screen: 🖥️ Screen:
@@ -340,7 +341,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logScreen( manager.logScreen(
name: name, name: name,
path: path, path: path,
@@ -363,7 +364,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
📊 Event: 📊 Event:
@@ -373,7 +374,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logEvent( manager.logEvent(
name: name, name: name,
action: action, action: action,
@@ -472,6 +473,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
internal class AnalyticsManager { internal class AnalyticsManager {
@MainActor
internal static var shared = AnalyticsManager() internal static var shared = AnalyticsManager()
private init() {} private init() {}
@@ -479,7 +481,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
// MARK: - Properties // MARK: - Properties
var managers: [TrackerType: AnalyticsManagerProtocol] = [:] var managers: [TrackerType: AnalyticsManagerProtocol] = [:]
private var isDebugMode: Bool = false private var isDebugMode: Bool = false
private var isEnabled: Bool { private var isEnabled: Bool {
@@ -489,7 +491,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
true true
} }
} }
private let logger = Logger(subsystem: "resgen", category: "analytics") private let logger = Logger(subsystem: "resgen", category: "analytics")
// MARK: - Enable Methods // MARK: - Enable Methods
@@ -524,12 +526,12 @@ final class AnalyticsGeneratorTests: XCTestCase {
private func formattedParams(_ params: [String: Any]?) -> String { private func formattedParams(_ params: [String: Any]?) -> String {
guard let params = params, !params.isEmpty else { return "-" } guard let params = params, !params.isEmpty else { return "-" }
let formattedParams = params.map { key, value in let formattedParams = params.map { key, value in
" \\(key): \\(value)" " \\(key): \\(value)"
} }
.joined(separator: "\\n") .joined(separator: "\\n")
return "\\n" + formattedParams return "\\n" + formattedParams
} }
@@ -544,9 +546,9 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
return return
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
🖥️ Screen: 🖥️ Screen:
@@ -555,7 +557,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logScreen( manager.logScreen(
name: name, name: name,
path: path, path: path,
@@ -563,7 +565,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
) )
} }
} }
private func logEvent( private func logEvent(
name: String, name: String,
action: String, action: String,
@@ -576,9 +578,9 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
return return
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
📊 Event: 📊 Event:
@@ -588,7 +590,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logEvent( manager.logEvent(
name: name, name: name,
action: action, action: action,
@@ -597,9 +599,9 @@ final class AnalyticsGeneratorTests: XCTestCase {
) )
} }
} }
// MARK: - section_one // MARK: - section_one
internal func logScreenS1DefOne() { internal func logScreenS1DefOne() {
logScreen( logScreen(
name: "s1 def one", name: "s1 def one",
@@ -607,7 +609,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
params: nil params: nil
) )
} }
internal func logEventS1DefTwo() { internal func logEventS1DefTwo() {
logEvent( logEvent(
name: "s1 def two", name: "s1 def two",
@@ -616,9 +618,9 @@ final class AnalyticsGeneratorTests: XCTestCase {
params: nil params: nil
) )
} }
// MARK: - section_two // MARK: - section_two
internal func logScreenS2DefOne() { internal func logScreenS2DefOne() {
logScreen( logScreen(
name: "s2 def one", name: "s2 def one",
@@ -692,6 +694,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
internal class AnalyticsManager { internal class AnalyticsManager {
@MainActor
internal static var shared = AnalyticsManager() internal static var shared = AnalyticsManager()
private init() {} private init() {}
@@ -699,7 +702,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
// MARK: - Properties // MARK: - Properties
var managers: [TrackerType: AnalyticsManagerProtocol] = [:] var managers: [TrackerType: AnalyticsManagerProtocol] = [:]
private var isDebugMode: Bool = false private var isDebugMode: Bool = false
private var isEnabled: Bool { private var isEnabled: Bool {
@@ -709,7 +712,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
true true
} }
} }
private let logger = Logger(subsystem: "resgen", category: "analytics") private let logger = Logger(subsystem: "resgen", category: "analytics")
// MARK: - Enable Methods // MARK: - Enable Methods
@@ -742,15 +745,15 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
// MARK: - Private Log Methods // MARK: - Private Log Methods
private func formattedParams(_ params: [String: Any]?) -> String { private func formattedParams(_ params: [String: Any]?) -> String {
guard let params = params, !params.isEmpty else { return "-" } guard let params = params, !params.isEmpty else { return "-" }
let formattedParams = params.map { key, value in let formattedParams = params.map { key, value in
" \\(key): \\(value)" " \\(key): \\(value)"
} }
.joined(separator: "\\n") .joined(separator: "\\n")
return "\\n" + formattedParams return "\\n" + formattedParams
} }
@@ -765,9 +768,9 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
return return
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
🖥️ Screen: 🖥️ Screen:
@@ -776,7 +779,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logScreen( manager.logScreen(
name: name, name: name,
path: path, path: path,
@@ -784,7 +787,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
) )
} }
} }
private func logEvent( private func logEvent(
name: String, name: String,
action: String, action: String,
@@ -797,9 +800,9 @@ final class AnalyticsGeneratorTests: XCTestCase {
} }
return return
} }
managers.values.forEach { manager in managers.values.forEach { manager in
if isDebugMode { if isDebugMode {
logger.debug(\""" logger.debug(\"""
📊 Event: 📊 Event:
@@ -809,7 +812,7 @@ final class AnalyticsGeneratorTests: XCTestCase {
Params: \\(self.formattedParams(params), privacy: .public) Params: \\(self.formattedParams(params), privacy: .public)
\""") \""")
} }
manager.logEvent( manager.logEvent(
name: name, name: name,
action: action, action: action,