Skip to content

Commit cb0fa51

Browse files
feat: add cocoapods support (#87)
- Observability Pod - Session Replay Pod <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Adds CocoaPods support with new podspecs and widespread conditional imports/guards, plus minor build/link fixes and release config updates. > > - **Packaging/Release** > - Add `LaunchDarklyObservability.podspec` and `LaunchDarklySessionReplay.podspec` with subspecs and dependencies. > - Update `release-please-config.json` to include the new podspecs. > - **Build/Integration** > - Gate many imports behind `#if !LD_COCOAPODS` and `canImport(...)` to support CocoaPods builds (e.g., `Common`, `URLSessionInstrumentation`, `KSCrash*`, `NetworkStatus`). > - Adjust URLSession network status injection to exclude CocoaPods builds. > - Change C entry point exposure from `@_silgen_name` to `@_cdecl` for `SwiftStartupMetricsInitialize`. > - Minor refactors for OTLP client/constants scoping. > - **Modules** > - Apply the above guards across Observability, Metrics, Traces, Logs, Transport, Sampling, Session, and Session Replay sources to ensure compatibility under CocoaPods. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 419892f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 85270f5 commit cb0fa51

38 files changed

+254
-96
lines changed

LaunchDarklyObservability.podspec

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
Pod::Spec.new do |s|
2+
s.name = "LaunchDarklyObservability"
3+
s.version = "0.11.1" # x-release-please-version
4+
s.summary = "iOS Observability Plugin for LaunchDarkly."
5+
s.description = <<-DESC
6+
LaunchDarkly is the feature management platform that software teams use to build better software, faster.
7+
DESC
8+
s.homepage = "https://github.com/launchdarkly/swift-launchdarkly-observability"
9+
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE.txt" }
10+
s.author = { "LaunchDarkly" => "sdks@launchdarkly.com" }
11+
s.platforms = { :ios => "13.0" }
12+
s.source = { :git => "https://github.com/launchdarkly/swift-launchdarkly-observability.git",
13+
:tag => s.version.to_s }
14+
s.swift_version = "5.9"
15+
16+
s.default_subspec = 'LaunchDarklyObservability'
17+
18+
s.pod_target_xcconfig = {
19+
'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => 'LD_COCOAPODS',
20+
'OTHER_SWIFT_FLAGS' => '$(inherited) -package-name LaunchDarklyObservability'
21+
}
22+
23+
# Main LaunchDarklyObservability subspec
24+
s.subspec "LaunchDarklyObservability" do |ss|
25+
ss.source_files = [
26+
"Sources/#{ss.module_name}/**/*.{swift,h,m}",
27+
"Sources/ObjCBridge/**/*.{h,m}"
28+
]
29+
ss.public_header_files = "Sources/ObjCBridge/*.h"
30+
ss.dependency "LaunchDarklyObservability/Core"
31+
end
32+
33+
# Observability Core
34+
35+
s.subspec "Core" do |ss|
36+
#ss.source_files = "Sources/#{ss.module_name}/**/*.{swift,h,m}"
37+
ss.dependency "LaunchDarklyObservability/OpenTelemetry"
38+
ss.dependency "LaunchDarklyObservability/Misc"
39+
ss.dependency "LaunchDarklyObservability/Internal"
40+
end
41+
42+
# Internal
43+
44+
s.subspec "Internal" do |ss|
45+
ss.dependency "LaunchDarklyObservability/Common"
46+
#ss.dependency "LaunchDarklyObservability/ObjCBridge"
47+
ss.dependency "LaunchDarklyObservability/OpenTelemetryProtocolExporterCommon"
48+
ss.dependency "LaunchDarklyObservability/NetworkStatus"
49+
ss.dependency "LaunchDarklyObservability/URLSessionInstrumentation"
50+
end
51+
52+
s.subspec "Common" do |ss|
53+
ss.source_files = "Sources/Common/**/*.{swift,h,m}"
54+
ss.dependency 'DataCompression'
55+
end
56+
57+
# OpenTelemetryProtocolExporterCommon subspec
58+
s.subspec "OpenTelemetryProtocolExporterCommon" do |ss|
59+
ss.source_files = "Sources/OpenTelemetry/OpenTelemetryProtocolExporterCommon/**/*.{swift,h,m}"
60+
ss.dependency 'OpenTelemetry-Swift-Sdk', '~> 2.3.0'
61+
#ss.dependency 'SwiftLog'
62+
ss.dependency 'SwiftProtobuf'
63+
end
64+
65+
# NetworkStatus subspec
66+
s.subspec "NetworkStatus" do |ss|
67+
ss.source_files = "Sources/OpenTelemetry/Instrumentation/NetworkStatus/**/*.{swift,h,m}"
68+
ss.dependency 'OpenTelemetry-Swift-Api', '~> 2.3.0'
69+
ss.frameworks = 'CoreTelephony'
70+
end
71+
72+
# URLSessionInstrumentation subspec
73+
s.subspec "URLSessionInstrumentation" do |ss|
74+
ss.source_files = "Sources/OpenTelemetry/Instrumentation/URLSession/**/*.{swift,h,m}"
75+
ss.dependency 'OpenTelemetry-Swift-Sdk', '~> 2.3.0'
76+
ss.dependency "LaunchDarklyObservability/NetworkStatus"
77+
end
78+
79+
# External
80+
81+
s.subspec 'OpenTelemetry' do |ss|
82+
ss.dependency 'OpenTelemetry-Swift-Api', '~> 2.3.0'
83+
ss.dependency 'OpenTelemetry-Swift-Sdk', '~> 2.3.0'
84+
end
85+
86+
s.subspec 'Misc' do |ss|
87+
ss.dependency 'DataCompression', '~> 3.8.0'
88+
ss.dependency 'KSCrash'
89+
ss.dependency 'LaunchDarkly', '~> 9.15'
90+
end
91+
92+
end

LaunchDarklySessionReplay.podspec

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Pod::Spec.new do |s|
2+
s.name = "LaunchDarklySessionReplay"
3+
s.version = "0.11.1" # x-release-please-version
4+
s.summary = "Session replay library for LaunchDarkly"
5+
s.description = <<-DESC
6+
Session Replay captures user interactions and screen recordings to help you understand how users interact with your application.
7+
DESC
8+
s.homepage = "https://github.com/launchdarkly/swift-launchdarkly-observability"
9+
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE.txt" }
10+
s.author = { "LaunchDarkly" => "sdks@launchdarkly.com" }
11+
s.platforms = { :ios => "13.0" }
12+
s.source = { :git => "https://github.com/launchdarkly/swift-launchdarkly-observability.git",
13+
:tag => s.version.to_s }
14+
s.swift_version = "5.9"
15+
16+
s.default_subspec = 'LaunchDarklySessionReplay'
17+
18+
s.pod_target_xcconfig = {
19+
'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => 'LD_COCOAPODS',
20+
'OTHER_SWIFT_FLAGS' => '$(inherited) -package-name LaunchDarklyObservability'
21+
}
22+
23+
s.dependency "LaunchDarklyObservability/LaunchDarklyObservability", s.version.to_s
24+
25+
26+
s.subspec "Common" do |ss|
27+
ss.source_files = "Sources/Common/**/*.{swift,h,m}"
28+
end
29+
30+
s.subspec "LaunchDarklySessionReplay" do |ss|
31+
ss.source_files = "Sources/LaunchDarklySessionReplay/**/*.{swift,h,m}"
32+
ss.dependency "LaunchDarklySessionReplay/Common"
33+
ss.dependency "LaunchDarklyObservability/LaunchDarklyObservability"
34+
end
35+
end

Sources/LaunchDarklyObservability/AutoInstrumentation/Launch/AppStartTime.swift

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
//
2-
// AppStartTime.swift
3-
// swift-launchdarkly-observability
4-
//
5-
// Created by Mario Canto on 03/11/25.
6-
//
7-
8-
91
import Foundation
102

113
@objcMembers
@@ -25,7 +17,8 @@ public final class AppStartTime: NSObject {
2517
}
2618

2719
// Expose a function Swift can call from C
28-
@_silgen_name("SwiftStartupMetricsInitialize")
20+
//@_silgen_name("SwiftStartupMetricsInitialize")
21+
@_cdecl("SwiftStartupMetricsInitialize")
2922
public func SwiftStartupMetricsInitialize() {
3023
_ = AppStartTime.stats
3124
}

Sources/LaunchDarklyObservability/AutoInstrumentation/Launch/LaunchMeter.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#if canImport(UIKit)
22
import Foundation
33
import UIKit
4-
import Common
4+
#if !LD_COCOAPODS
5+
import Common
6+
#endif
57

68
enum LaunchType {
79
case cold, warm

Sources/LaunchDarklyObservability/AutoInstrumentation/Launch/LaunchTracker.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import Foundation
22
import Combine
3+
import UIKit
4+
#if !LD_COCOAPODS
5+
import Common
6+
#endif
37

48
final class LaunchTracker {
59
struct SceneData: Equatable {
@@ -108,10 +112,6 @@ extension LaunchTracker {
108112
}
109113
}
110114

111-
import UIKit
112-
import Combine
113-
import Common
114-
115115
extension LaunchTracker {
116116
func subscribeToSceneNotifications(usingStore store: Store<State, Action>) {
117117
NotificationCenter.default.publisher(for: UIScene.didActivateNotification)

Sources/LaunchDarklyObservability/AutoInstrumentation/Networking/NetworkInstrumentationManager.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import Foundation
2-
import URLSessionInstrumentation
2+
#if !LD_COCOAPODS
3+
import URLSessionInstrumentation
4+
#endif
5+
36

47
final class NetworkInstrumentationManager: AutoInstrumentation {
58
private let uRLSessionInstrumentation: URLSessionInstrumentation

Sources/LaunchDarklyObservability/Client/ObservabilityClientFactory.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import Foundation
2-
import Common
32
import OSLog
43
import OpenTelemetrySdk
4+
#if !LD_COCOAPODS
5+
import Common
6+
#endif
57

68
public struct ObservabilityClientFactory {
79
public static func noOp() -> Observe {

Sources/LaunchDarklyObservability/Client/ObservabilityContext.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import OpenTelemetryApi
22
import OpenTelemetrySdk
3-
import Common
3+
#if !LD_COCOAPODS
4+
import Common
5+
#endif
46

57
/** Shared info between plugins */
68
public class ObservabilityContext {

Sources/LaunchDarklyObservability/Constants/Constants.swift renamed to Sources/LaunchDarklyObservability/Constants/CommonOTelConfiguration.swift

File renamed without changes.

Sources/LaunchDarklyObservability/CrashReports/CrashReportsManager.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import Foundation
22
import OSLog
3-
import KSCrashInstallations
4-
import KSCrashRecording
5-
import KSCrashDemangleFilter
6-
import KSCrashFilters
3+
#if canImport(KSCrashRecording)
4+
import KSCrashInstallations
5+
import KSCrashRecording
6+
import KSCrashDemangleFilter
7+
import KSCrashFilters
8+
#elseif canImport(KSCrash)
9+
import KSCrash
10+
#endif
711

812
public protocol CrashReporting {
913
func logPendingCrashReports()

0 commit comments

Comments
 (0)