diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df5e5f4923..4f066fa369 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -136,7 +136,7 @@ Smoke Tests (iOS): PLATFORM: "iOS Simulator" DEVICE: "iPhone 15 Pro" script: - - ./tools/runner-setup.sh --xcode "$XCODE" --iOS --os "$OS" # temporary, waiting for AMI + - ./tools/runner-setup.sh --xcode "$XCODE" --iOS --tvOS --os "$OS" # temporary, waiting for AMI - make clean repo-setup ENV=ci - make spm-build-ios - make smoke-test-ios-all OS="$OS" PLATFORM="$PLATFORM" DEVICE="$DEVICE" @@ -152,7 +152,7 @@ Smoke Tests (tvOS): PLATFORM: "tvOS Simulator" DEVICE: "Apple TV" script: - - ./tools/runner-setup.sh --xcode "$XCODE" --tvOS --os "$OS" # temporary, waiting for AMI + - ./tools/runner-setup.sh --xcode "$XCODE" --iOS --tvOS --os "$OS" # temporary, waiting for AMI - make clean repo-setup ENV=ci - make spm-build-tvos - make smoke-test-tvos-all OS="$OS" PLATFORM="$PLATFORM" DEVICE="$DEVICE" diff --git a/CHANGELOG.md b/CHANGELOG.md index 12b8c5baa9..4097780939 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Unreleased +# 2.14.1 / 09-07-2024 + +- [FIX] Objc attributes interop for KMP. See [#1947][] +- [FIX] Inject backtrace reporter into Logs feature. See [#1948][] + # 2.14.0 / 04-07-2024 - [IMPROVEMENT] Use `#fileID` over `#filePath` as the default argument in errors. See [#1938][] @@ -708,6 +713,8 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO [#1925]: https://github.com/DataDog/dd-sdk-ios/pull/1925 [#1934]: https://github.com/DataDog/dd-sdk-ios/pull/1934 [#1938]: https://github.com/DataDog/dd-sdk-ios/pull/1938 +[#1947]: https://github.com/DataDog/dd-sdk-ios/pull/1947 +[#1948]: https://github.com/DataDog/dd-sdk-ios/pull/1948 [@00fa9a]: https://github.com/00FA9A [@britton-earnin]: https://github.com/Britton-Earnin [@hengyu]: https://github.com/Hengyu diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index e5c9f41ff7..ebda4a4175 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -268,7 +268,6 @@ 61133BD92423979B00786299 /* DataUploadDelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133BB32423979B00786299 /* DataUploadDelay.swift */; }; 61133C00242397DA00786299 /* DatadogObjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 61133BF2242397DA00786299 /* DatadogObjc.h */; settings = {ATTRIBUTES = (Public, ); }; }; 61133C0E2423983800786299 /* Datadog+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C092423983800786299 /* Datadog+objc.swift */; }; - 61133C0F2423983800786299 /* ObjcIntercompatibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0B2423983800786299 /* ObjcIntercompatibility.swift */; }; 61133C102423983800786299 /* Logs+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0C2423983800786299 /* Logs+objc.swift */; }; 61133C112423983800786299 /* DatadogConfiguration+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0D2423983800786299 /* DatadogConfiguration+objc.swift */; }; 61133C482423990D00786299 /* DDDatadogTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C142423990D00786299 /* DDDatadogTests.swift */; }; @@ -1504,7 +1503,6 @@ D2CB6F8427C520D400A62B57 /* DatadogTestsObserverLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 6184751726EFD03400C7C9C5 /* DatadogTestsObserverLoader.m */; }; D2CB6F8527C520D400A62B57 /* PerformancePresetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61345612244756E300E7DA6B /* PerformancePresetTests.swift */; }; D2CB6F9627C5217A00A62B57 /* DatadogObjc.h in Headers */ = {isa = PBXBuildFile; fileRef = 61133BF2242397DA00786299 /* DatadogObjc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D2CB6F9827C5217A00A62B57 /* ObjcIntercompatibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61133C0B2423983800786299 /* ObjcIntercompatibility.swift */; }; D2CB6F9927C5217A00A62B57 /* Casting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF5024A49F7400D7BD17 /* Casting.swift */; }; D2CB6F9A27C5217A00A62B57 /* RUMDataModels+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6111C58125C0081F00F5C4A2 /* RUMDataModels+objc.swift */; }; D2CB6F9B27C5217A00A62B57 /* DDSpanContext+objc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6132BF4824A49B6800D7BD17 /* DDSpanContext+objc.swift */; }; @@ -2298,7 +2296,6 @@ 61133BF2242397DA00786299 /* DatadogObjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DatadogObjc.h; sourceTree = ""; }; 61133BF3242397DA00786299 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61133C092423983800786299 /* Datadog+objc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Datadog+objc.swift"; sourceTree = ""; }; - 61133C0B2423983800786299 /* ObjcIntercompatibility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjcIntercompatibility.swift; sourceTree = ""; }; 61133C0C2423983800786299 /* Logs+objc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Logs+objc.swift"; sourceTree = ""; }; 61133C0D2423983800786299 /* DatadogConfiguration+objc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DatadogConfiguration+objc.swift"; sourceTree = ""; }; 61133C142423990D00786299 /* DDDatadogTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DDDatadogTests.swift; sourceTree = ""; }; @@ -4222,20 +4219,11 @@ 6111C58025C0080C00F5C4A2 /* RUM */, 6132BF4024A38D0600D7BD17 /* OpenTracing */, D2A434A72A8E3FFB0028E329 /* SessionReplay */, - 61133C0A2423983800786299 /* ObjcIntercompatibility */, ); name = DatadogObjc; path = ../DatadogObjc/Sources; sourceTree = ""; }; - 61133C0A2423983800786299 /* ObjcIntercompatibility */ = { - isa = PBXGroup; - children = ( - 61133C0B2423983800786299 /* ObjcIntercompatibility.swift */, - ); - path = ObjcIntercompatibility; - sourceTree = ""; - }; 61133C122423990D00786299 /* DatadogCoreTests */ = { isa = PBXGroup; children = ( @@ -8226,7 +8214,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 61133C0F2423983800786299 /* ObjcIntercompatibility.swift in Sources */, 6132BF5124A49F7400D7BD17 /* Casting.swift in Sources */, 6111C58225C0081F00F5C4A2 /* RUMDataModels+objc.swift in Sources */, 6132BF4924A49B6800D7BD17 /* DDSpanContext+objc.swift in Sources */, @@ -9484,7 +9471,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D2CB6F9827C5217A00A62B57 /* ObjcIntercompatibility.swift in Sources */, D2CB6F9927C5217A00A62B57 /* Casting.swift in Sources */, D2CB6F9A27C5217A00A62B57 /* RUMDataModels+objc.swift in Sources */, D2CB6F9B27C5217A00A62B57 /* DDSpanContext+objc.swift in Sources */, diff --git a/DatadogAlamofireExtension.podspec b/DatadogAlamofireExtension.podspec index 489329b06b..30294e1b7a 100644 --- a/DatadogAlamofireExtension.podspec +++ b/DatadogAlamofireExtension.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogAlamofireExtension" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "An Official Extensions of Datadog Swift SDK for Alamofire." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogCore.podspec b/DatadogCore.podspec index bd9481c460..bb47bedf5e 100644 --- a/DatadogCore.podspec +++ b/DatadogCore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogCore" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Swift SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogCore/Sources/Versioning.swift b/DatadogCore/Sources/Versioning.swift index 018926618d..3298b7561f 100644 --- a/DatadogCore/Sources/Versioning.swift +++ b/DatadogCore/Sources/Versioning.swift @@ -1,3 +1,3 @@ // GENERATED FILE: Do not edit directly -internal let __sdkVersion = "2.14.0" +internal let __sdkVersion = "2.14.1" diff --git a/DatadogCore/Tests/DatadogObjc/DDDatadogTests.swift b/DatadogCore/Tests/DatadogObjc/DDDatadogTests.swift index b798ef6ff1..1f7e7f7d87 100644 --- a/DatadogCore/Tests/DatadogObjc/DDDatadogTests.swift +++ b/DatadogCore/Tests/DatadogObjc/DDDatadogTests.swift @@ -140,10 +140,10 @@ class DDDatadogTests: XCTestCase { XCTAssertEqual(userInfo.current.name, "name") XCTAssertEqual(userInfo.current.email, "email") let extraInfo = userInfo.current.extraInfo - XCTAssertEqual(extraInfo["attribute-int"] as? Int, 42) - XCTAssertEqual(extraInfo["attribute-double"] as? Double, 42.5) - XCTAssertEqual(extraInfo["attribute-string"] as? String, "string value") - XCTAssertEqual(extraInfo["foo"] as? String, "bar") + XCTAssertEqual(extraInfo["attribute-int"]?.dd.decode(), 42) + XCTAssertEqual(extraInfo["attribute-double"]?.dd.decode(), 42.5) + XCTAssertEqual(extraInfo["attribute-string"]?.dd.decode(), "string value") + XCTAssertEqual(extraInfo["foo"]?.dd.decode(), "bar") DDDatadog.setUserInfo(id: nil, name: nil, email: nil, extraInfo: [:]) XCTAssertNil(userInfo.current.id) diff --git a/DatadogCore/Tests/DatadogObjc/DDRUMMonitorTests.swift b/DatadogCore/Tests/DatadogObjc/DDRUMMonitorTests.swift index 8f2a1659e9..059b376c1a 100644 --- a/DatadogCore/Tests/DatadogObjc/DDRUMMonitorTests.swift +++ b/DatadogCore/Tests/DatadogObjc/DDRUMMonitorTests.swift @@ -34,7 +34,7 @@ class DDRUMViewTests: XCTestCase { func testItCreatesSwiftRUMView() { let objcRUMView = DDRUMView(name: "name", attributes: ["foo": "bar"]) XCTAssertEqual(objcRUMView.swiftView.name, "name") - XCTAssertEqual(objcRUMView.swiftView.attributes["foo"] as? String, "bar") + XCTAssertEqual(objcRUMView.swiftView.attributes["foo"]?.dd.decode(), "bar") XCTAssertEqual(objcRUMView.name, "name") XCTAssertEqual(objcRUMView.attributes["foo"] as? String, "bar") } @@ -80,7 +80,7 @@ class DDRUMActionTests: XCTestCase { func testItCreatesSwiftRUMAction() { let objcRUMAction = DDRUMAction(name: "name", attributes: ["foo": "bar"]) XCTAssertEqual(objcRUMAction.swiftAction.name, "name") - XCTAssertEqual(objcRUMAction.swiftAction.attributes["foo"] as? String, "bar") + XCTAssertEqual(objcRUMAction.swiftAction.attributes["foo"]?.dd.decode(), "bar") XCTAssertEqual(objcRUMAction.name, "name") XCTAssertEqual(objcRUMAction.attributes["foo"] as? String, "bar") } diff --git a/DatadogCore/Tests/DatadogObjc/DDTraceConfigurationTests.swift b/DatadogCore/Tests/DatadogObjc/DDTraceConfigurationTests.swift index 16957ca9a5..7e4aff6885 100644 --- a/DatadogCore/Tests/DatadogObjc/DDTraceConfigurationTests.swift +++ b/DatadogCore/Tests/DatadogObjc/DDTraceConfigurationTests.swift @@ -6,6 +6,7 @@ import XCTest import TestUtilities +import DatadogInternal @testable import DatadogTrace @testable import DatadogObjc @@ -26,10 +27,10 @@ class DDTraceConfigurationTests: XCTestCase { } func testTags() { - let random = mockRandomAttributes() + let random: [String: Any] = mockRandomAttributes() objc.tags = random - DDAssertDictionariesEqual(objc.tags!, random) - DDAssertReflectionEqual(swift.tags!, castAttributesToSwift(random)) + DDAssertJSONEqual(objc.tags!, random) + DDAssertReflectionEqual(swift.tags!, random.dd.swiftAttributes) } func testSetDDTraceURLSessionTracking() { diff --git a/DatadogCore/Tests/DatadogObjc/RUM/RUMDataModels+objcTests.swift b/DatadogCore/Tests/DatadogObjc/RUM/RUMDataModels+objcTests.swift index 9c337099bf..b87370e5f3 100644 --- a/DatadogCore/Tests/DatadogObjc/RUM/RUMDataModels+objcTests.swift +++ b/DatadogCore/Tests/DatadogObjc/RUM/RUMDataModels+objcTests.swift @@ -17,8 +17,8 @@ class RUMDataModels_objcTests: XCTestCase { // Given var swiftView: RUMViewEvent = .mockRandom() - swiftView.context?.contextInfo = castAttributesToSwift(expectedContextAttributes) - swiftView.usr?.usrInfo = castAttributesToSwift(expectedUserInfoAttributes) + swiftView.context?.contextInfo = expectedContextAttributes.dd.swiftAttributes + swiftView.usr?.usrInfo = expectedUserInfoAttributes.dd.swiftAttributes let objcView = DDRUMViewEvent(swiftModel: swiftView) @@ -37,8 +37,8 @@ class RUMDataModels_objcTests: XCTestCase { // Given var swiftResource: RUMResourceEvent = .mockRandom() - swiftResource.context?.contextInfo = castAttributesToSwift(expectedContextAttributes) - swiftResource.usr?.usrInfo = castAttributesToSwift(expectedUserInfoAttributes) + swiftResource.context?.contextInfo = expectedContextAttributes.dd.swiftAttributes + swiftResource.usr?.usrInfo = expectedUserInfoAttributes.dd.swiftAttributes let objcResource = DDRUMResourceEvent(swiftModel: swiftResource) @@ -57,8 +57,8 @@ class RUMDataModels_objcTests: XCTestCase { // Given var swiftAction: RUMActionEvent = .mockRandom() - swiftAction.context?.contextInfo = castAttributesToSwift(expectedContextAttributes) - swiftAction.usr?.usrInfo = castAttributesToSwift(expectedUserInfoAttributes) + swiftAction.context?.contextInfo = expectedContextAttributes.dd.swiftAttributes + swiftAction.usr?.usrInfo = expectedUserInfoAttributes.dd.swiftAttributes let objcAction = DDRUMActionEvent(swiftModel: swiftAction) @@ -77,8 +77,8 @@ class RUMDataModels_objcTests: XCTestCase { // Given var swiftError: RUMErrorEvent = .mockRandom() - swiftError.context?.contextInfo = castAttributesToSwift(expectedContextAttributes) - swiftError.usr?.usrInfo = castAttributesToSwift(expectedUserInfoAttributes) + swiftError.context?.contextInfo = expectedContextAttributes.dd.swiftAttributes + swiftError.usr?.usrInfo = expectedUserInfoAttributes.dd.swiftAttributes let objcError = DDRUMErrorEvent(swiftModel: swiftError) @@ -97,8 +97,8 @@ class RUMDataModels_objcTests: XCTestCase { // Given var swiftLongTask: RUMLongTaskEvent = .mockRandom() - swiftLongTask.context?.contextInfo = castAttributesToSwift(expectedContextAttributes) - swiftLongTask.usr?.usrInfo = castAttributesToSwift(expectedUserInfoAttributes) + swiftLongTask.context?.contextInfo = expectedContextAttributes.dd.swiftAttributes + swiftLongTask.usr?.usrInfo = expectedUserInfoAttributes.dd.swiftAttributes let objcLongTask = DDRUMLongTaskEvent(swiftModel: swiftLongTask) diff --git a/DatadogCrashReporting.podspec b/DatadogCrashReporting.podspec index e149328fc9..bdbbddef39 100644 --- a/DatadogCrashReporting.podspec +++ b/DatadogCrashReporting.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogCrashReporting" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Crash Reporting SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogInternal.podspec b/DatadogInternal.podspec index cccacea351..c5ca4de7cd 100644 --- a/DatadogInternal.podspec +++ b/DatadogInternal.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogInternal" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Datadog Internal Package. This module is not for public use." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogInternal/Sources/Attributes/Attributes.swift b/DatadogInternal/Sources/Attributes/Attributes.swift index 5ee57a30f0..362374d48b 100644 --- a/DatadogInternal/Sources/Attributes/Attributes.swift +++ b/DatadogInternal/Sources/Attributes/Attributes.swift @@ -163,3 +163,39 @@ public struct LaunchArguments { /// For example, if this flag is present it can use no sampling. public static let Debug = "DD_DEBUG" } + +extension DatadogExtension where ExtendedType == [String: Any] { + public var swiftAttributes: [String: Encodable] { + type.mapValues { AnyEncodable($0) } + } +} + +extension DatadogExtension where ExtendedType == [String: Encodable] { + public var objCAttributes: [String: Any] { + type.compactMapValues { ($0 as? AnyEncodable)?.value } + } +} + +extension AttributeValue { + /// Instance Datadog extension point. + /// + /// `AttributeValue` aka `Encodable` is a protocol and cannot be extended + /// with conformance to`DatadogExtension`, so we need to define the `dd` + /// endpoint. + public var dd: DatadogExtension { + DatadogExtension(self) + } +} + +extension DatadogExtension where ExtendedType == AttributeValue { + public func decode(_: T.Type = T.self) -> T? { + switch type { + case let encodable as _AnyEncodable: + return encodable.value as? T + case let val as T: + return val + default: + return nil + } + } +} diff --git a/DatadogInternal/Sources/Extensions/DatadogExtended.swift b/DatadogInternal/Sources/Extensions/DatadogExtended.swift index 4b840bd452..7d37267226 100644 --- a/DatadogInternal/Sources/Extensions/DatadogExtended.swift +++ b/DatadogInternal/Sources/Extensions/DatadogExtended.swift @@ -46,3 +46,6 @@ extension DatadogExtended { set {} } } + +extension Array: DatadogExtended {} +extension Dictionary: DatadogExtended {} diff --git a/DatadogLogs.podspec b/DatadogLogs.podspec index 61445c6cb7..43a208c2b8 100644 --- a/DatadogLogs.podspec +++ b/DatadogLogs.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogLogs" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Datadog Logs Module." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogLogs/Sources/Logs.swift b/DatadogLogs/Sources/Logs.swift index 62ac807df6..c55513bcb1 100644 --- a/DatadogLogs/Sources/Logs.swift +++ b/DatadogLogs/Sources/Logs.swift @@ -64,7 +64,8 @@ public enum Logs { logEventMapper: logEventMapper, dateProvider: configuration.dateProvider, customIntakeURL: configuration.customEndpoint, - telemetry: core.telemetry + telemetry: core.telemetry, + backtraceReporter: core.backtraceReporter ) do { diff --git a/DatadogLogs/Sources/RemoteLogger.swift b/DatadogLogs/Sources/RemoteLogger.swift index 1506defdf7..2533c54d84 100644 --- a/DatadogLogs/Sources/RemoteLogger.swift +++ b/DatadogLogs/Sources/RemoteLogger.swift @@ -111,9 +111,9 @@ internal final class RemoteLogger: LoggerProtocol { // capture current tags and attributes before opening the write event context let tags = self.tags var logAttributes = attributes - let isCrash = logAttributes?.removeValue(forKey: CrossPlatformAttributes.errorLogIsCrash) as? Bool ?? false - let errorFingerprint = logAttributes?.removeValue(forKey: Logs.Attributes.errorFingerprint) as? String - let addBinaryImages = logAttributes?.removeValue(forKey: CrossPlatformAttributes.includeBinaryImages) as? Bool ?? false + let isCrash = logAttributes?.removeValue(forKey: CrossPlatformAttributes.errorLogIsCrash)?.dd.decode() ?? false + let errorFingerprint: String? = logAttributes?.removeValue(forKey: Logs.Attributes.errorFingerprint)?.dd.decode() + let addBinaryImages = logAttributes?.removeValue(forKey: CrossPlatformAttributes.includeBinaryImages)?.dd.decode() ?? false let userAttributes = self.attributes .merging(logAttributes ?? [:]) { $1 } // prefer message attributes let combinedAttributes: [String: any Encodable] diff --git a/DatadogLogs/Tests/LogsTests.swift b/DatadogLogs/Tests/LogsTests.swift index 72c202dfce..8e29b2fac7 100644 --- a/DatadogLogs/Tests/LogsTests.swift +++ b/DatadogLogs/Tests/LogsTests.swift @@ -39,6 +39,18 @@ class LogsTests: XCTestCase { XCTAssertTrue(Logs._internal.isEnabled(in: core)) } + func testInitializedWithBacktraceReporter() throws { + // Given + let core = FeatureRegistrationCoreMock() + + // When + Logs.enable(in: core) + + // Then + let logs = try XCTUnwrap(core.get(feature: LogsFeature.self)) + XCTAssertNotNil(logs.backtraceReporter) + } + func testConfigurationOverrides() throws { // Given let customEndpoint: URL = .mockRandom() diff --git a/DatadogObjc.podspec b/DatadogObjc.podspec index f256756b32..54e902f055 100644 --- a/DatadogObjc.podspec +++ b/DatadogObjc.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogObjc" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Objective-C SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogObjc/Sources/Datadog+objc.swift b/DatadogObjc/Sources/Datadog+objc.swift index da55a08285..2d626e75fb 100644 --- a/DatadogObjc/Sources/Datadog+objc.swift +++ b/DatadogObjc/Sources/Datadog+objc.swift @@ -67,12 +67,12 @@ public class DDDatadog: NSObject { @objc public static func setUserInfo(id: String? = nil, name: String? = nil, email: String? = nil, extraInfo: [String: Any] = [:]) { - Datadog.setUserInfo(id: id, name: name, email: email, extraInfo: castAttributesToSwift(extraInfo)) + Datadog.setUserInfo(id: id, name: name, email: email, extraInfo: extraInfo.dd.swiftAttributes) } @objc public static func addUserExtraInfo(_ extraInfo: [String: Any]) { - Datadog.addUserExtraInfo(castAttributesToSwift(extraInfo)) + Datadog.addUserExtraInfo(extraInfo.dd.swiftAttributes) } @objc diff --git a/DatadogObjc/Sources/Logs/Logs+objc.swift b/DatadogObjc/Sources/Logs/Logs+objc.swift index d498e4d296..a41972f72d 100644 --- a/DatadogObjc/Sources/Logs/Logs+objc.swift +++ b/DatadogObjc/Sources/Logs/Logs+objc.swift @@ -225,12 +225,12 @@ public class DDLogger: NSObject { @objc public func debug(_ message: String, attributes: [String: Any]) { - sdkLogger.debug(message, attributes: castAttributesToSwift(attributes)) + sdkLogger.debug(message, attributes: attributes.dd.swiftAttributes) } @objc public func debug(_ message: String, error: NSError, attributes: [String: Any]) { - sdkLogger.debug(message, error: error, attributes: castAttributesToSwift(attributes)) + sdkLogger.debug(message, error: error, attributes: attributes.dd.swiftAttributes) } @objc @@ -240,12 +240,12 @@ public class DDLogger: NSObject { @objc public func info(_ message: String, attributes: [String: Any]) { - sdkLogger.info(message, attributes: castAttributesToSwift(attributes)) + sdkLogger.info(message, attributes: attributes.dd.swiftAttributes) } @objc public func info(_ message: String, error: NSError, attributes: [String: Any]) { - sdkLogger.info(message, error: error, attributes: castAttributesToSwift(attributes)) + sdkLogger.info(message, error: error, attributes: attributes.dd.swiftAttributes) } @objc @@ -255,12 +255,12 @@ public class DDLogger: NSObject { @objc public func notice(_ message: String, attributes: [String: Any]) { - sdkLogger.notice(message, attributes: castAttributesToSwift(attributes)) + sdkLogger.notice(message, attributes: attributes.dd.swiftAttributes) } @objc public func notice(_ message: String, error: NSError, attributes: [String: Any]) { - sdkLogger.notice(message, error: error, attributes: castAttributesToSwift(attributes)) + sdkLogger.notice(message, error: error, attributes: attributes.dd.swiftAttributes) } @objc @@ -270,12 +270,12 @@ public class DDLogger: NSObject { @objc public func warn(_ message: String, attributes: [String: Any]) { - sdkLogger.warn(message, attributes: castAttributesToSwift(attributes)) + sdkLogger.warn(message, attributes: attributes.dd.swiftAttributes) } @objc public func warn(_ message: String, error: NSError, attributes: [String: Any]) { - sdkLogger.warn(message, error: error, attributes: castAttributesToSwift(attributes)) + sdkLogger.warn(message, error: error, attributes: attributes.dd.swiftAttributes) } @objc @@ -285,12 +285,12 @@ public class DDLogger: NSObject { @objc public func error(_ message: String, attributes: [String: Any]) { - sdkLogger.error(message, attributes: castAttributesToSwift(attributes)) + sdkLogger.error(message, attributes: attributes.dd.swiftAttributes) } @objc public func error(_ message: String, error: NSError, attributes: [String: Any]) { - sdkLogger.error(message, error: error, attributes: castAttributesToSwift(attributes)) + sdkLogger.error(message, error: error, attributes: attributes.dd.swiftAttributes) } @objc @@ -300,12 +300,12 @@ public class DDLogger: NSObject { @objc public func critical(_ message: String, attributes: [String: Any]) { - sdkLogger.critical(message, attributes: castAttributesToSwift(attributes)) + sdkLogger.critical(message, attributes: attributes.dd.swiftAttributes) } @objc public func critical(_ message: String, error: NSError, attributes: [String: Any]) { - sdkLogger.critical(message, error: error, attributes: castAttributesToSwift(attributes)) + sdkLogger.critical(message, error: error, attributes: attributes.dd.swiftAttributes) } @objc diff --git a/DatadogObjc/Sources/ObjcIntercompatibility/ObjcIntercompatibility.swift b/DatadogObjc/Sources/ObjcIntercompatibility/ObjcIntercompatibility.swift deleted file mode 100644 index 06dcb60392..0000000000 --- a/DatadogObjc/Sources/ObjcIntercompatibility/ObjcIntercompatibility.swift +++ /dev/null @@ -1,25 +0,0 @@ -/* -* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. -* This product includes software developed at Datadog (https://www.datadoghq.com/). -* Copyright 2019-Present Datadog, Inc. -*/ - -import Foundation -import DatadogInternal -import DatadogCore - -/// Casts `[String: Any]` attributes to their `Encodable` representation by wrapping each `Any` into `AnyEncodable`. -internal func castAttributesToSwift(_ attributes: [String: Any]) -> [String: Encodable] { - attributes.mapValues { $0 as? Encodable ?? AnyEncodable($0) } -} - -/// Casts `[String: Encodable]` attributes to their `Any` representation by unwrapping each `AnyEncodable` into `Any`. -internal func castAttributesToObjectiveC(_ attributes: [String: Encodable]) -> [String: Any] { - attributes.mapValues { ($0 as? AnyEncodable).map(\.value) ?? $0 } -} - -/// Helper extension to use `castAttributesToObjectiveC(_:)` in auto generated ObjC interop `RUMDataModels`. -/// Unlike the function it wraps, it has postfix notation which makes it easier to use in generated code. -internal extension Dictionary where Key == String, Value == Encodable { - func castToObjectiveC() -> [String: Any] { castAttributesToObjectiveC(self) } -} diff --git a/DatadogObjc/Sources/RUM/RUM+objc.swift b/DatadogObjc/Sources/RUM/RUM+objc.swift index fee8ba2561..26b651ee78 100644 --- a/DatadogObjc/Sources/RUM/RUM+objc.swift +++ b/DatadogObjc/Sources/RUM/RUM+objc.swift @@ -22,7 +22,7 @@ public class DDRUMView: NSObject { let swiftView: RUMView @objc public var name: String { swiftView.name } - @objc public var attributes: [String: Any] { castAttributesToObjectiveC(swiftView.attributes) } + @objc public var attributes: [String: Any] { swiftView.attributes.dd.objCAttributes } /// Initializes the RUM View description. /// - Parameters: @@ -32,7 +32,7 @@ public class DDRUMView: NSObject { public init(name: String, attributes: [String: Any]) { swiftView = RUMView( name: name, - attributes: castAttributesToSwift(attributes) + attributes: attributes.dd.swiftAttributes ) } } @@ -51,7 +51,7 @@ public class DDDefaultUIKitRUMViewsPredicate: NSObject, DDUIKitRUMViewsPredicate public func rumView(for viewController: UIViewController) -> DDRUMView? { return swiftPredicate.rumView(for: viewController).map { - DDRUMView(name: $0.name, attributes: castAttributesToObjectiveC($0.attributes)) + DDRUMView(name: $0.name, attributes: $0.attributes.dd.objCAttributes) } } } @@ -62,13 +62,13 @@ public class DDDefaultUIKitRUMActionsPredicate: NSObject, DDUIKitRUMActionsPredi #if os(tvOS) public func rumAction(press type: UIPress.PressType, targetView: UIView) -> DDRUMAction? { swiftPredicate.rumAction(press: type, targetView: targetView).map { - DDRUMAction(name: $0.name, attributes: castAttributesToObjectiveC($0.attributes)) + DDRUMAction(name: $0.name, attributes: $0.attributes.dd.objCAttributes) } } #else public func rumAction(targetView: UIView) -> DDRUMAction? { swiftPredicate.rumAction(targetView: targetView).map { - DDRUMAction(name: $0.name, attributes: castAttributesToObjectiveC($0.attributes)) + DDRUMAction(name: $0.name, attributes: $0.attributes.dd.objCAttributes) } } #endif @@ -105,7 +105,7 @@ public class DDRUMAction: NSObject { let swiftAction: RUMAction @objc public var name: String { swiftAction.name } - @objc public var attributes: [String: Any] { castAttributesToObjectiveC(swiftAction.attributes) } + @objc public var attributes: [String: Any] { swiftAction.attributes.dd.objCAttributes } /// Initializes the RUM Action description. /// - Parameters: @@ -115,7 +115,7 @@ public class DDRUMAction: NSObject { public init(name: String, attributes: [String: Any]) { swiftAction = RUMAction( name: name, - attributes: castAttributesToSwift(attributes) + attributes: attributes.dd.swiftAttributes ) } } @@ -319,7 +319,7 @@ public class DDRUMURLSessionTracking: NSObject { public func setResourceAttributesProvider(_ provider: @escaping (URLRequest, URLResponse?, Data?, Error?) -> [String: Any]?) { swiftConfig.resourceAttributesProvider = { request, response, data, error in let objcAttributes = provider(request, response, data, error) - return objcAttributes.map { castAttributesToSwift($0) } + return objcAttributes?.dd.swiftAttributes } } } @@ -484,7 +484,7 @@ public class DDRUMMonitor: NSObject { name: String?, attributes: [String: Any] ) { - swiftRUMMonitor.startView(viewController: viewController, name: name, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.startView(viewController: viewController, name: name, attributes: attributes.dd.swiftAttributes) } @objc @@ -492,7 +492,7 @@ public class DDRUMMonitor: NSObject { viewController: UIViewController, attributes: [String: Any] ) { - swiftRUMMonitor.stopView(viewController: viewController, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.stopView(viewController: viewController, attributes: attributes.dd.swiftAttributes) } @objc @@ -501,7 +501,7 @@ public class DDRUMMonitor: NSObject { name: String?, attributes: [String: Any] ) { - swiftRUMMonitor.startView(key: key, name: name, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.startView(key: key, name: name, attributes: attributes.dd.swiftAttributes) } @objc @@ -509,7 +509,7 @@ public class DDRUMMonitor: NSObject { key: String, attributes: [String: Any] ) { - swiftRUMMonitor.stopView(key: key, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.stopView(key: key, attributes: attributes.dd.swiftAttributes) } @objc @@ -524,7 +524,7 @@ public class DDRUMMonitor: NSObject { source: DDRUMErrorSource, attributes: [String: Any] ) { - swiftRUMMonitor.addError(message: message, stack: stack, source: source.swiftType, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.addError(message: message, stack: stack, source: source.swiftType, attributes: attributes.dd.swiftAttributes) } @objc @@ -533,7 +533,7 @@ public class DDRUMMonitor: NSObject { source: DDRUMErrorSource, attributes: [String: Any] ) { - swiftRUMMonitor.addError(error: error, source: source.swiftType, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.addError(error: error, source: source.swiftType, attributes: attributes.dd.swiftAttributes) } @objc @@ -542,7 +542,7 @@ public class DDRUMMonitor: NSObject { request: URLRequest, attributes: [String: Any] ) { - swiftRUMMonitor.startResource(resourceKey: resourceKey, request: request, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.startResource(resourceKey: resourceKey, request: request, attributes: attributes.dd.swiftAttributes) } @objc @@ -551,7 +551,7 @@ public class DDRUMMonitor: NSObject { url: URL, attributes: [String: Any] ) { - swiftRUMMonitor.startResource(resourceKey: resourceKey, url: url, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.startResource(resourceKey: resourceKey, url: url, attributes: attributes.dd.swiftAttributes) } @objc @@ -561,7 +561,7 @@ public class DDRUMMonitor: NSObject { urlString: String, attributes: [String: Any] ) { - swiftRUMMonitor.startResource(resourceKey: resourceKey, httpMethod: httpMethod.swiftType, urlString: urlString, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.startResource(resourceKey: resourceKey, httpMethod: httpMethod.swiftType, urlString: urlString, attributes: attributes.dd.swiftAttributes) } @objc @@ -570,7 +570,7 @@ public class DDRUMMonitor: NSObject { metrics: URLSessionTaskMetrics, attributes: [String: Any] ) { - swiftRUMMonitor.addResourceMetrics(resourceKey: resourceKey, metrics: metrics, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.addResourceMetrics(resourceKey: resourceKey, metrics: metrics, attributes: attributes.dd.swiftAttributes) } @objc @@ -580,7 +580,7 @@ public class DDRUMMonitor: NSObject { size: NSNumber?, attributes: [String: Any] ) { - swiftRUMMonitor.stopResource(resourceKey: resourceKey, response: response, size: size?.int64Value, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.stopResource(resourceKey: resourceKey, response: response, size: size?.int64Value, attributes: attributes.dd.swiftAttributes) } @objc @@ -596,7 +596,7 @@ public class DDRUMMonitor: NSObject { statusCode: statusCode?.intValue, kind: kind.swiftType, size: size?.int64Value, - attributes: castAttributesToSwift(attributes) + attributes: attributes.dd.swiftAttributes ) } @@ -607,7 +607,7 @@ public class DDRUMMonitor: NSObject { response: URLResponse?, attributes: [String: Any] ) { - swiftRUMMonitor.stopResourceWithError(resourceKey: resourceKey, error: error, response: response, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.stopResourceWithError(resourceKey: resourceKey, error: error, response: response, attributes: attributes.dd.swiftAttributes) } @objc @@ -617,7 +617,7 @@ public class DDRUMMonitor: NSObject { response: URLResponse?, attributes: [String: Any] ) { - swiftRUMMonitor.stopResourceWithError(resourceKey: resourceKey, message: message, response: response, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.stopResourceWithError(resourceKey: resourceKey, message: message, response: response, attributes: attributes.dd.swiftAttributes) } @objc @@ -626,7 +626,7 @@ public class DDRUMMonitor: NSObject { name: String, attributes: [String: Any] ) { - swiftRUMMonitor.startAction(type: type.swiftType, name: name, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.startAction(type: type.swiftType, name: name, attributes: attributes.dd.swiftAttributes) } @objc @@ -635,7 +635,7 @@ public class DDRUMMonitor: NSObject { name: String?, attributes: [String: Any] ) { - swiftRUMMonitor.stopAction(type: type.swiftType, name: name, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.stopAction(type: type.swiftType, name: name, attributes: attributes.dd.swiftAttributes) } @objc @@ -644,7 +644,7 @@ public class DDRUMMonitor: NSObject { name: String, attributes: [String: Any] ) { - swiftRUMMonitor.addAction(type: type.swiftType, name: name, attributes: castAttributesToSwift(attributes)) + swiftRUMMonitor.addAction(type: type.swiftType, name: name, attributes: attributes.dd.swiftAttributes) } @objc diff --git a/DatadogObjc/Sources/RUM/RUMDataModels+objc.swift b/DatadogObjc/Sources/RUM/RUMDataModels+objc.swift index 30453ce997..433a90c8b6 100644 --- a/DatadogObjc/Sources/RUM/RUMDataModels+objc.swift +++ b/DatadogObjc/Sources/RUM/RUMDataModels+objc.swift @@ -713,7 +713,7 @@ public class DDRUMActionEventRUMEventAttributes: NSObject { } @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + root.swiftModel.context!.contextInfo.dd.objCAttributes } } @@ -963,7 +963,7 @@ public class DDRUMActionEventRUMUser: NSObject { } @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + root.swiftModel.usr!.usrInfo.dd.objCAttributes } } @@ -1502,7 +1502,7 @@ public class DDRUMErrorEventRUMEventAttributes: NSObject { } @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + root.swiftModel.context!.contextInfo.dd.objCAttributes } } @@ -2178,7 +2178,7 @@ public class DDRUMErrorEventFeatureFlags: NSObject { } @objc public var featureFlagsInfo: [String: Any] { - root.swiftModel.featureFlags!.featureFlagsInfo.castToObjectiveC() + root.swiftModel.featureFlags!.featureFlagsInfo.dd.objCAttributes } } @@ -2347,7 +2347,7 @@ public class DDRUMErrorEventRUMUser: NSObject { } @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + root.swiftModel.usr!.usrInfo.dd.objCAttributes } } @@ -2882,7 +2882,7 @@ public class DDRUMLongTaskEventRUMEventAttributes: NSObject { } @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + root.swiftModel.context!.contextInfo.dd.objCAttributes } } @@ -3153,7 +3153,7 @@ public class DDRUMLongTaskEventRUMUser: NSObject { } @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + root.swiftModel.usr!.usrInfo.dd.objCAttributes } } @@ -3696,7 +3696,7 @@ public class DDRUMResourceEventRUMEventAttributes: NSObject { } @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + root.swiftModel.context!.contextInfo.dd.objCAttributes } } @@ -4378,7 +4378,7 @@ public class DDRUMResourceEventRUMUser: NSObject { } @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + root.swiftModel.usr!.usrInfo.dd.objCAttributes } } @@ -4953,7 +4953,7 @@ public class DDRUMViewEventRUMEventAttributes: NSObject { } @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + root.swiftModel.context!.contextInfo.dd.objCAttributes } } @@ -5089,7 +5089,7 @@ public class DDRUMViewEventFeatureFlags: NSObject { } @objc public var featureFlagsInfo: [String: Any] { - root.swiftModel.featureFlags!.featureFlagsInfo.castToObjectiveC() + root.swiftModel.featureFlags!.featureFlagsInfo.dd.objCAttributes } } @@ -5289,7 +5289,7 @@ public class DDRUMViewEventRUMUser: NSObject { } @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + root.swiftModel.usr!.usrInfo.dd.objCAttributes } } @@ -6178,7 +6178,7 @@ public class DDRUMVitalEventRUMEventAttributes: NSObject { } @objc public var contextInfo: [String: Any] { - root.swiftModel.context!.contextInfo.castToObjectiveC() + root.swiftModel.context!.contextInfo.dd.objCAttributes } } @@ -6428,7 +6428,7 @@ public class DDRUMVitalEventRUMUser: NSObject { } @objc public var usrInfo: [String: Any] { - root.swiftModel.usr!.usrInfo.castToObjectiveC() + root.swiftModel.usr!.usrInfo.dd.objCAttributes } } @@ -6688,7 +6688,7 @@ public class DDTelemetryErrorEventTelemetry: NSObject { } @objc public var telemetryInfo: [String: Any] { - root.swiftModel.telemetry.telemetryInfo.castToObjectiveC() + root.swiftModel.telemetry.telemetryInfo.dd.objCAttributes } } @@ -6938,7 +6938,7 @@ public class DDTelemetryDebugEventTelemetry: NSObject { } @objc public var telemetryInfo: [String: Any] { - root.swiftModel.telemetry.telemetryInfo.castToObjectiveC() + root.swiftModel.telemetry.telemetryInfo.dd.objCAttributes } } @@ -7167,7 +7167,7 @@ public class DDTelemetryConfigurationEventTelemetry: NSObject { } @objc public var telemetryInfo: [String: Any] { - root.swiftModel.telemetry.telemetryInfo.castToObjectiveC() + root.swiftModel.telemetry.telemetryInfo.dd.objCAttributes } } @@ -7539,7 +7539,7 @@ public class DDTelemetryConfigurationEventTelemetryConfigurationPlugins: NSObjec } @objc public var pluginsInfo: [String: Any] { - root.swiftModel.pluginsInfo.castToObjectiveC() + root.swiftModel.pluginsInfo.dd.objCAttributes } } diff --git a/DatadogObjc/Sources/Tracing/Trace+objc.swift b/DatadogObjc/Sources/Tracing/Trace+objc.swift index df3922f091..612c2ce4d3 100644 --- a/DatadogObjc/Sources/Tracing/Trace+objc.swift +++ b/DatadogObjc/Sources/Tracing/Trace+objc.swift @@ -28,8 +28,8 @@ public class DDTraceConfiguration: NSObject { } @objc public var tags: [String: Any]? { - set { swiftConfig.tags = newValue.map { castAttributesToSwift($0) } } - get { swiftConfig.tags.map { castAttributesToObjectiveC($0) } } + set { swiftConfig.tags = newValue?.dd.swiftAttributes } + get { swiftConfig.tags?.dd.objCAttributes } } @objc diff --git a/DatadogRUM.podspec b/DatadogRUM.podspec index 0e82d988eb..24556cb2cc 100644 --- a/DatadogRUM.podspec +++ b/DatadogRUM.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogRUM" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Datadog Real User Monitoring Module." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogRUM/Sources/Integrations/TelemetryReceiver.swift b/DatadogRUM/Sources/Integrations/TelemetryReceiver.swift index e012efce7a..18edad1f6b 100644 --- a/DatadogRUM/Sources/Integrations/TelemetryReceiver.swift +++ b/DatadogRUM/Sources/Integrations/TelemetryReceiver.swift @@ -220,7 +220,7 @@ internal final class TelemetryReceiver: FeatureMessageReceiver { // Override sessionID using standard `SDKMetricFields`, otherwise use current RUM session ID: var attributes = attributes - let sessionIDOverride = attributes.removeValue(forKey: SDKMetricFields.sessionIDOverrideKey) as? String + let sessionIDOverride: String? = attributes.removeValue(forKey: SDKMetricFields.sessionIDOverrideKey)?.dd.decode() let sessionID = sessionIDOverride ?? rum?.sessionID let event = TelemetryDebugEvent( diff --git a/DatadogRUM/Sources/RUMMonitor/Monitor.swift b/DatadogRUM/Sources/RUMMonitor/Monitor.swift index 20ae4d8350..0f3b7578cf 100644 --- a/DatadogRUM/Sources/RUMMonitor/Monitor.swift +++ b/DatadogRUM/Sources/RUMMonitor/Monitor.swift @@ -64,29 +64,15 @@ internal typealias RUMErrorSourceType = RUMErrorEvent.Error.SourceType internal extension RUMErrorSourceType { static func extract(from attributes: inout [AttributeKey: AttributeValue]) -> RUMErrorSourceType? { - return (attributes.removeValue(forKey: CrossPlatformAttributes.errorSourceType)) - .flatMap({ - $0.decoded() - }) + return attributes + .removeValue(forKey: CrossPlatformAttributes.errorSourceType)? + .dd.decode() .flatMap { - return RUMErrorEvent.Error.SourceType(rawValue: $0) + RUMErrorEvent.Error.SourceType(rawValue: $0) } } } -internal extension AttributeValue { - func decoded() -> T? { - switch self { - case let codable as AnyCodable: - return codable.value as? T - case let val as T: - return val - default: - return nil - } - } -} - internal enum RUMInternalErrorSource: String, Decodable { case custom case source @@ -194,7 +180,7 @@ internal class Monitor: RUMCommandSubscriber { var combinedUserAttributes = attributes combinedUserAttributes.merge(rumCommandAttributes: command.attributes) - if let customTimestampInMiliseconds = combinedUserAttributes.removeValue(forKey: CrossPlatformAttributes.timestampInMilliseconds) as? Int64 { + if let customTimestampInMiliseconds: Int64 = combinedUserAttributes.removeValue(forKey: CrossPlatformAttributes.timestampInMilliseconds)?.dd.decode() { let customTimeInterval = TimeInterval(fromMilliseconds: customTimestampInMiliseconds) mutableCommand.time = Date(timeIntervalSince1970: customTimeInterval) } diff --git a/DatadogRUM/Sources/RUMMonitor/RUMCommand.swift b/DatadogRUM/Sources/RUMMonitor/RUMCommand.swift index b99d863fec..0be97fcd21 100644 --- a/DatadogRUM/Sources/RUMMonitor/RUMCommand.swift +++ b/DatadogRUM/Sources/RUMMonitor/RUMCommand.swift @@ -203,7 +203,7 @@ internal struct RUMAddCurrentViewErrorCommand: RUMErrorCommand { attributes: [AttributeKey: AttributeValue] ) { var attributes = attributes - let isCrossPlatformCrash: Bool? = attributes.removeValue(forKey: CrossPlatformAttributes.errorIsCrash)?.decoded() + let isCrossPlatformCrash: Bool? = attributes.removeValue(forKey: CrossPlatformAttributes.errorIsCrash)?.dd.decode() let crossPlatformSourceType = RUMErrorSourceType.extract(from: &attributes) self.time = time diff --git a/DatadogRUM/Sources/RUMMonitor/Scopes/RUMResourceScope.swift b/DatadogRUM/Sources/RUMMonitor/Scopes/RUMResourceScope.swift index 1f410380e8..6df9469254 100644 --- a/DatadogRUM/Sources/RUMMonitor/Scopes/RUMResourceScope.swift +++ b/DatadogRUM/Sources/RUMMonitor/Scopes/RUMResourceScope.swift @@ -119,36 +119,32 @@ internal class RUMResourceScope: RUMScope { let size: Int64? // Check trace attributes - var traceId: TraceID? = nil - if let tid = attributes.removeValue(forKey: CrossPlatformAttributes.traceID) as? String { - traceId = .init(tid, representation: .hexadecimal) - } else { - traceId = spanContext?.traceID - } + let traceId: TraceID? = attributes.removeValue(forKey: CrossPlatformAttributes.traceID)? + .dd.decode() + .map { .init($0, representation: .hexadecimal) } + ?? spanContext?.traceID - var spanId: SpanID? = nil - if let sid = attributes.removeValue(forKey: CrossPlatformAttributes.spanID) as? String { - spanId = .init(sid, representation: .decimal) - } else { - spanId = spanContext?.spanID - } + let spanId: SpanID? = attributes.removeValue(forKey: CrossPlatformAttributes.spanID)? + .dd.decode() + .map { .init($0, representation: .decimal) } + ?? spanContext?.spanID - let traceSamplingRate = (attributes.removeValue(forKey: CrossPlatformAttributes.rulePSR) as? Double) ?? spanContext?.samplingRate + let traceSamplingRate = attributes.removeValue(forKey: CrossPlatformAttributes.rulePSR)?.dd.decode() ?? spanContext?.samplingRate // Check GraphQL attributes var graphql: RUMResourceEvent.Resource.Graphql? = nil - let graphqlOperationName = (attributes.removeValue(forKey: CrossPlatformAttributes.graphqlOperationName) as? String) - let graphqlPayload = (attributes.removeValue(forKey: CrossPlatformAttributes.graphqlPayload) as? String) - let graphqlVariables = (attributes.removeValue(forKey: CrossPlatformAttributes.graphqlVariables) as? String) - if let rawGraphqlOperationType = (attributes.removeValue(forKey: CrossPlatformAttributes.graphqlOperationType) as? String) { - if let graphqlOperationType = RUMResourceEvent.Resource.Graphql.OperationType(rawValue: rawGraphqlOperationType) { - graphql = .init( - operationName: graphqlOperationName, - operationType: graphqlOperationType, - payload: graphqlPayload, - variables: graphqlVariables - ) - } + let graphqlOperationName: String? = attributes.removeValue(forKey: CrossPlatformAttributes.graphqlOperationName)?.dd.decode() + let graphqlPayload: String? = attributes.removeValue(forKey: CrossPlatformAttributes.graphqlPayload)?.dd.decode() + let graphqlVariables: String? = attributes.removeValue(forKey: CrossPlatformAttributes.graphqlVariables)?.dd.decode() + if + let rawGraphqlOperationType: String = attributes.removeValue(forKey: CrossPlatformAttributes.graphqlOperationType)?.dd.decode(), + let graphqlOperationType = RUMResourceEvent.Resource.Graphql.OperationType(rawValue: rawGraphqlOperationType) { + graphql = .init( + operationName: graphqlOperationName, + operationType: graphqlOperationType, + payload: graphqlPayload, + variables: graphqlVariables + ) } /// Metrics values take precedence over other values. @@ -271,10 +267,9 @@ internal class RUMResourceScope: RUMScope { private func sendErrorEvent(on command: RUMStopResourceWithErrorCommand, context: DatadogContext, writer: Writer) { attributes.merge(rumCommandAttributes: command.attributes) - let errorFingerprint = attributes.removeValue(forKey: RUM.Attributes.errorFingerprint) as? String - var timeSinceAppStart: Int64? = nil - if let startTime = context.launchTime?.launchDate { - timeSinceAppStart = command.time.timeIntervalSince(startTime).toInt64Milliseconds + let errorFingerprint: String? = attributes.removeValue(forKey: RUM.Attributes.errorFingerprint)?.dd.decode() + let timeSinceAppStart = context.launchTime.map { + command.time.timeIntervalSince($0.launchDate).toInt64Milliseconds } let errorEvent = RUMErrorEvent( diff --git a/DatadogRUM/Sources/RUMMonitor/Scopes/RUMViewScope.swift b/DatadogRUM/Sources/RUMMonitor/Scopes/RUMViewScope.swift index 5eb1de30d3..a1b56ec528 100644 --- a/DatadogRUM/Sources/RUMMonitor/Scopes/RUMViewScope.swift +++ b/DatadogRUM/Sources/RUMMonitor/Scopes/RUMViewScope.swift @@ -575,14 +575,14 @@ internal class RUMViewScope: RUMScope, RUMContextProvider { errorsCount += 1 var commandAttributes = command.attributes - let errorFingerprint = commandAttributes.removeValue(forKey: RUM.Attributes.errorFingerprint) as? String + let errorFingerprint: String? = commandAttributes.removeValue(forKey: RUM.Attributes.errorFingerprint)?.dd.decode() var timeSinceAppStart: Int64? = nil if let startTime = context.launchTime?.launchDate { timeSinceAppStart = command.time.timeIntervalSince(startTime).toInt64Milliseconds } var binaryImages = command.binaryImages?.compactMap { $0.toRUMDataFormat } - if commandAttributes.removeValue(forKey: CrossPlatformAttributes.includeBinaryImages) != nil { + if commandAttributes.removeValue(forKey: CrossPlatformAttributes.includeBinaryImages)?.dd.decode() == true { // Don't try to get binary images if we already have them. if binaryImages == nil { // TODO: RUM-4072 Replace full backtrace reporter with simpler binary image fetcher diff --git a/DatadogSDK.podspec b/DatadogSDK.podspec index 9878a9069f..feb61a59df 100644 --- a/DatadogSDK.podspec +++ b/DatadogSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogSDK" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Swift SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogSDKAlamofireExtension.podspec b/DatadogSDKAlamofireExtension.podspec index 31e1af20d5..c435eea385 100644 --- a/DatadogSDKAlamofireExtension.podspec +++ b/DatadogSDKAlamofireExtension.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDKAlamofireExtension" s.module_name = "DatadogAlamofireExtension" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "An Official Extensions of Datadog Swift SDK for Alamofire." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogSDKCrashReporting.podspec b/DatadogSDKCrashReporting.podspec index d60c448d0c..a6f95fcc5f 100644 --- a/DatadogSDKCrashReporting.podspec +++ b/DatadogSDKCrashReporting.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDKCrashReporting" s.module_name = "DatadogCrashReporting" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Crash Reporting SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogSDKObjc.podspec b/DatadogSDKObjc.podspec index fa8eef30f9..669c8dd2c3 100644 --- a/DatadogSDKObjc.podspec +++ b/DatadogSDKObjc.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "DatadogSDKObjc" s.module_name = "DatadogObjc" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Objective-C SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogSessionReplay.podspec b/DatadogSessionReplay.podspec index f9c1b4d131..c641b470f8 100644 --- a/DatadogSessionReplay.podspec +++ b/DatadogSessionReplay.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogSessionReplay" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Official Datadog Session Replay SDK for iOS." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogTrace.podspec b/DatadogTrace.podspec index f06de562c7..3701cfa92d 100644 --- a/DatadogTrace.podspec +++ b/DatadogTrace.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogTrace" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Datadog Trace Module." s.homepage = "https://www.datadoghq.com" diff --git a/DatadogTrace/Sources/Integrations/TracingWithLoggingIntegration.swift b/DatadogTrace/Sources/Integrations/TracingWithLoggingIntegration.swift index 3e0348a671..82a6b8cdae 100644 --- a/DatadogTrace/Sources/Integrations/TracingWithLoggingIntegration.swift +++ b/DatadogTrace/Sources/Integrations/TracingWithLoggingIntegration.swift @@ -75,9 +75,9 @@ internal struct TracingWithLoggingIntegration { var userAttributes = fields // get the log message and optional error kind - let errorKind = userAttributes.removeValue(forKey: OTLogFields.errorKind) as? String - let message = (userAttributes.removeValue(forKey: OTLogFields.message) as? String) ?? message ?? Constants.defaultLogMessage - let errorStack = userAttributes.removeValue(forKey: OTLogFields.stack) as? String + let errorKind: String? = userAttributes.removeValue(forKey: OTLogFields.errorKind)?.dd.decode() + let message = userAttributes.removeValue(forKey: OTLogFields.message)?.dd.decode() ?? message ?? Constants.defaultLogMessage + let errorStack: String? = userAttributes.removeValue(forKey: OTLogFields.stack)?.dd.decode() // infer the log level let isErrorEvent = fields[OTLogFields.event] as? String == "error" diff --git a/DatadogTrace/Sources/Span/SpanTagsReducer.swift b/DatadogTrace/Sources/Span/SpanTagsReducer.swift index 69363df2cf..172dcaebce 100644 --- a/DatadogTrace/Sources/Span/SpanTagsReducer.swift +++ b/DatadogTrace/Sources/Span/SpanTagsReducer.swift @@ -5,6 +5,7 @@ */ import Foundation +import DatadogInternal /// Reduces `DDSpan` tags and log attributes by extracting values that require separate handling. /// @@ -61,15 +62,15 @@ internal struct SpanTagsReducer { } // extract resource name from `mutableSpanTags` - if let resourceName = mutableSpanTags.removeValue(forKey: SpanTags.resource) as? String { + if let resourceName: String = mutableSpanTags.removeValue(forKey: SpanTags.resource)?.dd.decode() { extractedResourceName = resourceName } - if let operationName = mutableSpanTags.removeValue(forKey: SpanTags.operation) as? String { + if let operationName: String = mutableSpanTags.removeValue(forKey: SpanTags.operation)?.dd.decode() { extractedOperationName = operationName } - if let serviceName = mutableSpanTags.removeValue(forKey: SpanTags.service) as? String { + if let serviceName: String = mutableSpanTags.removeValue(forKey: SpanTags.service)?.dd.decode() { extractedServiceName = serviceName } diff --git a/DatadogWebViewTracking.podspec b/DatadogWebViewTracking.podspec index b161a44ca9..f14208a069 100644 --- a/DatadogWebViewTracking.podspec +++ b/DatadogWebViewTracking.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "DatadogWebViewTracking" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Datadog WebView Tracking Module." s.homepage = "https://www.datadoghq.com" diff --git a/TestUtilities.podspec b/TestUtilities.podspec index 1325437c8d..c909015274 100644 --- a/TestUtilities.podspec +++ b/TestUtilities.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "TestUtilities" - s.version = "2.14.0" + s.version = "2.14.1" s.summary = "Datadog Testing Utilities. This module is for internal testing and should not be published." s.homepage = "https://www.datadoghq.com" diff --git a/tools/rum-models-generator/Sources/CodeGeneration/Print/ObjcInteropPrinter.swift b/tools/rum-models-generator/Sources/CodeGeneration/Print/ObjcInteropPrinter.swift index e6640f1b3a..e48b6feaf1 100644 --- a/tools/rum-models-generator/Sources/CodeGeneration/Print/ObjcInteropPrinter.swift +++ b/tools/rum-models-generator/Sources/CodeGeneration/Print/ObjcInteropPrinter.swift @@ -495,9 +495,9 @@ public class ObjcInteropPrinter: BasePrinter, CodePrinter { // Normally, `[Key: Any]` <> `[Key: Any]` interoperability wouldn't require casting. // However our SDK bridges `[String: Any]` attributes passed in Objective-C API to their `[String: Encodable]` representation // in underlying Swift SDK. This is done with `AnyEncodable` type erasure. To return these attributes back - // to the user, `AnyEncodable` must be unpacked to its original `Any` value. This is done in `.castToObjectiveC()` extension + // to the user, `AnyEncodable` must be unpacked to its original `Any` value. This is done in `.dd.objCAttributes` extension // defined in `DatadogObjc` module. Here we just emit its invocation: - return optionality + ".castToObjectiveC()" + return optionality + ".dd.objCAttributes" default: throw Exception.unimplemented("Cannot print `swiftToObjcCast()` for \(type(of: objcType)).") } diff --git a/tools/rum-models-generator/Tests/CodeGenerationTests/Print/ObjcInteropPrinterTests.swift b/tools/rum-models-generator/Tests/CodeGenerationTests/Print/ObjcInteropPrinterTests.swift index 0c38f0a5db..a0c9a553b3 100644 --- a/tools/rum-models-generator/Tests/CodeGenerationTests/Print/ObjcInteropPrinterTests.swift +++ b/tools/rum-models-generator/Tests/CodeGenerationTests/Print/ObjcInteropPrinterTests.swift @@ -1280,11 +1280,11 @@ final class ObjcInteropPrinterTests: XCTestCase { } @objc public var immutableCodables: [String: Any] { - root.swiftModel.immutableCodables.castToObjectiveC() + root.swiftModel.immutableCodables.dd.objCAttributes } @objc public var optionalImmutableCodables: [String: Any]? { - root.swiftModel.optionalImmutableCodables?.castToObjectiveC() + root.swiftModel.optionalImmutableCodables?.dd.objCAttributes } }