Issue #395
Prefer static enum to avoid repetition and error. The Log should have methods with all required fields so the call site is as simple as possible. How to format and assign parameters is encapsulated in this Analytics.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 import Foundationimport Firebaseimport FirebaseAnalyticsstruct Analytics { enum Parameter : String { case studentId = "student_id" case classId = "class_id" case url = "url" } enum Property : String { case grantLocation = "grant_location" } enum Name : String { case login case logOut = "log_out" case enroll } struct Log { private func log (_ name: Name, parameters: [Parameter: String] = [:]) { let mapped: [String : String ] = Dictionary (uniqueKeysWithValues: parameters.map ({ key, value in return (key.rawValue, value) })) FirebaseAnalytics .Analytics .logEvent(name.rawValue, parameters: mapped) } private func set (userId: String?) { FirebaseAnalytics .Analytics .setUserID(userId) } private func setProperty (_ property: Property, value: String) { FirebaseAnalytics .Analytics .setUserProperty(value, forName: property.rawValue) } } let log = Log () } extension Analytics .Log { func grantLocation (hasGranted: Bool) { setProperty(.grantLocation, value: hasGranted.toString ()) } func login (userId: String) { log(.login) set (userId: userId) } func logOut () { log(.logOut) set (userId: nil ) } func enroll (classId: String) { log(.enroll, parameters: [ .classId: classId ]) } } private extension Bool { func toString () -> String { return self ? "yes" : "no" } }