Skip to content

Commit

Permalink
Merge pull request #1711 from DataDog/maciey/innovation-week-changes
Browse files Browse the repository at this point in the history
[Innovation week] Enable compilation for macOS
  • Loading branch information
maciejburda authored Apr 24, 2024
2 parents 0387e08 + c08e66b commit 79943d3
Show file tree
Hide file tree
Showing 21 changed files with 620 additions and 49 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [FEATURE] Add support for 128 bit trace IDs. See [#1721][]
- [FEATURE] Fatal App Hangs are tracked in RUM. See [#1763][]
- [FIX] Avoid name collision with Required Reason APIs. See [#1774][]
- [IMPROVEMENT] Make the SDK compile on macOS 12+. See [#1711][]

# 2.9.0 / 11-04-2024

Expand Down Expand Up @@ -629,6 +630,7 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO
[#1696]: https://github.com/DataDog/dd-sdk-ios/pull/1696
[#1697]: https://github.com/DataDog/dd-sdk-ios/pull/1697
[#1707]: https://github.com/DataDog/dd-sdk-ios/pull/1707
[#1711]: https://github.com/DataDog/dd-sdk-ios/pull/1711
[#1722]: https://github.com/DataDog/dd-sdk-ios/pull/1722
[#1724]: https://github.com/DataDog/dd-sdk-ios/pull/1724
[#1741]: https://github.com/DataDog/dd-sdk-ios/pull/1741
Expand Down
8 changes: 6 additions & 2 deletions DatadogCore/Private/ObjcAppLaunchHandler.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
* Copyright 2019-Present Datadog, Inc.
*/

#import <UIKit/UIKit.h>
#import <pthread.h>
#import <sys/sysctl.h>

#import "ObjcAppLaunchHandler.h"

#if TARGET_OS_IOS || TARGET_OS_TV
#import <UIKit/UIKit.h>
#endif

// A very long application launch time is most-likely the result of a pre-warmed process.
// We consider 30s as a threshold for pre-warm detection.
#define COLD_START_TIME_THRESHOLD 30
Expand Down Expand Up @@ -39,7 +42,7 @@ + (void)load {
// This is called at the `DatadogPrivate` load time, keep the work minimal
_shared = [[self alloc] initWithProcessInfo:NSProcessInfo.processInfo
loadTime:CFAbsoluteTimeGetCurrent()];

#if TARGET_OS_IOS || TARGET_OS_TV
NSNotificationCenter * __weak center = NSNotificationCenter.defaultCenter;
id __block __unused token = [center addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil
Expand All @@ -55,6 +58,7 @@ + (void)load {
[center removeObserver:token];
token = nil;
}];
#endif
}

+ (__dd_private_AppLaunchHandler *)shared {
Expand Down
2 changes: 2 additions & 0 deletions DatadogCore/Sources/Core/Context/LaunchTimePublisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright 2019-Present Datadog, Inc.
*/

#if !os(macOS)
import Foundation
import DatadogInternal

Expand Down Expand Up @@ -42,3 +43,4 @@ internal struct LaunchTimePublisher: ContextValuePublisher {
AppLaunchHandler.shared.setApplicationDidBecomeActiveCallback { _ in }
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,13 @@ extension NetworkConnectionInfo.Reachability {
extension NetworkConnectionInfo.Interface {
@available(iOS 2.0, macCatalyst 13.0, *)
init?(_ flags: SCNetworkReachabilityFlags?) {
#if os(iOS) || os(tvOS)
guard let flags = flags, flags.contains(.isWWAN) else {
return nil
}
self = .cellular
#else
self = .other
#endif
}
}
3 changes: 3 additions & 0 deletions DatadogCore/Sources/Core/DatadogCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,10 @@ extension DatadogContextProvider {
self.init(context: context)

subscribe(\.serverTimeOffset, to: ServerOffsetPublisher(provider: serverDateProvider))

#if !os(macOS)
subscribe(\.launchTime, to: LaunchTimePublisher())
#endif

if #available(iOS 12, tvOS 12, *) {
subscribe(\.networkConnectionInfo, to: NWPathMonitorPublisher())
Expand Down
2 changes: 1 addition & 1 deletion DatadogCore/Sources/Core/Upload/FeatureUpload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internal struct FeatureUpload {
? UIKitBackgroundTaskCoordinator()
: nil
#else
let backgroundTaskCoordinator = nil
let backgroundTaskCoordinator: BackgroundTaskCoordinator? = nil
#endif

self.init(
Expand Down
6 changes: 5 additions & 1 deletion DatadogCore/Sources/Datadog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,12 @@ public enum Datadog {
consolePrint("⚠️ Catalyst is not officially supported by Datadog SDK: some features may NOT be functional!", .warn)
#endif

#if os(macOS)
consolePrint("⚠️ macOS is not officially supported by Datadog SDK: some features may NOT be functional!", .warn)
#endif

#if swift(>=5.9) && os(visionOS)
consolePrint("⚠️ VisionOS is not officially supported by Datadog SDK: some features may NOT be functional!", .warn)
consolePrint("⚠️ visionOS is not officially supported by Datadog SDK: some features may NOT be functional!", .warn)
#endif

do {
Expand Down
33 changes: 31 additions & 2 deletions DatadogInternal/Sources/Context/DeviceInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ public struct DeviceInfo: Codable, Equatable, PassthroughAnyCodable {
}
}

#if canImport(UIKit)
import MachO

#if canImport(UIKit)
import UIKit
import MachO

extension DeviceInfo {
/// Creates device info based on UIKit description.
Expand Down Expand Up @@ -96,4 +96,33 @@ extension DeviceInfo {
#endif
}
}
#elseif os(macOS)
/// Creates device info based on Host description.
///
/// - Parameters:
/// - processInfo: The current process information.
extension DeviceInfo {
public init(
processInfo: ProcessInfo = .processInfo
) {
var architecture = "unknown"
if let archInfo = NXGetLocalArchInfo()?.pointee {
architecture = String(utf8String: archInfo.name) ?? "unknown"
}
Host.current().name

let build = (try? Sysctl.osVersion()) ?? ""
let model = (try? Sysctl.model()) ?? ""
let systemVersion = processInfo.operatingSystemVersion

self.init(
name: model.components(separatedBy: CharacterSet.letters.inverted).joined(),
model: model,
osName: "macOS",
osVersion: "\(systemVersion.majorVersion).\(systemVersion.minorVersion).\(systemVersion.patchVersion)",
osBuildNumber: build,
architecture: architecture
)
}
}
#endif
2 changes: 1 addition & 1 deletion DatadogInternal/Sources/Upload/DefaultJSONEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extension DatadogExtension where ExtendedType == JSONEncoder {
let formatted = iso8601DateFormatter.string(from: date)
try container.encode(formatted)
}
if #available(iOS 13, tvOS 13, macOS 10.15, *) {
if #available(iOS 13, tvOS 13, *) {
encoder.outputFormatting = [.withoutEscapingSlashes]
}
return encoder
Expand Down
4 changes: 3 additions & 1 deletion DatadogRUM/Sources/RUMVitals/VitalRefreshRateReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ extension FrameInfoProvider {
extension CADisplayLink: FrameInfoProvider {
var maximumDeviceFramesPerSecond: Int {
#if swift(>=5.9) && os(visionOS)
120
// Hardcoded as for now there's no good way of extracting maximum FPS on VisionOS
// https://developer.apple.com/documentation/visionos/analyzing-the-performance-of-your-visionos-app#Inspect-frame-rendering-performance
90
#else
UIScreen.main.maximumFramesPerSecond
#endif
Expand Down
3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ let package = Package(
name: "Datadog",
platforms: [
.iOS(.v11),
.tvOS(.v11)
.tvOS(.v11),
.macOS(.v12)
],
products: [
.library(
Expand Down
22 changes: 15 additions & 7 deletions SUPPORTED-VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,24 @@
| **iOS** || `11+` |
| **tvOS** || `11+` |
| **iPadOS** || `11+` |
| **VisionOS** | ⚠️ | `1.1+` |
| **macOS (Designed for iPad)** || `11+` |
| **macOS (Catalyst)** | ⚠️ | `12+` |
| **macOS** | ⚠️ | `12+` |
| **visionOS** | ⚠️ | `1.0+` |
| **watchOS**|| `n/a` |
| **macOS** || `n/a` |
| **Linux** || `n/a` |

## VisionOS
VisionOS is not officially supported by Datadog SDK. Some features may not be fully functional.

VisionOS is not officially supported by Datadog SDK. Some features may not be fully functional. Note that `DatadogCrashReporting` is not supported on VisionOS, due to lack of support on the [PLCrashReporter side](https://github.com/microsoft/plcrashreporter/issues/288).

## MacOS

MacOS is not officially supported by Datadog SDK. Some features may not be fully functional. Note that `DatadogRUM`, `DatadogSessionReplay` and `DatadogObjc` which heavily depend on `UIKit` do not build on macOS.

## Catalyst

We support Catalyst in build mode only, which means that macOS target will build, but functionalities for the SDK might not work for this target.

## Xcode

Expand Down Expand Up @@ -47,9 +58,6 @@ We currently support integration of the SDK using following dependency managers.

*Note: Third party networking libraries can be instrumented by implementing custom `DDURLSessionDelegate`.*

## Catalyst
We support Catalyst in build mode only, which means that macOS target will build, but functionalities for the SDK won't work for this target.

## Dependencies
The Datadog SDK depends on the following third-party library:
- [PLCrashReporter](https://github.com/microsoft/plcrashreporter) 1.11.1
- [PLCrashReporter](https://github.com/microsoft/plcrashreporter) 1.11.1
12 changes: 12 additions & 0 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,18 @@ workflows:
-project "$BITRISE_SOURCE_DIR/dependency-manager-tests/spm/SPMProject.xcodeproj" \
-destination "platform=macOS,variant=Mac Catalyst" \
| xcpretty
- script:
title: Check macOS compatibility (build SPMProject for macOS)
run_if: '{{enveq "DD_RUN_SMOKE_TESTS" "1"}}'
inputs:
- content: |-
#!/usr/bin/env bash
set -euxo pipefail
xcodebuild build -scheme "App macOS" \
-project "$BITRISE_SOURCE_DIR/dependency-manager-tests/spm/SPMProject.xcodeproj" \
-destination "platform=macOS" \
| xcpretty
- xcode-test:
title: Run SPMProject iOS tests
run_if: '{{enveq "DD_RUN_SMOKE_TESTS" "1"}}'
Expand Down
2 changes: 2 additions & 0 deletions dependency-manager-tests/spm/App macOS/App_macOS.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<key>com.apple.security.app-sandbox</key>
<true/>
20 changes: 20 additions & 0 deletions dependency-manager-tests/spm/App macOS/App_macOSApp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 SwiftUI

@main
struct App_macOSApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}

init() {
DatadogSetup.initialize()
}
}
18 changes: 18 additions & 0 deletions dependency-manager-tests/spm/App macOS/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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 SwiftUI

struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
Text("Testing...")
}
.padding()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 XCTest

final class App_macOSUITests: XCTestCase {
func testExample() throws {
let app = XCUIApplication()
app.launch()
XCTAssert(app.staticTexts["Testing..."].exists)
}
}
33 changes: 3 additions & 30 deletions dependency-manager-tests/spm/App/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,19 @@
*/

import UIKit
import DatadogCore
import DatadogLogs
import DatadogTrace
import DatadogRUM
import DatadogCrashReporting
import DatadogSessionReplay // it should compile for iOS and tvOS, but APIs are only available on iOS
import DatadogObjc
import DatadogSessionReplay // it should compile for iOS and tvOS, but APIs are only available on iOS

internal class ViewController: UIViewController {
private var logger: LoggerProtocol! // swiftlint:disable:this implicitly_unwrapped_optional

override func viewDidLoad() {
super.viewDidLoad()

Datadog.initialize(
with: Datadog.Configuration(clientToken: "abc", env: "tests"),
trackingConsent: .granted
)

Logs.enable()

CrashReporting.enable()

self.logger = Logger.create(
with: Logger.Configuration(
remoteSampleRate: 0,
consoleLogFormat: .short
)
)
DatadogSetup.initialize()

// RUM APIs must be visible:
RUM.enable(with: .init(applicationID: "app-id"))
RUMMonitor.shared().startView(viewController: self)

// Trace APIs must be visible:
Trace.enable()

logger.info("It works")
_ = Tracer.shared().startSpan(operationName: "this too")


#if os(iOS)
// Session Replay API must be visible:
SessionReplay.enable(with: .init(replaySampleRate: 0))
Expand Down
Loading

0 comments on commit 79943d3

Please sign in to comment.