SessionStartEvent.swift 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //
  2. // Copyright 2022 Google LLC
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. import Foundation
  16. @_implementationOnly import GoogleDataTransport
  17. ///
  18. /// SessionStartEvent is responsible for:
  19. /// 1) Writing fields to the Session proto
  20. /// 2) Synthesizing itself for persisting to disk and logging to GoogleDataTransport
  21. ///
  22. class SessionStartEvent: NSObject, GDTCOREventDataObject {
  23. var proto: firebase_appquality_sessions_SessionEvent
  24. init(identifiers: IdentifierProvider, appInfo: ApplicationInfoProtocol,
  25. time: TimeProvider = Time()) {
  26. proto = firebase_appquality_sessions_SessionEvent()
  27. super.init()
  28. proto.event_type = firebase_appquality_sessions_EventType_SESSION_START
  29. proto.session_data.session_id = makeProtoString(identifiers.sessionID)
  30. proto.session_data.previous_session_id = makeProtoStringOrNil(identifiers.previousSessionID)
  31. proto.session_data.event_timestamp_us = time.timestampUS
  32. proto.application_info.app_id = makeProtoString(appInfo.appID)
  33. proto.application_info.session_sdk_version = makeProtoString(appInfo.sdkVersion)
  34. proto.application_info.log_environment = convertLogEnvironment(environment: appInfo.environment)
  35. // proto.application_info.device_model = makeProtoString(appInfo.deviceModel)
  36. // proto.application_info.development_platform_name;
  37. // proto.application_info.development_platform_version;
  38. // `which_platform_info` tells nanopb which oneof we're choosing to fill in for our proto
  39. proto.application_info.which_platform_info = FIRSESGetAppleApplicationInfoTag()
  40. proto.application_info.apple_app_info.bundle_short_version = makeProtoString(appInfo.bundleID)
  41. // proto.application_info.apple_app_info.network_connection_info
  42. proto.application_info.apple_app_info.os_name = convertOSName(osName: appInfo.osName)
  43. proto.application_info.apple_app_info.mcc_mnc = makeProtoString(appInfo.mccMNC)
  44. }
  45. func setInstallationID(identifiers: IdentifierProvider) {
  46. proto.session_data.firebase_installation_id = makeProtoString(identifiers.installationID)
  47. }
  48. // MARK: - GDTCOREventDataObject
  49. func transportBytes() -> Data {
  50. var fields = firebase_appquality_sessions_SessionEvent_fields
  51. var error: NSError?
  52. let data = FIRSESEncodeProto(&fields.0, &proto, &error)
  53. if error != nil {
  54. Logger.logError(error.debugDescription)
  55. }
  56. guard let data = data else {
  57. Logger.logError("Session event generated nil transportBytes. Returning empty data.")
  58. return Data()
  59. }
  60. return data
  61. }
  62. // MARK: - Data Conversion
  63. private func makeProtoStringOrNil(_ string: String?) -> UnsafeMutablePointer<pb_bytes_array_t>? {
  64. guard let string = string else {
  65. return nil
  66. }
  67. return FIRSESEncodeString(string)
  68. }
  69. private func makeProtoString(_ string: String) -> UnsafeMutablePointer<pb_bytes_array_t>? {
  70. return FIRSESEncodeString(string)
  71. }
  72. private func convertOSName(osName: String) -> firebase_appquality_sessions_OsName {
  73. switch osName.lowercased() {
  74. case "macos":
  75. return firebase_appquality_sessions_OsName_MACOS
  76. case "maccatalyst":
  77. return firebase_appquality_sessions_OsName_MACCATALYST
  78. case "ios_on_mac":
  79. return firebase_appquality_sessions_OsName_IOS_ON_MAC
  80. case "ios":
  81. return firebase_appquality_sessions_OsName_IOS
  82. case "tvos":
  83. return firebase_appquality_sessions_OsName_TVOS
  84. case "watchos":
  85. return firebase_appquality_sessions_OsName_WATCHOS
  86. case "ipados":
  87. return firebase_appquality_sessions_OsName_IPADOS
  88. default:
  89. Logger.logWarning("Found unknown OSName: \"\(osName)\" while converting.")
  90. return firebase_appquality_sessions_OsName_UNKNOWN_OSNAME
  91. }
  92. }
  93. /// Encodes the proto in this SessionStartEvent to Data, and then decodes the Data back into
  94. /// the proto object and returns the decoded proto. This is used for validating encoding works
  95. /// and should not be used in production code.
  96. func encodeDecodeEvent() -> firebase_appquality_sessions_SessionEvent {
  97. let transportBytes = self.transportBytes()
  98. var proto = firebase_appquality_sessions_SessionEvent()
  99. var fields = firebase_appquality_sessions_SessionEvent_fields
  100. let bytes = (transportBytes as NSData).bytes
  101. var istream: pb_istream_t = pb_istream_from_buffer(bytes, transportBytes.count)
  102. if !pb_decode(&istream, &fields.0, &proto) {
  103. let errorMessage = FIRSESPBGetError(istream)
  104. if errorMessage.count > 0 {
  105. Logger.logInfo("Failed to decode transportBytes: \(errorMessage)")
  106. }
  107. }
  108. return proto
  109. }
  110. private func convertLogEnvironment(environment: DevEnvironment) -> firebase_appquality_sessions_LogEnvironment {
  111. switch environment {
  112. case .prod:
  113. return firebase_appquality_sessions_LogEnvironment_LOG_ENVIRONMENT_PROD
  114. case .staging:
  115. return firebase_appquality_sessions_LogEnvironment_LOG_ENVIRONMENT_STAGING
  116. case .autopush:
  117. return firebase_appquality_sessions_LogEnvironment_LOG_ENVIRONMENT_AUTOPUSH
  118. }
  119. }
  120. }