Skip to content

Commit

Permalink
Merge pull request #1918 from jfiser-paylocity/develop
Browse files Browse the repository at this point in the history
[Issue #125] Enable DatadogCore and DatadogLogs to compile on watchOS platform
  • Loading branch information
ncreated authored Jul 8, 2024
2 parents 72c95e5 + d9749fd commit a0b3240
Show file tree
Hide file tree
Showing 21 changed files with 212 additions and 22 deletions.
13 changes: 13 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,16 @@ Smoke Tests (macOS):
- ./tools/runner-setup.sh --xcode "$XCODE" # temporary, waiting for AMI
- make clean repo-setup ENV=ci
- make spm-build-macos

Smoke Tests (watchOS):
stage: smoke-test
tags:
- macos:ventura
- specific:true
variables:
XCODE: "15.2.0"
OS: "10.2"
script:
- ./tools/runner-setup.sh --xcode "$XCODE" --watchOS --os "$OS" # temporary, waiting for AMI
- make clean repo-setup ENV=ci
- make spm-build-watchos
18 changes: 18 additions & 0 deletions Datadog/Datadog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,12 @@
E1C853142AA9B9A300C74BCF /* TelemetryMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C853132AA9B9A300C74BCF /* TelemetryMocks.swift */; };
E1C853152AA9B9A300C74BCF /* TelemetryMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C853132AA9B9A300C74BCF /* TelemetryMocks.swift */; };
E1D5AEA724B4D45B007F194B /* Versioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D5AEA624B4D45A007F194B /* Versioning.swift */; };
E2AA55E42C32C6AF002FEF28 /* DeviceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AA55E32C32C6AF002FEF28 /* DeviceProtocol.swift */; };
E2AA55E52C32C6AF002FEF28 /* DeviceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AA55E32C32C6AF002FEF28 /* DeviceProtocol.swift */; };
E2AA55E72C32C6D9002FEF28 /* ApplicationNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AA55E62C32C6D9002FEF28 /* ApplicationNotifications.swift */; };
E2AA55E82C32C6D9002FEF28 /* ApplicationNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AA55E62C32C6D9002FEF28 /* ApplicationNotifications.swift */; };
E2AA55EA2C32C76A002FEF28 /* WatchKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AA55E92C32C76A002FEF28 /* WatchKitExtensions.swift */; };
E2AA55EC2C32C78B002FEF28 /* WatchKitExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2AA55E92C32C76A002FEF28 /* WatchKitExtensions.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -3030,6 +3036,9 @@
E1D202E924C065CF00D1AF3A /* ActiveSpansPool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpansPool.swift; sourceTree = "<group>"; };
E1D203FB24C1884500D1AF3A /* ActiveSpansPoolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveSpansPoolTests.swift; sourceTree = "<group>"; };
E1D5AEA624B4D45A007F194B /* Versioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Versioning.swift; sourceTree = "<group>"; };
E2AA55E32C32C6AF002FEF28 /* DeviceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceProtocol.swift; sourceTree = "<group>"; };
E2AA55E62C32C6D9002FEF28 /* ApplicationNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationNotifications.swift; sourceTree = "<group>"; };
E2AA55E92C32C76A002FEF28 /* WatchKitExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WatchKitExtensions.swift; sourceTree = "<group>"; };
F637AED12697404200516F32 /* UIKitRUMUserActionsPredicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitRUMUserActionsPredicate.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -5819,6 +5828,7 @@
D23039B2298D5235001A1FA3 /* Context */ = {
isa = PBXGroup;
children = (
E2AA55E62C32C6D9002FEF28 /* ApplicationNotifications.swift */,
D23039B3298D5235001A1FA3 /* AppState.swift */,
D23039B4298D5235001A1FA3 /* UserInfo.swift */,
D23039B5298D5235001A1FA3 /* BatteryStatus.swift */,
Expand All @@ -5829,6 +5839,7 @@
D23039BA298D5235001A1FA3 /* DatadogContext.swift */,
D23039BB298D5235001A1FA3 /* TrackingConsent.swift */,
D23039BC298D5235001A1FA3 /* DeviceInfo.swift */,
E2AA55E32C32C6AF002FEF28 /* DeviceProtocol.swift */,
D23039BE298D5235001A1FA3 /* LaunchTime.swift */,
D2F8235229915E12003C7E99 /* DatadogSite.swift */,
6174D6122BFDF16C00EC7469 /* BundleType.swift */,
Expand Down Expand Up @@ -6262,6 +6273,7 @@
D23039D9298D5235001A1FA3 /* DateFormatting.swift */,
613C6B8F2768FDDE00870CBF /* Sampler.swift */,
D23039DC298D5235001A1FA3 /* DDError.swift */,
E2AA55E92C32C76A002FEF28 /* WatchKitExtensions.swift */,
61133BBA2423979B00786299 /* SwiftExtensions.swift */,
D29A9F9429DDB1DB005C54A4 /* UIKitExtensions.swift */,
);
Expand Down Expand Up @@ -8584,6 +8596,7 @@
D23039F9298D5236001A1FA3 /* CoreLogger.swift in Sources */,
D2160CA229C0DE5700FAA9A5 /* NetworkInstrumentationFeature.swift in Sources */,
D2EBEE1F29BA160F00B15732 /* HTTPHeadersReader.swift in Sources */,
E2AA55E72C32C6D9002FEF28 /* ApplicationNotifications.swift in Sources */,
D263BCAF29DAFFEB00FA0E21 /* PerformancePresetOverride.swift in Sources */,
D23039E7298D5236001A1FA3 /* NetworkConnectionInfo.swift in Sources */,
D23039E9298D5236001A1FA3 /* TrackingConsent.swift in Sources */,
Expand All @@ -8597,6 +8610,7 @@
D2160CC929C0DED100FAA9A5 /* DatadogURLSessionDelegate.swift in Sources */,
D2EBEE2929BA160F00B15732 /* HTTPHeadersWriter.swift in Sources */,
D2432CF929EDB22C00D93657 /* Flushable.swift in Sources */,
E2AA55E42C32C6AF002FEF28 /* DeviceProtocol.swift in Sources */,
D23039F7298D5236001A1FA3 /* AttributesSanitizer.swift in Sources */,
D23039EB298D5236001A1FA3 /* DatadogFeature.swift in Sources */,
D2BEEDBA2B33638F0065F3AC /* NetworkInstrumentationSwizzler.swift in Sources */,
Expand Down Expand Up @@ -8629,6 +8643,7 @@
D2160CF429C0EDFC00FAA9A5 /* UploadPerformancePreset.swift in Sources */,
D23039E1298D5236001A1FA3 /* AppState.swift in Sources */,
D2DE63532A30A7CA00441A54 /* CoreRegistry.swift in Sources */,
E2AA55EA2C32C76A002FEF28 /* WatchKitExtensions.swift in Sources */,
D2EBEE2829BA160F00B15732 /* W3CHTTPHeadersWriter.swift in Sources */,
D23039EA298D5236001A1FA3 /* DeviceInfo.swift in Sources */,
D2EBEE2329BA160F00B15732 /* B3HTTPHeadersReader.swift in Sources */,
Expand Down Expand Up @@ -9551,6 +9566,7 @@
D2DA2358298D57AA00C6C7E6 /* CoreLogger.swift in Sources */,
D2160CA329C0DE5700FAA9A5 /* NetworkInstrumentationFeature.swift in Sources */,
D2EBEE2D29BA161100B15732 /* HTTPHeadersReader.swift in Sources */,
E2AA55E82C32C6D9002FEF28 /* ApplicationNotifications.swift in Sources */,
D263BCB029DAFFEB00FA0E21 /* PerformancePresetOverride.swift in Sources */,
D2DA2359298D57AA00C6C7E6 /* NetworkConnectionInfo.swift in Sources */,
D2DA235A298D57AA00C6C7E6 /* TrackingConsent.swift in Sources */,
Expand All @@ -9564,6 +9580,7 @@
D2160CCA29C0DED100FAA9A5 /* DatadogURLSessionDelegate.swift in Sources */,
D2EBEE3729BA161100B15732 /* HTTPHeadersWriter.swift in Sources */,
D2432CFA29EDB22C00D93657 /* Flushable.swift in Sources */,
E2AA55E52C32C6AF002FEF28 /* DeviceProtocol.swift in Sources */,
D2DA235D298D57AA00C6C7E6 /* AttributesSanitizer.swift in Sources */,
D2DA235E298D57AA00C6C7E6 /* DatadogFeature.swift in Sources */,
D2BEEDBB2B3363900065F3AC /* NetworkInstrumentationSwizzler.swift in Sources */,
Expand Down Expand Up @@ -9596,6 +9613,7 @@
D2160CF529C0EDFC00FAA9A5 /* UploadPerformancePreset.swift in Sources */,
D2DA236C298D57AA00C6C7E6 /* AppState.swift in Sources */,
D2DE63542A30A7CA00441A54 /* CoreRegistry.swift in Sources */,
E2AA55EC2C32C78B002FEF28 /* WatchKitExtensions.swift in Sources */,
D2EBEE3629BA161100B15732 /* W3CHTTPHeadersWriter.swift in Sources */,
D2DA236D298D57AA00C6C7E6 /* DeviceInfo.swift in Sources */,
D2EBEE3129BA161100B15732 /* B3HTTPHeadersReader.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions DatadogCore.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Pod::Spec.new do |s|
s.swift_version = '5.9'
s.ios.deployment_target = '12.0'
s.tvos.deployment_target = '12.0'
s.watchos.deployment_target = '7.0'

s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s }

Expand Down
27 changes: 17 additions & 10 deletions DatadogCore/Sources/Core/Context/ApplicationStatePublisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@
#if canImport(UIKit)
import UIKit
import DatadogInternal
#if canImport(WatchKit)
import WatchKit
#endif

internal final class ApplicationStatePublisher: ContextValuePublisher {
typealias Snapshot = AppStateHistory.Snapshot

private static var currentApplicationState: UIApplication.State {
private static var currentApplicationState: ApplicationState {
#if canImport(WatchKit)
WKExtension.dd.shared.applicationState
#else
UIApplication.dd.managedShared?.applicationState ?? .active // fallback to most expected state
#endif
}

/// The default publisher queue.
Expand Down Expand Up @@ -85,7 +92,7 @@ internal final class ApplicationStatePublisher: ContextValuePublisher {
/// - dateProvider: The date provider for the Application state snapshot timestamp.
/// - notificationCenter: The notification center where this publisher observes `UIApplication` notifications.
convenience init(
applicationState: UIApplication.State = ApplicationStatePublisher.currentApplicationState,
applicationState: ApplicationState = ApplicationStatePublisher.currentApplicationState,
queue: DispatchQueue = ApplicationStatePublisher.defaultQueue,
dateProvider: DateProvider = SystemDateProvider(),
notificationCenter: NotificationCenter = .default
Expand All @@ -100,10 +107,10 @@ internal final class ApplicationStatePublisher: ContextValuePublisher {

func publish(to receiver: @escaping ContextValueReceiver<AppStateHistory>) {
queue.async { self.receiver = receiver }
notificationCenter.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.didBecomeActiveNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationWillResignActive), name: UIApplication.willResignActiveNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationDidBecomeActive), name: ApplicationNotifications.didBecomeActive, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationWillResignActive), name: ApplicationNotifications.willResignActive, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationDidEnterBackground), name: ApplicationNotifications.didEnterBackground, object: nil)
notificationCenter.addObserver(self, selector: #selector(applicationWillEnterForeground), name: ApplicationNotifications.willEnterForeground, object: nil)
}

@objc
Expand Down Expand Up @@ -135,10 +142,10 @@ internal final class ApplicationStatePublisher: ContextValuePublisher {
}

func cancel() {
notificationCenter.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
notificationCenter.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
notificationCenter.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil)
notificationCenter.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
notificationCenter.removeObserver(self, name: ApplicationNotifications.didBecomeActive, object: nil)
notificationCenter.removeObserver(self, name: ApplicationNotifications.willResignActive, object: nil)
notificationCenter.removeObserver(self, name: ApplicationNotifications.didEnterBackground, object: nil)
notificationCenter.removeObserver(self, name: ApplicationNotifications.willEnterForeground, object: nil)
queue.async { self.receiver = nil }
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal protocol BackgroundTaskCoordinator {
import UIKit
import DatadogInternal

#if !os(watchOS)
/// Bridge protocol that calls corresponding `UIApplication` interface for background tasks. Allows easier testablity.
internal protocol UIKitAppBackgroundTaskCoordinator {
func beginBgTask(_ handler: (() -> Void)?) -> UIBackgroundTaskIdentifier
Expand Down Expand Up @@ -69,6 +70,7 @@ internal class AppBackgroundTaskCoordinator: BackgroundTaskCoordinator {
self.currentTaskId = nil
}
}
#endif

/// Bridge protocol that matches `ProcessInfo` interface for background activity. Allows easier testablity.
internal protocol ProcessInfoActivityCoordinator {
Expand Down
4 changes: 4 additions & 0 deletions DatadogCore/Sources/Core/Upload/FeatureUpload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ internal struct FeatureUpload {
let backgroundTaskCoordinator: BackgroundTaskCoordinator?
switch (backgroundTasksEnabled, isRunFromExtension) {
case (true, false):
#if os(watchOS)
backgroundTaskCoordinator = ExtensionBackgroundTaskCoordinator()
#else
backgroundTaskCoordinator = AppBackgroundTaskCoordinator()
#endif
case (true, true):
backgroundTaskCoordinator = ExtensionBackgroundTaskCoordinator()
case (false, _):
Expand Down
2 changes: 2 additions & 0 deletions DatadogCore/Sources/Core/Upload/URLSessionClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ internal class URLSessionClient: HTTPClient {
configuration.urlCache = nil
configuration.connectionProxyDictionary = proxyConfiguration

#if !os(watchOS)
// URLSession does not set the `Proxy-Authorization` header automatically when using a proxy
// configuration. We manually set the HTTP basic authentication header.
if let user = proxyConfiguration?[kCFProxyUsernameKey] as? String,
let password = proxyConfiguration?[kCFProxyPasswordKey] as? String {
let authorization = basicHTTPAuthentication(username: user, password: password)
configuration.httpAdditionalHeaders = ["Proxy-Authorization": authorization]
}
#endif

self.init(session: URLSession(configuration: configuration))
}
Expand Down
6 changes: 6 additions & 0 deletions DatadogCore/Sources/Kronos/KronosDNSResolver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ internal final class KronosDNSResolver {
timeout: TimeInterval = kDefaultTimeout,
completion: @escaping ([KronosInternetAddress]) -> Void
) {
#if os(watchOS)
completion([])
#else
let callback: CFHostClientCallBack = { host, _, _, info in
guard let info = info else {
return
Expand Down Expand Up @@ -79,8 +82,10 @@ internal final class KronosDNSResolver {
CFHostSetClient(hostReference, callback, &clientContext)
CFHostScheduleWithRunLoop(hostReference, CFRunLoopGetMain(), CFRunLoopMode.commonModes.rawValue)
CFHostStartInfoResolution(hostReference, .addresses, nil)
#endif
}

#if !os(watchOS)
@objc
private func onTimeout() {
defer {
Expand All @@ -99,4 +104,5 @@ internal final class KronosDNSResolver {
CFHostUnscheduleFromRunLoop(hostReference, CFRunLoopGetMain(), CFRunLoopMode.commonModes.rawValue)
CFHostSetClient(hostReference, nil, nil)
}
#endif
}
1 change: 1 addition & 0 deletions DatadogInternal.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Pod::Spec.new do |s|
s.swift_version = '5.9'
s.ios.deployment_target = '12.0'
s.tvos.deployment_target = '12.0'
s.watchos.deployment_target = '7.0'

s.source = { :git => "https://github.com/DataDog/dd-sdk-ios.git", :tag => s.version.to_s }

Expand Down
10 changes: 9 additions & 1 deletion DatadogInternal/Sources/Context/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,16 @@ extension AppStateHistory {

import UIKit

#if canImport(WatchKit)
import WatchKit

public typealias ApplicationState = WKApplicationState
#else
public typealias ApplicationState = UIApplication.State
#endif

extension AppState {
public init(_ state: UIApplication.State) {
public init(_ state: ApplicationState) {
switch state {
case .active:
self = .active
Expand Down
49 changes: 49 additions & 0 deletions DatadogInternal/Sources/Context/ApplicationNotifications.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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

#if canImport(UIKit)
import UIKit
#if canImport(WatchKit)
import WatchKit
#endif

/// Convenient wrapper to get system notifications independent from platform
public enum ApplicationNotifications {
public static var didBecomeActive: Notification.Name {
#if canImport(WatchKit)
WKExtension.applicationDidBecomeActiveNotification
#else
UIApplication.didBecomeActiveNotification
#endif
}

public static var willResignActive: Notification.Name {
#if canImport(WatchKit)
WKExtension.applicationWillResignActiveNotification
#else
UIApplication.willResignActiveNotification
#endif
}

public static var didEnterBackground: Notification.Name {
#if canImport(WatchKit)
WKExtension.applicationDidEnterBackgroundNotification
#else
UIApplication.didEnterBackgroundNotification
#endif
}

public static var willEnterForeground: Notification.Name {
#if canImport(WatchKit)
WKExtension.applicationWillEnterForegroundNotification
#else
UIApplication.willEnterForegroundNotification
#endif
}
}
#endif
10 changes: 5 additions & 5 deletions DatadogInternal/Sources/Context/DeviceInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ import MachO
import UIKit

extension DeviceInfo {
/// Creates device info based on UIKit description.
/// Creates device info based on device description.
///
/// - Parameters:
/// - processInfo: The current process information.
/// - device: The `UIDevice` description.
/// - device: The `DeviceProtocol` description.
public init(
processInfo: ProcessInfo = .processInfo,
device: UIDevice = .current,
device: DeviceProtocol = DeviceFactory.current,
sysctl: SysctlProviding = Sysctl()
) {
var architecture = "unknown"
Expand All @@ -96,7 +96,7 @@ extension DeviceInfo {

#if !targetEnvironment(simulator)
let model = try? sysctl.model()
// Real iOS device
// Real device
self.init(
name: device.model,
model: model ?? device.model,
Expand All @@ -111,7 +111,7 @@ extension DeviceInfo {
)
#else
let model = processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] ?? device.model
// iOS Simulator - battery monitoring doesn't work on Simulator, so return "always OK" value
// Simulator - battery monitoring doesn't work on Simulator, so return "always OK" value
self.init(
name: device.model,
model: "\(model) Simulator",
Expand Down
Loading

0 comments on commit a0b3240

Please sign in to comment.