// // AnalyticsGenerator.swift // // // Created by Loris Perret on 08/12/2023. // import Foundation import ToolCore import CoreVideo class AnalyticsGenerator { static var targets: [TrackerType] = [] static func writeExtensionFiles(sections: [AnalyticsCategory], target: String, tags: [String], staticVar: Bool, extensionName: String, extensionFilePath: String) { // Get target type from enum let targetsString: [String] = target.components(separatedBy: " ") TrackerType.allCases.forEach { enumTarget in if targetsString.contains(enumTarget.value) { targets.append(enumTarget) } } // Get extension content let extensionFileContent = Self.getExtensionContent(sections: sections, tags: tags, staticVar: staticVar, extensionName: extensionName) // Write content let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath) do { try extensionFileContent.write(to: extensionFilePathURL, atomically: false, encoding: .utf8) } catch let error { let error = AnalyticsError.writeFile(extensionFilePath, error.localizedDescription) print(error.description) Analytics.exit(withError: error) } } // MARK: - Extension content static func getExtensionContent(sections: [AnalyticsCategory], tags: [String], staticVar: Bool, extensionName: String) -> String { [ Self.getHeader(extensionClassname: extensionName, staticVar: staticVar), Self.getProperties(sections: sections, tags: tags, staticVar: staticVar), Self.getFooter() ] .joined(separator: "\n") } // MARK: - Extension part private static func getHeader(extensionClassname: String, staticVar: Bool) -> String { """ // Generated by ResgenSwift.\(Analytics.toolName) \(ResgenSwiftVersion) \(Self.getImport()) \(Self.getAnalyticsProtocol()) // MARK: - Manager class AnalyticsManager { static var shared = AnalyticsManager() // MARK: - Properties var managers: [AnalyticsManagerProtocol] = [] \(Self.getEnabledContent()) \(Self.getAnalyticsProperties()) \(Self.getPrivateLogFunction()) """ } private static func getEnabledContent() -> String { """ private var isEnabled: Bool = true // MARK: - Methods func setAnalyticsEnabled(_ enable: Bool) { isEnabled = enable } """ } private static func getImport() -> String { var result: [String] = [] if targets.contains(TrackerType.matomo) { result.append("import MatomoTracker") } if targets.contains(TrackerType.firebase) { result.append("import FirebaseAnalytics") } return result.joined(separator: "\n") } private static func getPrivateLogFunction() -> String { """ private func logScreen(name: String, path: String) { guard isEnabled else { return } managers.forEach { manager in manager.logScreen(name: name, path: path) } } private func logEvent( name: String, action: String, category: String, params: [String: Any]? ) { guard isEnabled else { return } managers.forEach { manager in manager.logEvent( name: name, action: action, category: category, params: params ) } } """ } private static func getAnalyticsProperties() -> String { var header = "" var content: [String] = [] let footer = " }" if targets.contains(TrackerType.matomo) { header = "func configure(siteId: String, url: String) {" } else if targets.contains(TrackerType.firebase) { header = "func configure() {" } if targets.contains(TrackerType.matomo) { content.append(""" managers.append( MatomoAnalyticsManager( siteId: siteId, url: url ) ) """) } if targets.contains(TrackerType.firebase) { content.append(" managers.append(FirebaseAnalyticsManager())") } return [ header, content.joined(separator: "\n"), footer ] .joined(separator: "\n") } private static func getAnalyticsProtocol() -> String { let proto = """ // MARK: - Protocol protocol AnalyticsManagerProtocol { func logScreen(name: String, path: String) func logEvent( name: String, action: String, category: String, params: [String: Any]? ) } """ var result: [String] = [proto] if targets.contains(TrackerType.matomo) { result.append(MatomoGenerator.service) } if targets.contains(TrackerType.firebase) { result.append(FirebaseGenerator.service) } return result.joined(separator: "\n") } private static func getProperties(sections: [AnalyticsCategory], tags: [String], staticVar: Bool) -> String { sections .compactMap { section in // Check that at least one string will be generated guard section.hasOneOrMoreMatchingTags(tags: tags) else { return nil// Go to next section } var res = "\n // MARK: - \(section.id)" section.definitions.forEach { definition in guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { return // Go to next definition } if staticVar { res += "\n\n\(definition.getStaticProperty())" } else { res += "\n\n\(definition.getProperty())" } } return res } .joined(separator: "\n") } private static func getFooter() -> String { """ } """ } }