From ac12fe0f13f6dd75c8e57919c4c3bf47512bc615 Mon Sep 17 00:00:00 2001 From: Ignacio Tischelman Date: Thu, 27 Feb 2025 13:06:59 -0300 Subject: [PATCH] Re-enabling SwiftLint plugin --- .swiftlint.yml | 1 + Package.resolved | 9 ++++++++ Package.swift | 12 ++++++++++ README.md | 6 +++++ .../Models/EmbraceStackTrace.swift | 1 - .../EmbraceCore/Capture/CaptureServices.swift | 7 +++++- .../URLSessionCaptureService+Options.swift | 6 ++++- .../Capture/UX/Tap/TapCaptureService.swift | 2 +- .../UX/View/UIViewControllerHandler.swift | 1 - .../Capture/WebView/WKWebView+Embrace.swift | 3 ++- .../EmbraceCore/Internal/Embrace+Config.swift | 7 +++++- .../Tracing/StorageSpanExporter.swift | 1 - .../Options/Embrace+Endpoints.swift | 3 ++- .../Public/Metadata/MetadataRecordTmp.swift | 10 +++++++- .../EmbraceStorageError.swift | 1 - .../Queries/SpanRecord+SessionQuery.swift | 2 +- .../EmbraceUploadInternal/EmbraceUpload.swift | 23 +++++++++++-------- .../EmbraceUpload+ExponentialBackoff.swift | 4 +++- 18 files changed, 76 insertions(+), 23 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 402a1177..2d91acf5 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -3,6 +3,7 @@ disabled_rules: # rule identifiers turned on by default to exclude from running - function_parameter_count - notification_center_detachment - compiler_protocol_init + - for_where opt_in_rules: - conditional_returns_on_newline diff --git a/Package.resolved b/Package.resolved index 17d5ee72..5322cbe0 100644 --- a/Package.resolved +++ b/Package.resolved @@ -153,6 +153,15 @@ "version" : "1.3.1" } }, + { + "identity" : "swiftlintplugins", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SimplyDanny/SwiftLintPlugins", + "state" : { + "revision" : "7a3d77f3dd9f91d5cea138e52c20cfceabf352de", + "version" : "0.58.2" + } + }, { "identity" : "thrift-swift", "kind" : "remoteSourceControl", diff --git a/Package.swift b/Package.swift index d709f915..3dac3559 100644 --- a/Package.swift +++ b/Package.swift @@ -292,3 +292,15 @@ let package = Package( ) ] ) + +if ProcessInfo.processInfo.environment["EMBRACE_ENABLE_SWIFTLINT"] != nil { + package.dependencies.append(contentsOf: [ + .package(url: "https://github.com/SimplyDanny/SwiftLintPlugins", from: "0.58.2") + ]) + + for target in package.targets { + target.plugins = [ + .plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLintPlugins"), + ] + } +} diff --git a/README.md b/README.md index bee0d4bf..425078a1 100644 --- a/README.md +++ b/README.md @@ -175,6 +175,12 @@ swiftlint --fix ### Using SwiftLint +The SwiftLint Xcode plugin can be optionally enabled during development by using an environmental variable when opening the project from the commandline. +``` +EMBRACE_ENABLE_SWIFTLINT=1 open Package.swift +``` +Note: Xcode must be completely closed before running the above command, close Xcode using `⌘Q` or running `killall xcode` in the commandline. + Aside from the warnings and errors that will appear directly in Xcode, you can use SwiftLint to automatically correct some issues. For this first you'll need to install SwiftLint in your local environment. Follow [SwiftLint's GitHub page](https://github.com/realm/SwiftLint) to see all available options. diff --git a/Sources/EmbraceCommonInternal/Models/EmbraceStackTrace.swift b/Sources/EmbraceCommonInternal/Models/EmbraceStackTrace.swift index 48f87197..f1e27f29 100644 --- a/Sources/EmbraceCommonInternal/Models/EmbraceStackTrace.swift +++ b/Sources/EmbraceCommonInternal/Models/EmbraceStackTrace.swift @@ -80,4 +80,3 @@ public struct EmbraceStackTrace: Equatable { return frame.range(of: pattern, options: .regularExpression) != nil } } - diff --git a/Sources/EmbraceCore/Capture/CaptureServices.swift b/Sources/EmbraceCore/Capture/CaptureServices.swift index 6c800b97..408146b0 100644 --- a/Sources/EmbraceCore/Capture/CaptureServices.swift +++ b/Sources/EmbraceCore/Capture/CaptureServices.swift @@ -19,7 +19,12 @@ final class CaptureServices { weak var config: EmbraceConfigurable? - init(options: Embrace.Options, config: EmbraceConfigurable?, storage: EmbraceStorage?, upload: EmbraceUpload?) throws { + init( + options: Embrace.Options, + config: EmbraceConfigurable?, + storage: EmbraceStorage?, + upload: EmbraceUpload? + ) throws { self.config = config // add required capture services diff --git a/Sources/EmbraceCore/Capture/Network/URLSessionCaptureService+Options.swift b/Sources/EmbraceCore/Capture/Network/URLSessionCaptureService+Options.swift index 2ce83bc6..88359a8f 100644 --- a/Sources/EmbraceCore/Capture/Network/URLSessionCaptureService+Options.swift +++ b/Sources/EmbraceCore/Capture/Network/URLSessionCaptureService+Options.swift @@ -19,7 +19,11 @@ extension URLSessionCaptureService { /// Any request's url that contains any of these strings will not be captured. @objc public let ignoredURLs: [String] - @objc public init(injectTracingHeader: Bool, requestsDataSource: URLSessionRequestsDataSource?, ignoredURLs: [String]) { + @objc public init( + injectTracingHeader: Bool, + requestsDataSource: URLSessionRequestsDataSource?, + ignoredURLs: [String] + ) { self.injectTracingHeader = injectTracingHeader self.requestsDataSource = requestsDataSource self.ignoredURLs = ignoredURLs diff --git a/Sources/EmbraceCore/Capture/UX/Tap/TapCaptureService.swift b/Sources/EmbraceCore/Capture/UX/Tap/TapCaptureService.swift index 7936d8d2..e4977d61 100644 --- a/Sources/EmbraceCore/Capture/UX/Tap/TapCaptureService.swift +++ b/Sources/EmbraceCore/Capture/UX/Tap/TapCaptureService.swift @@ -134,7 +134,7 @@ class UIWindowSendEventSwizzler: Swizzlable { var onEvent: ((UIEvent) -> Void)? func install() throws { - try swizzleInstanceMethod { originalImplementation in { [weak self] uiWindow, uiEvent -> Void in + try swizzleInstanceMethod { originalImplementation in { [weak self] uiWindow, uiEvent in self?.onEvent?(uiEvent) originalImplementation(uiWindow, UIWindowSendEventSwizzler.selector, uiEvent) } diff --git a/Sources/EmbraceCore/Capture/UX/View/UIViewControllerHandler.swift b/Sources/EmbraceCore/Capture/UX/View/UIViewControllerHandler.swift index d700d1bd..686140fb 100644 --- a/Sources/EmbraceCore/Capture/UX/View/UIViewControllerHandler.swift +++ b/Sources/EmbraceCore/Capture/UX/View/UIViewControllerHandler.swift @@ -108,7 +108,6 @@ class UIViewControllerHandler { queue.async { // generate parent span - let spanName = nameFormat.replacingOccurrences(of: "NAME", with: className) let parentSpan = self.createSpan( diff --git a/Sources/EmbraceCore/Capture/WebView/WKWebView+Embrace.swift b/Sources/EmbraceCore/Capture/WebView/WKWebView+Embrace.swift index 3a3d41d9..d78c169d 100644 --- a/Sources/EmbraceCore/Capture/WebView/WKWebView+Embrace.swift +++ b/Sources/EmbraceCore/Capture/WebView/WKWebView+Embrace.swift @@ -14,7 +14,8 @@ extension WKWebView { var emb_proxy: EMBWKNavigationDelegateProxy? { get { - if let value = objc_getAssociatedObject(self, &AssociatedKeys.embraceProxy) as? EMBWKNavigationDelegateProxy { + if let value = objc_getAssociatedObject(self, &AssociatedKeys.embraceProxy) + as? EMBWKNavigationDelegateProxy { return value as EMBWKNavigationDelegateProxy } diff --git a/Sources/EmbraceCore/Internal/Embrace+Config.swift b/Sources/EmbraceCore/Internal/Embrace+Config.swift index e71f691c..9a7a1bfc 100644 --- a/Sources/EmbraceCore/Internal/Embrace+Config.swift +++ b/Sources/EmbraceCore/Internal/Embrace+Config.swift @@ -39,6 +39,11 @@ extension Embrace { return DefaultConfig() } + let cacheLocation = EmbraceFileSystem.configDirectoryURL( + partitionIdentifier: appId, + appGroupId: options.appGroupId + ) + let options = RemoteConfig.Options( apiBaseUrl: configBaseURL, queue: DispatchQueue(label: "com.embrace.config"), @@ -48,7 +53,7 @@ extension Embrace { sdkVersion: EmbraceMeta.sdkVersion, appVersion: EMBDevice.operatingSystemVersion, userAgent: EmbraceMeta.userAgent, - cacheLocation: EmbraceFileSystem.configDirectoryURL(partitionIdentifier: appId, appGroupId: options.appGroupId) + cacheLocation: cacheLocation ) return RemoteConfig( diff --git a/Sources/EmbraceCore/Internal/Tracing/StorageSpanExporter.swift b/Sources/EmbraceCore/Internal/Tracing/StorageSpanExporter.swift index d3359d08..95dd61b3 100644 --- a/Sources/EmbraceCore/Internal/Tracing/StorageSpanExporter.swift +++ b/Sources/EmbraceCore/Internal/Tracing/StorageSpanExporter.swift @@ -48,7 +48,6 @@ class StorageSpanExporter: SpanExporter { } public func flush(explicitTimeout: TimeInterval?) -> SpanExporterResultCode { - // TODO: do we need to make sure storage writes are finished? return .success } diff --git a/Sources/EmbraceCore/Options/Embrace+Endpoints.swift b/Sources/EmbraceCore/Options/Embrace+Endpoints.swift index e6413b71..91e05d2f 100644 --- a/Sources/EmbraceCore/Options/Embrace+Endpoints.swift +++ b/Sources/EmbraceCore/Options/Embrace+Endpoints.swift @@ -17,7 +17,7 @@ extension Embrace { @objc public let configBaseURL: String @available(*, deprecated, message: "Development base URL is not used anymore.") - @objc public let developmentBaseURL: String = "" + @objc public let developmentBaseURL: String = "" // TODO: Remove in next major version /// Initializer that allows for custom endpoints. /// - Note: If you wish to use the default endpoints please refer to the convenience initializer: `init(appId: String)`. @@ -37,6 +37,7 @@ extension Embrace { /// - configBaseURL: Endpoint to fetch the remote config @available(*, deprecated, message: "Use `init(baseURL:configBaseURL)` instead.") @objc public init(baseURL: String, developmentBaseURL: String, configBaseURL: String) { + // TODO: Remove in next major version self.baseURL = baseURL self.configBaseURL = configBaseURL } diff --git a/Sources/EmbraceCore/Public/Metadata/MetadataRecordTmp.swift b/Sources/EmbraceCore/Public/Metadata/MetadataRecordTmp.swift index 75da1d8e..d47dd1af 100644 --- a/Sources/EmbraceCore/Public/Metadata/MetadataRecordTmp.swift +++ b/Sources/EmbraceCore/Public/Metadata/MetadataRecordTmp.swift @@ -80,7 +80,15 @@ extension MetadataRecordTmp { dateAttribute.name = "collectedAt" dateAttribute.attributeType = .dateAttributeType - entity.properties = [keyAttribute, valueAttribute, typeAttribute, lifespanAttribute, lifespanIdAttribute, dateAttribute] + entity.properties = [ + keyAttribute, + valueAttribute, + typeAttribute, + lifespanAttribute, + lifespanIdAttribute, + dateAttribute + ] + return entity } } diff --git a/Sources/EmbraceStorageInternal/EmbraceStorageError.swift b/Sources/EmbraceStorageInternal/EmbraceStorageError.swift index bc8c4ce0..febcf72c 100644 --- a/Sources/EmbraceStorageInternal/EmbraceStorageError.swift +++ b/Sources/EmbraceStorageInternal/EmbraceStorageError.swift @@ -7,7 +7,6 @@ import GRDB public enum EmbraceStorageError: Error, Equatable { case cannotUpsertSpan(spanName: String, message: String) - // TODO: Add missing errors in here } extension EmbraceStorageError: LocalizedError, CustomNSError { diff --git a/Sources/EmbraceStorageInternal/Queries/SpanRecord+SessionQuery.swift b/Sources/EmbraceStorageInternal/Queries/SpanRecord+SessionQuery.swift index 1fbdae08..a2035feb 100644 --- a/Sources/EmbraceStorageInternal/Queries/SpanRecord+SessionQuery.swift +++ b/Sources/EmbraceStorageInternal/Queries/SpanRecord+SessionQuery.swift @@ -28,7 +28,7 @@ extension SpanRecord { } else { return SpanRecord.filter( - matchingSessionId(session.id) || + matchingSessionId(session.id) || overlappingStart(startTime: session.startTime) || entirelyWithin(startTime: session.startTime, endTime: sessionEndTime) || overlappingEnd(endTime: sessionEndTime) || diff --git a/Sources/EmbraceUploadInternal/EmbraceUpload.swift b/Sources/EmbraceUploadInternal/EmbraceUpload.swift index 1ee6a1a4..bf230237 100644 --- a/Sources/EmbraceUploadInternal/EmbraceUpload.swift +++ b/Sources/EmbraceUploadInternal/EmbraceUpload.swift @@ -64,25 +64,28 @@ public class EmbraceUpload: EmbraceLogUploader { /// Attempts to upload all the available cached data. public func retryCachedData() { queue.async { [weak self] in - guard let self = self else { return } + guard let strongSelf = self else { + return + } + do { // in place mechanism to not retry sending cache data at the same time - guard !self.isRetryingCache else { + guard !strongSelf.isRetryingCache else { return } - self.isRetryingCache = true + strongSelf.isRetryingCache = true defer { // on finishing everything, allow to retry cache (i.e. reconnection) - self.isRetryingCache = false + strongSelf.isRetryingCache = false } // clear data from cache that shouldn't be retried as it's stale - self.clearCacheFromStaleData() + strongSelf.clearCacheFromStaleData() // get all the data cached first, is the only thing that could throw - let cachedObjects = try self.cache.fetchAllUploadData() + let cachedObjects = try strongSelf.cache.fetchAllUploadData() // create a sempahore to allow only to send two request at a time so we don't // get throttled by the backend on cases where cache has many failed requests. @@ -91,19 +94,19 @@ public class EmbraceUpload: EmbraceLogUploader { guard let type = EmbraceUploadType(rawValue: uploadData.type) else { continue } - self.semaphore.wait() + strongSelf.semaphore.wait() - self.reUploadData( + strongSelf.reUploadData( id: uploadData.id, data: uploadData.data, type: type, attemptCount: uploadData.attemptCount ) { - self.semaphore.signal() + strongSelf.semaphore.signal() } } } catch { - self.logger.debug("Error retrying cached upload data: \(error.localizedDescription)") + strongSelf.logger.debug("Error retrying cached upload data: \(error.localizedDescription)") } } } diff --git a/Sources/EmbraceUploadInternal/Options/EmbraceUpload+ExponentialBackoff.swift b/Sources/EmbraceUploadInternal/Options/EmbraceUpload+ExponentialBackoff.swift index 607db0e4..5d9b244f 100644 --- a/Sources/EmbraceUploadInternal/Options/EmbraceUpload+ExponentialBackoff.swift +++ b/Sources/EmbraceUploadInternal/Options/EmbraceUpload+ExponentialBackoff.swift @@ -14,7 +14,9 @@ public extension EmbraceUpload { maxDelay: Double = 32.0 ) { self.baseDelay = baseDelay - self.maxDelay = max(maxDelay, baseDelay) // prevent somebody from adding a baseDelay larger than the maxDelay + + // prevent somebody from adding a baseDelay larger than the maxDelay + self.maxDelay = max(maxDelay, baseDelay) } /// Calculates the exponential backoff delay based on the given `retryNumber`.