Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .changeset/v4-internalize-wrapper-apis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'posthog-ios': major
---

**Breaking:** hide SDK internals that were public only for PostHog's own wrapper SDKs.

Moved behind `@_spi(PostHogInternal)`. These are for PostHog's wrapper SDKs and carry no stability guarantees:

- `postHogSdkName` and `postHogVersion`
- `PostHogSessionManager`: use `PostHogSDK.getSessionId()`, `startSession()` and `endSession()`.
- `PostHogStorageManager` and `PostHogConfig.storageManager`: use the `PostHogSDK` identity methods such as `identify`, `getDistinctId()` and `reset()`.
- `PostHogConfig.snapshotEndpoint`
- `dateToMillis(_:)`: use `Int64(date.timeIntervalSince1970 * 1000)`.
- `imageToBase64(_:_:)`: no public replacement. It returned a WebP `data:` URI, or JPEG when WebP encoding failed.

No longer public:

- `toISO8601String(_:)`, `toISO8601Date(_:)`, `sanitizeDictionary(_:)`, `deleteSafely(_:)` and `postHogiOSSdkName`
- `Gzip`, `GzipError` and `CompressionLevel`
- `ReachabilityError`
- `UIColor.init(hex:)` and `UIColor.hexDescription(_:)`

`PostHogSessionManager.shared`, `PostHogSessionManager.setSessionId(_:)` and `PostHogConfig.snapshotEndpoint` are no longer exposed to Objective-C.
4 changes: 2 additions & 2 deletions PostHog/PostHogConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ public typealias BeforeSendBlock = (PostHogEvent) -> PostHogEvent?
///
/// - Warning: This value is managed by the SDK from remote configuration and should not
/// be changed by application code.
@objc public var snapshotEndpoint: String = "/s/"
@_spi(PostHogInternal) public var snapshotEndpoint: String = "/s/"

/// Default PostHog ingestion host for US Cloud projects.
///
Expand Down Expand Up @@ -479,7 +479,7 @@ public typealias BeforeSendBlock = (PostHogEvent) -> PostHogEvent?
///
/// - Warning: This is an SDK extension point used internally to share identity storage
/// with SDK integrations and tests. Application code should not normally replace it.
public var storageManager: PostHogStorageManager?
@_spi(PostHogInternal) public var storageManager: PostHogStorageManager?

