diff --git a/ExampleApp/ExampleApp/ExampleAppApp.swift b/ExampleApp/ExampleApp/ExampleAppApp.swift index 9071dde..43a95d0 100644 --- a/ExampleApp/ExampleApp/ExampleAppApp.swift +++ b/ExampleApp/ExampleApp/ExampleAppApp.swift @@ -17,7 +17,7 @@ struct ExampleAppApp: App { case .manualInstrumentation: InstrumentationView() case .automaticInstrumentation: - NetworkRequestView() + AutomaticInstrumentationView() case .evaluation: FeatureFlagView() } diff --git a/ExampleApp/ExampleApp/Instrumentation/Automatic/AutomaticInstrumentationView.swift b/ExampleApp/ExampleApp/Instrumentation/Automatic/AutomaticInstrumentationView.swift new file mode 100644 index 0000000..3363d6c --- /dev/null +++ b/ExampleApp/ExampleApp/Instrumentation/Automatic/AutomaticInstrumentationView.swift @@ -0,0 +1,14 @@ +import SwiftUI + +struct AutomaticInstrumentationView: View { + var body: some View { + VStack { + NetworkRequestView() + HelloWorldView() + } + } +} + +#Preview { + AutomaticInstrumentationView() +} diff --git a/ExampleApp/ExampleApp/Instrumentation/Automatic/HelloWorldView.swift b/ExampleApp/ExampleApp/Instrumentation/Automatic/HelloWorldView.swift new file mode 100644 index 0000000..5163198 --- /dev/null +++ b/ExampleApp/ExampleApp/Instrumentation/Automatic/HelloWorldView.swift @@ -0,0 +1,55 @@ +import SwiftUI +import ObservabilitySwiftUIExtensions + +struct AChildView: View { + @State private var count = 0 + var body: some View { + VStack { + Text("Child A View") + .padding() + Text(count.description) + .bold() + Button { + count = count + 1 + } label: { + Text("Increment") + .bold() + } + .tint(.yellow) + .buttonStyle(.borderedProminent) + } + .padding() + .background { + Color.red + } + } +} + +struct HelloWorldView: View { + @State private var count = 0 + var body: some View { + VStack { + Text(count.description) + .bold() + Button { + count = count + 1 + } label: { + Text("Increment") + } + AChildView() + } + .logViewName( + "HelloWorldView", + attributes: [ + "view": .string("vstack") + ] + ) + .onAppear { + print("PRINT FROM ONAPPEAR") + } + } +} + +#Preview { + HelloWorldView() +} diff --git a/Package.swift b/Package.swift index 8025dca..7438103 100644 --- a/Package.swift +++ b/Package.swift @@ -7,7 +7,11 @@ let package = Package( products: [ .library( name: "LaunchDarklyObservability", - targets: ["LaunchDarklyObservability"]), + targets: [ + "LaunchDarklyObservability", + "ObservabilitySwiftUIExtensions" + ] + ), ], dependencies: [ .package(url: "https://github.com/open-telemetry/opentelemetry-swift", exact: "2.0.0"), @@ -111,6 +115,15 @@ let package = Package( .product(name: "OpenTelemetrySdk", package: "opentelemetry-swift"), .product(name: "OpenTelemetryApi", package: "opentelemetry-swift"), ] + ), + .target( + name: "ObservabilitySwiftUIExtensions", + dependencies: [ + "LaunchDarklyObservability", + .product(name: "LaunchDarkly", package: "ios-client-sdk"), + .product(name: "OpenTelemetrySdk", package: "opentelemetry-swift"), + .product(name: "OpenTelemetryApi", package: "opentelemetry-swift"), + ] ) ] ) diff --git a/Sources/ObservabilitySwiftUIExtensions/ViewNameViewModifier.swift b/Sources/ObservabilitySwiftUIExtensions/ViewNameViewModifier.swift new file mode 100644 index 0000000..5f66b86 --- /dev/null +++ b/Sources/ObservabilitySwiftUIExtensions/ViewNameViewModifier.swift @@ -0,0 +1,50 @@ +import Foundation +import os +import SwiftUI + +import OpenTelemetryApi + +import LaunchDarklyObservability + +public struct ViewNameViewModifier: ViewModifier { + public let viewName: String + public let attributes: [String: AttributeValue]? + + public init(viewName: String, attributes: [String: AttributeValue]? = nil) { + self.viewName = viewName + self.attributes = attributes + } + + public func body(content: Content) -> some View { + content + .onDisappear { + let logAttributes = self.attributes ?? [String: AttributeValue]() + LDObserve.shared.recordLog( + message: "on Disappear \(self.viewName)", + severity: .info, + attributes: [ + "screen.name": .string(self.viewName), + ].merging(logAttributes) { _, inbound in inbound } + ) + } + .onAppear { + let logAttributes = self.attributes ?? [String: AttributeValue]() + LDObserve.shared.recordLog( + message: "on Appear \(self.viewName)", + severity: .info, + attributes: [ + "screen.name": .string(self.viewName), + ].merging(logAttributes) { _, inbound in inbound } + ) + } + } +} + + +extension View { + public func logViewName(_ viewName: String, attributes: [String: AttributeValue]? = nil) -> some View { + modifier(ViewNameViewModifier(viewName: viewName, attributes: attributes)) + } +} + +