diff --git a/Sources/Datadog/Core/AutoInstrumentation/MethodSwizzler.swift b/Sources/Datadog/Core/AutoInstrumentation/MethodSwizzler.swift index 4760a031b6..84612ae654 100644 --- a/Sources/Datadog/Core/AutoInstrumentation/MethodSwizzler.swift +++ b/Sources/Datadog/Core/AutoInstrumentation/MethodSwizzler.swift @@ -62,8 +62,8 @@ internal class MethodSwizzler { @discardableResult func swizzle( _ foundMethod: FoundMethod, - impProvider: (TypedIMP) -> TypedBlockIMP, - onlyIfNonSwizzled: Bool = false + onlyIfNonSwizzled: Bool = false, + impProvider: (TypedIMP) -> TypedBlockIMP ) -> Bool { sync { if onlyIfNonSwizzled && diff --git a/Sources/Datadog/Core/AutoInstrumentation/URLSessionSwizzler.swift b/Sources/Datadog/Core/AutoInstrumentation/URLSessionSwizzler.swift index 1be2eb069f..a45a6d1b1e 100644 --- a/Sources/Datadog/Core/AutoInstrumentation/URLSessionSwizzler.swift +++ b/Sources/Datadog/Core/AutoInstrumentation/URLSessionSwizzler.swift @@ -146,14 +146,13 @@ internal class URLSessionSwizzler { typealias BlockIMP = @convention(block) (URLSessionTask) -> Void swizzle( foundMethod, - impProvider: { currentTypedImp -> BlockIMP in - return { impSelf in - impSelf.consumePayloads { $0(.starting(impSelf.currentRequest)) } - return currentTypedImp(impSelf, Self.selector) - } - }, onlyIfNonSwizzled: true - ) + ) { currentTypedImp -> BlockIMP in + return { impSelf in + impSelf.consumePayloads { $0(.starting(impSelf.currentRequest)) } + return currentTypedImp(impSelf, Self.selector) + } + } } } } diff --git a/Sources/Datadog/Core/Persistence/Files/File.swift b/Sources/Datadog/Core/Persistence/Files/File.swift index 1f9f26a5d5..bf552529ef 100644 --- a/Sources/Datadog/Core/Persistence/Files/File.swift +++ b/Sources/Datadog/Core/Persistence/Files/File.swift @@ -46,60 +46,84 @@ internal struct File: WritableFile, ReadableFile { func append(data: Data) throws { let fileHandle = try FileHandle(forWritingTo: url) + // NOTE: RUMM-669 + // https://github.com/DataDog/dd-sdk-ios/issues/214 + // https://en.wikipedia.org/wiki/Xcode#11.x_series + // compiler version needs to have iOS 13.4+ as base SDK + #if compiler(>=5.2) + /** + Even though the `fileHandle.seekToEnd()` should be available since iOS 13.0: + ``` + @available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func seekToEnd() throws -> UInt64 + ``` + it crashes on iOS Simulators prior to iOS 13.4: + ``` + Symbol not found: _$sSo12NSFileHandleC10FoundationE9seekToEnds6UInt64VyKF + ``` + This is fixed in iOS 14/Xcode 12 + */ if #available(iOS 13.4, *) { - /** - Even though the `fileHandle.seekToEnd()` should be available since iOS 13.0: - ``` - @available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) - public func seekToEnd() throws -> UInt64 - ``` - it crashes on iOS Simulators prior to iOS 13.4: - ``` - Symbol not found: _$sSo12NSFileHandleC10FoundationE9seekToEnds6UInt64VyKF - ``` - */ defer { try? fileHandle.close() } try fileHandle.seekToEnd() try fileHandle.write(contentsOf: data) } else { - defer { - try? objcExceptionHandler.rethrowToSwift { - fileHandle.closeFile() - } - } + try legacyAppend(data, to: fileHandle) + } + #else + try legacyAppend(data, to: fileHandle) + #endif + } - try objcExceptionHandler.rethrowToSwift { - fileHandle.seekToEndOfFile() - fileHandle.write(data) + private func legacyAppend(_ data: Data, to fileHandle: FileHandle) throws { + defer { + try? objcExceptionHandler.rethrowToSwift { + fileHandle.closeFile() } } + try objcExceptionHandler.rethrowToSwift { + fileHandle.seekToEndOfFile() + fileHandle.write(data) + } } func read() throws -> Data { let fileHandle = try FileHandle(forReadingFrom: url) + // NOTE: RUMM-669 + // https://github.com/DataDog/dd-sdk-ios/issues/214 + // https://en.wikipedia.org/wiki/Xcode#11.x_series + // compiler version needs to have iOS 13.4+ as base SDK + #if compiler(>=5.2) + /** + Even though the `fileHandle.seekToEnd()` should be available since iOS 13.0: + ``` + @available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) + public func readToEnd() throws -> Data? + ``` + it crashes on iOS Simulators prior to iOS 13.4: + ``` + Symbol not found: _$sSo12NSFileHandleC10FoundationE9readToEndAC4DataVSgyKF + ``` + This is fixed in iOS 14/Xcode 12 + */ if #available(iOS 13.4, *) { - /** - Even though the `fileHandle.seekToEnd()` should be available since iOS 13.0: - ``` - @available(OSX 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) - public func readToEnd() throws -> Data? - ``` - it crashes on iOS Simulators prior to iOS 13.4: - ``` - Symbol not found: _$sSo12NSFileHandleC10FoundationE9readToEndAC4DataVSgyKF - ``` - */ defer { try? fileHandle.close() } return try fileHandle.readToEnd() ?? Data() } else { - defer { - try? objcExceptionHandler.rethrowToSwift { - fileHandle.closeFile() - } - } - return fileHandle.readDataToEndOfFile() + return try legacyRead(from: fileHandle) + } + #else + return try legacyRead(from: fileHandle) + #endif + } + + private func legacyRead(from fileHandle: FileHandle) throws -> Data { + let data = fileHandle.readDataToEndOfFile() + try? objcExceptionHandler.rethrowToSwift { + fileHandle.closeFile() } + return data } func size() throws -> UInt64 { diff --git a/Tests/DatadogTests/Datadog/Core/AutoInstrumentation/MethodSwizzlerTests.swift b/Tests/DatadogTests/Datadog/Core/AutoInstrumentation/MethodSwizzlerTests.swift index 8475c04842..71fac60359 100644 --- a/Tests/DatadogTests/Datadog/Core/AutoInstrumentation/MethodSwizzlerTests.swift +++ b/Tests/DatadogTests/Datadog/Core/AutoInstrumentation/MethodSwizzlerTests.swift @@ -107,7 +107,7 @@ class MethodSwizzlerTests: XCTestCase { let secondSwizzlingReturnValue = "Second swizzling" let newImp: TypedBlockIMPReturnString = { _ in secondSwizzlingReturnValue } XCTAssertFalse( - swizzler.swizzle(foundMethod, impProvider: { _ in newImp }, onlyIfNonSwizzled: true), + swizzler.swizzle(foundMethod, onlyIfNonSwizzled: true) { _ in newImp }, "Already swizzled method should not be swizzled again" ) @@ -130,12 +130,11 @@ class MethodSwizzlerTests: XCTestCase { XCTAssertFalse( swizzler.swizzle( foundMethod, - impProvider: { _ -> TypedBlockIMPReturnString in - XCTFail("New IMP should not be created after error") - return newIMPReturnString - }, onlyIfNonSwizzled: true - ), + ) { _ -> TypedBlockIMPReturnString in + XCTFail("New IMP should not be created after error") + return newIMPReturnString + }, "Already swizzled method should not be swizzled again" ) } @@ -178,13 +177,12 @@ class MethodSwizzlerTests: XCTestCase { DispatchQueue.concurrentPerform(iterations: iterations) { _ in swizzler.swizzle( foundMethod, - impProvider: { originalImp -> TypedBlockIMPReturnString in - return { impSelf -> String in - return originalImp(impSelf, selector).appending(appendString) - } - }, onlyIfNonSwizzled: true - ) + ) { originalImp -> TypedBlockIMPReturnString in + return { impSelf -> String in + return originalImp(impSelf, selector).appending(appendString) + } + } expectation.fulfill() }