private static func normalizeProjectToken(_ projectToken: String) -> String {
projectToken.trimmingCharacters(in: .whitespacesAndNewlines)
Expand Down
12 changes: 5 additions & 7 deletions PostHog/PostHogSessionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import Foundation

/// Manages the active PostHog session ID and session rotation state.
///
/// - Warning: This class is public for backwards compatibility, but is intended for
/// SDK-internal use only. Application code should use `PostHogSDK.getSessionId()`,
/// - Warning: For PostHog's wrapper SDKs only, which import it with
/// `@_spi(PostHogInternal)`. Application code should use `PostHogSDK.getSessionId()`,
/// `startSession()`, and `endSession()` instead of interacting with this manager directly.
@objc public class PostHogSessionManager: NSObject {
@_spi(PostHogInternal) @objc public class PostHogSessionManager: NSObject {
enum SessionIDChangeReason: String {
case sessionIdEmpty = "Session id was empty"
case sessionStart = "Session started"
Expand All @@ -24,8 +24,7 @@ import Foundation
}

/// Session manager used by `PostHogSDK.shared`.
@available(*, deprecated, message: "PostHogSessionManager becomes SDK-internal in PostHog 4.0. Use PostHogSDK.shared.getSessionId(), startSession() and endSession() instead. From 4.0, wrapper SDKs must import PostHog with @_spi(PostHogInternal) to use it.")
@objc public static var shared: PostHogSessionManager {
public static var shared: PostHogSessionManager {
PostHogSDK.shared.sessionManager
}

Expand Down Expand Up @@ -75,8 +74,7 @@ import Foundation
/// Use with care: changing the session ID affects analytics session attribution and session replay.
///
/// - Parameter sessionId: Session ID to use for subsequent events.
@available(*, deprecated, message: "PostHogSessionManager becomes SDK-internal in PostHog 4.0. Use PostHogSDK.shared.getSessionId(), startSession() and endSession() instead. From 4.0, wrapper SDKs must import PostHog with @_spi(PostHogInternal) to use it.")
@objc public func setSessionId(_ sessionId: String) {
public func setSessionId(_ sessionId: String) {
setSessionIdInternal(sessionId, at: now(), reason: .customSessionId)
}

Expand Down
6 changes: 3 additions & 3 deletions PostHog/PostHogStorageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import Foundation

/// Manages persisted identity metadata for a PostHog SDK instance.
///
/// - Warning: This class is public for backwards compatibility, but is intended for
/// SDK-internal use only. Application code should use `PostHogSDK` identity APIs
/// - Warning: For PostHog's wrapper SDKs only, which import it with
/// `@_spi(PostHogInternal)`. Application code should use `PostHogSDK` identity APIs
/// instead of interacting with storage directly.
public class PostHogStorageManager {
@_spi(PostHogInternal) public class PostHogStorageManager {
private let storage: PostHogStorage!

private let anonLock = NSLock()
Expand Down
6 changes: 3 additions & 3 deletions PostHog/PostHogVersion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import Foundation
/// Current SDK version string.
///
/// - Warning: This is intended for SDK internals and integrations. Application code should not mutate it.
public var postHogVersion = "3.90.0"
@_spi(PostHogInternal) public var postHogVersion = "3.90.0"

/// Default SDK name reported by the native iOS SDK.
public let postHogiOSSdkName = "posthog-ios"
let postHogiOSSdkName = "posthog-ios"

/// SDK name included in captured event context.
///
/// - Warning: This is intended for SDK internals and wrapper SDKs. Application code should not mutate it.
public var postHogSdkName = postHogiOSSdkName
@_spi(PostHogInternal) public var postHogSdkName = postHogiOSSdkName
3 changes: 1 addition & 2 deletions PostHog/Replay/Date+Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ extension Date {
///
/// - Parameter date: Date to convert.
/// - Returns: Milliseconds since 1970-01-01 00:00:00 UTC.
@available(*, deprecated, message: "dateToMillis(_:) becomes SDK-internal in PostHog 4.0. Use Int64(date.timeIntervalSince1970 * 1000) instead. From 4.0, wrapper SDKs must import PostHog with @_spi(PostHogInternal) to use it.")
public func dateToMillis(_ date: Date) -> Int64 {
@_spi(PostHogInternal) public func dateToMillis(_ date: Date) -> Int64 {
date.toMillis()
}
3 changes: 1 addition & 2 deletions PostHog/Replay/UIImage+Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
/// - image: Image to encode.
/// - compressionQuality: Compression quality from `0.0` to `1.0`. Defaults to `0.3`.
/// - Returns: A `data:image/...;base64` string, or `nil` if encoding fails.
@available(*, deprecated, message: "imageToBase64(_:_:) becomes SDK-internal in PostHog 4.0. From 4.0, wrapper SDKs must import PostHog with @_spi(PostHogInternal) to use it.")
public func imageToBase64(_ image: UIImage, _ compressionQuality: CGFloat = 0.3) -> String? {
@_spi(PostHogInternal) public func imageToBase64(_ image: UIImage, _ compressionQuality: CGFloat = 0.3) -> String? {
image.toBase64(compressionQuality)
}
#endif
3 changes: 1 addition & 2 deletions PostHog/Surveys/Utils/Survey+Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

// swiftlint:disable identifier_name
/// Convenience helpers for creating and describing survey colors.
public extension UIColor {
extension UIColor {
/**
Creates an immutable UIColor instance specified by a hex string, CSS color name, or nil.

Expand Down Expand Up @@ -71,7 +71,6 @@

- Returns: A new `String` with the color's hexadecimal value.
*/
@available(*, deprecated, message: "UIColor.hexDescription(_:) is removed from the public API in PostHog 4.0.")
func hexDescription(_ includeAlpha: Bool = false) -> String {
guard cgColor.numberOfComponents == 4 else {
return "Color not RGB."
Expand Down
30 changes: 15 additions & 15 deletions PostHog/Utils/Data+Gzip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,47 @@ import Foundation
#endif

/// Namespace for gzip constants used by the SDK's compression helpers.
public enum Gzip {
enum Gzip {
/// Maximum value for windowBits (`MAX_WBITS`).
public static let maxWindowBits = MAX_WBITS
static let maxWindowBits = MAX_WBITS
}

/// Compression level whose raw value is based on zlib constants.
public struct CompressionLevel: RawRepresentable, Sendable {
struct CompressionLevel: RawRepresentable, Sendable {
/// Compression level in the range of `0` (no compression) to `9` (maximum compression).
public let rawValue: Int32
let rawValue: Int32

/// zlib `Z_NO_COMPRESSION` level.
public static let noCompression = Self(Z_NO_COMPRESSION)
static let noCompression = Self(Z_NO_COMPRESSION)
/// zlib `Z_BEST_SPEED` level.
public static let bestSpeed = Self(Z_BEST_SPEED)
static let bestSpeed = Self(Z_BEST_SPEED)
/// zlib `Z_BEST_COMPRESSION` level.
public static let bestCompression = Self(Z_BEST_COMPRESSION)
static let bestCompression = Self(Z_BEST_COMPRESSION)

/// zlib `Z_DEFAULT_COMPRESSION` level.
public static let defaultCompression = Self(Z_DEFAULT_COMPRESSION)
static let defaultCompression = Self(Z_DEFAULT_COMPRESSION)

/// Creates a compression level from a zlib raw value.
///
/// - Parameter rawValue: zlib compression level constant.
public init(rawValue: Int32) {
init(rawValue: Int32) {
self.rawValue = rawValue
}

/// Creates a compression level from a zlib raw value.
///
/// - Parameter rawValue: zlib compression level constant.
public init(_ rawValue: Int32) {
init(_ rawValue: Int32) {
self.rawValue = rawValue
}
}

/// Errors on gzipping/gunzipping based on the zlib error codes.
public struct GzipError: Swift.Error, Sendable {
struct GzipError: Swift.Error, Sendable {
// cf. http://www.zlib.net/manual.html

/// High-level zlib error category.
public enum Kind: Equatable, Sendable {
enum Kind: Equatable, Sendable {
/// The stream structure was inconsistent.
///
/// - Note: Underlying zlib error: `Z_STREAM_ERROR` (-2).
Expand Down Expand Up @@ -112,18 +112,18 @@ public struct GzipError: Swift.Error, Sendable {
}

/// Error kind.
public let kind: Kind
let kind: Kind

/// Returned message by zlib.
public let message: String
let message: String

init(code: Int32, msg: UnsafePointer<CChar>?) {
message = msg.flatMap(String.init(validatingUTF8:)) ?? "Unknown gzip error"
kind = Kind(code: code)
}

/// Human-readable zlib error message.
public var localizedDescription: String {
var localizedDescription: String {
message
}
}
Expand Down
4 changes: 2 additions & 2 deletions PostHog/Utils/DateUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ let apiDateFormatter = PostHogAPIDateFormatter()
///
/// - Parameter date: Date to format.
/// - Returns: An ISO-8601-like timestamp string with milliseconds.
public func toISO8601String(_ date: Date) -> String {
func toISO8601String(_ date: Date) -> String {
apiDateFormatter.string(from: date)
}

/// Parses a date string in the SDK's API timestamp format.
///
/// - Parameter date: Timestamp string with optional milliseconds.
/// - Returns: A parsed `Date`, or `nil` when the string is invalid.
public func toISO8601Date(_ date: String) -> Date? {
func toISO8601Date(_ date: String) -> Date? {
apiDateFormatter.date(from: date)
}

Expand Down
2 changes: 1 addition & 1 deletion PostHog/Utils/DictUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func fromJSONData(_ data: Data, options: JSONSerialization.ReadingOptions = [])
///
/// - Parameter dict: Dictionary to sanitize.
/// - Returns: A sanitized dictionary, or `nil` when the input is `nil` or empty.
public func sanitizeDictionary(_ dict: [String: Any]?) -> [String: Any]? {
func sanitizeDictionary(_ dict: [String: Any]?) -> [String: Any]? {
if dict == nil || dict!.isEmpty {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion PostHog/Utils/FileUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
/// Deletes a file if it exists, logging and ignoring any removal error.
///
/// - Parameter file: File URL to delete.
public func deleteSafely(_ file: URL) {
func deleteSafely(_ file: URL) {
if FileManager.default.fileExists(atPath: file.path) {
do {
try FileManager.default.removeItem(at: file)
Expand Down
2 changes: 1 addition & 1 deletion PostHog/Utils/Reachability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Foundation
import SystemConfiguration

/// Errors thrown while creating or configuring reachability monitoring.
public enum ReachabilityError: Error {
enum ReachabilityError: Error {
/// Failed to create reachability with a socket address.
///
/// - Parameters:
Expand Down
3 changes: 2 additions & 1 deletion PostHogExample/SessionRecordingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ struct SessionRecordingView: View {
Section("Event Trigger") {
Button {
PostHogSDK.shared.stopSessionRecording()
PostHogSDK.shared.endSession()
PostHogSDK.shared.startSession()
PostHogSDK.shared.startSessionRecording()
PostHogSessionManager.shared.setSessionId(UUID().uuidString)
refreshStatus()
} label: {
Text("Restart & Rotate Session Id")
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogContextTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation
import Nimble
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Quick

class PostHogContextTest: QuickSpec {
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogDeviceBucketingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing
import XCTest

Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogEventSnapshotTests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing
import XCTest

Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogIdentityTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing

@Suite("Identity tests", .serialized)
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogLogsQueueTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import Foundation
import OHHTTPStubs
import OHHTTPStubsSwift
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing
import XCTest

Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogMemoryExceptionReporterTest.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing

#if os(iOS) && !targetEnvironment(macCatalyst) && compiler(>=6.4)
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogRemoteConfigTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Yiannis Josephides on 20/01/2025.
//

@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing
import XCTest

Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogSDKTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation
import Nimble
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
#if SWIFT_PACKAGE
import PostHogTestsObjC
#endif
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogSamplingTest.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing

@Suite("Session Replay Sampling Tests")
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogSessionManagerTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing

@Suite(.serialized, .resetsGlobalState)
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogSessionReplayEventTriggersTest.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#if os(iOS)
import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing

@Suite("Session Replay Event Triggers", .serialized)
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogSessionReplayManualModeTest.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#if os(iOS)
import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Testing

@Suite("Session Replay Manual Mode", .serialized)
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogSessionReplayPluginTest.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#if os(iOS)
import Foundation
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
#if !SWIFT_PACKAGE
import CwlCatchException
#endif
Expand Down
2 changes: 1 addition & 1 deletion PostHogTests/PostHogStorageManagerTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation
import Nimble
@testable import PostHog
@_spi(PostHogInternal) @testable import PostHog
import Quick

class PostHogStorageManagerTest: QuickSpec {
Expand Down
Loading
Loading