Skip to content

Commit

Permalink
Merge branch 'main' into append-crashInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
ArielDemarco committed Sep 5, 2024
2 parents 6652b9c + 365ed59 commit bd3c780
Show file tree
Hide file tree
Showing 28 changed files with 342 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/groue/GRDB.swift",
"state" : {
"revision" : "e83f3eb25ef4d5a36a13dbee98f8ac67e24e5c8f",
"version" : "6.16.0"
"revision" : "dd6b98ce04eda39aa22f066cd421c24d7236ea8a",
"version" : "6.29.1"
}
},
{
Expand Down
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/groue/GRDB.swift.git",
"state" : {
"revision" : "e83f3eb25ef4d5a36a13dbee98f8ac67e24e5c8f",
"version" : "6.16.0"
"revision" : "dd6b98ce04eda39aa22f066cd421c24d7236ea8a",
"version" : "6.29.1"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let package = Package(
),
.package(
url: "https://github.com/groue/GRDB.swift",
exact: "6.16.0"
exact: "6.29.1"
),
.package(
url: "https://github.com/realm/SwiftLint",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import Foundation
/// Object passed to the active crash reporter during setup
@objc public final class CrashReporterContext: NSObject {

public let appId: String
public let appId: String?
public let sdkVersion: String
public let filePathProvider: FilePathProvider
public let notificationCenter: NotificationCenter

public init(
appId: String,
appId: String?,
sdkVersion: String,
filePathProvider: FilePathProvider,
notificationCenter: NotificationCenter
Expand Down
6 changes: 5 additions & 1 deletion Sources/EmbraceCore/Capture/CaptureServices.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ final class CaptureServices {
services = CaptureServiceFactory.addRequiredServices(to: options.services.unique)

// create context for crash reporter
let partitionIdentifier = options.appId ?? EmbraceFileSystem.defaultPartitionId
context = CrashReporterContext(
appId: options.appId,
sdkVersion: EmbraceMeta.sdkVersion,
filePathProvider: EmbraceFilePathProvider(appId: options.appId, appGroupIdentifier: options.appGroupId),
filePathProvider: EmbraceFilePathProvider(
partitionId: partitionIdentifier,
appGroupId: options.appGroupId
),
notificationCenter: Embrace.notificationCenter
)
crashReporter = options.crashReporter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public final class URLSessionCaptureService: CaptureService, URLSessionTaskHandl

var injectTracingHeader: Bool {
// check remote config
guard Embrace.client?.config.isNetworkSpansForwardingEnabled == true else {
guard Embrace.client?.config?.isNetworkSpansForwardingEnabled == true else {
return false
}

Expand Down Expand Up @@ -136,13 +136,13 @@ struct SessionTaskResumeSwizzler: URLSessionSwizzler {
if #available(iOS 15.0, tvOS 15.0, macOS 12, watchOS 8, *) {
try swizzleInstanceMethod { originalImplementation -> BlockImplementationType in
return { [weak handler = self.handler] task in
let captured = handler?.create(task: task) ?? true
let handled = handler?.create(task: task) ?? true

// if the task wasn't captured by other swizzlers
// if the task was handled by this swizzler
// by the time resume was called it probably means
// it was an async/await task
// we set a proxy delegate to get a callback when the task finishes
if !captured, let handler = handler {
if handled, let handler = handler {
let originalDelegate = task.delegate
task.delegate = URLSessionDelegateProxy(originalDelegate: originalDelegate, handler: handler)
}
Expand Down
14 changes: 8 additions & 6 deletions Sources/EmbraceCore/Embrace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ To start the SDK you first need to configure it using an `Embrace.Options` insta
/// Returns the current `MetadataHandler` used to store resources and session properties.
public let metadata: MetadataHandler

let config: EmbraceConfig
let config: EmbraceConfig?
let storage: EmbraceStorage
let upload: EmbraceUpload?
let captureServices: CaptureServices
Expand Down Expand Up @@ -110,8 +110,7 @@ To start the SDK you first need to configure it using an `Embrace.Options` insta
return client
}

try options.validateAppId()
try options.validateGroupId()
try options.validate()

client = try Embrace(options: options)
if let client = client {
Expand Down Expand Up @@ -189,7 +188,7 @@ To start the SDK you first need to configure it using an `Embrace.Options` insta
return
}

guard config.isSDKEnabled else {
guard config == nil || config?.isSDKEnabled == true else {
Embrace.logger.warning("Embrace can't start when disabled!")
return
}
Expand Down Expand Up @@ -228,9 +227,10 @@ To start the SDK you first need to configure it using an `Embrace.Options` insta

/// Returns the current session identifier, if any.
@objc public func currentSessionId() -> String? {
guard config.isSDKEnabled else {
guard config == nil || config?.isSDKEnabled == true else {
return nil
}

return sessionController.currentSession?.id.toString
}

Expand All @@ -252,6 +252,8 @@ To start the SDK you first need to configure it using an `Embrace.Options` insta

/// Called everytime the remote config changes
@objc private func onConfigUpdated() {
Embrace.logger.limits = InternalLogLimits(config: config)
if let config = config {
Embrace.logger.limits = InternalLogLimits(config: config)
}
}
}
6 changes: 3 additions & 3 deletions Sources/EmbraceCore/ErrorManagement/EmbraceSetupError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public enum EmbraceSetupError: Error, Equatable {
case invalidAppGroupId(_ description: String)
case invalidThread(_ description: String)
case invalidOptions(_ description: String)
case failedStorageCreation(_ description: String)
case failedStorageCreation(partitionId: String, appGroupId: String?)
case unableToInitialize(_ description: String)
case initializationNotAllowed(_ description: String)
}
Expand Down Expand Up @@ -52,8 +52,8 @@ extension EmbraceSetupError: LocalizedError, CustomNSError {
return description
case .unableToInitialize(let description):
return description
case .failedStorageCreation(let description):
return description
case .failedStorageCreation(let partitionId, let appGroupId):
return "Failed to create Storage Directory. partitionId: '\(partitionId)' appGroupId: '\(appGroupId ?? "")'"
case .initializationNotAllowed(let description):
return description
}
Expand Down
27 changes: 21 additions & 6 deletions Sources/EmbraceCore/FileSystem/EmbraceFilePathProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,36 @@
import Foundation
import EmbraceCommonInternal

/// Class used to provide file paths to help when capturing data.
/// It can be beneficial to pass a filepath to an external instrumentation, like crash reports,
/// that can then be read from later.
class EmbraceFilePathProvider: FilePathProvider {
let appId: String
let appGroupIdentifier: String?
let partitionId: String
let appGroupId: String?

init(appId: String, appGroupIdentifier: String?) {
self.appId = appId
self.appGroupIdentifier = appGroupIdentifier
/// - Parameters:
/// - partitionId: The base directory this file path provider should use.
/// - appGroupId: An optional app group identifier to use if the provider should create file paths in the app group container.
init(partitionId: String, appGroupId: String?) {
self.partitionId = partitionId
self.appGroupId = appGroupId
}

/// Returns a file URL for the given scope and name.
/// - Parameters:
/// - scope: The directory scope to create this file URL in.
/// - name: The name of the file.
func fileURL(for scope: String, name: String) -> URL? {
return directoryURL(for: scope)?.appendingPathComponent(name)
}

/// Returns a directory URL for the given scope.
/// - Parameters:
/// - scope: The directory scope to create a reference to
func directoryURL(for scope: String) -> URL? {
let captureURL = EmbraceFileSystem.captureDirectoryURL(appId: appId, appGroupId: appGroupIdentifier)
let captureURL = EmbraceFileSystem.captureDirectoryURL(
partitionIdentifier: partitionId,
appGroupId: appGroupId)
return captureURL?.appendingPathComponent(scope)
}
}
43 changes: 30 additions & 13 deletions Sources/EmbraceCore/FileSystem/EmbraceFileSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public struct EmbraceFileSystem {
static let crashesDirectoryName = "crashes"
static let captureDirectoryName = "capture"

static let defaultPartitionId = "default"

/// Returns the path to the system directory that is the root directory for storage.
/// When `appGroupId` is present, will be a URL to an app group container
/// If not present, will be a path to the user's applicaton support directory.
Expand All @@ -37,7 +39,6 @@ public struct EmbraceFileSystem {
do {
return try FileManager.default.url(for: directory, in: .userDomainMask, appropriateFor: nil, create: true)
} catch {
// TODO: should we throw error and allow return type to be non-optional?
return nil
}
}
Expand All @@ -48,42 +49,58 @@ public struct EmbraceFileSystem {

/// Returns a subpath within the root directory of the Embrace SDK.
/// ```
/// io.embrace.data/<version>/<app-id>/<name>
/// io.embrace.data/<version>/<partition-id>/<name>
/// ```
static func directoryURL(name: String, appId: String, appGroupId: String? = nil) -> URL? {
/// - Parameters:
/// - name: The name of the subdirectory
/// - partitionIdentifier: The main paritition identifier to use
/// - appGroupId: The app group identifier if using an app group container.
static func directoryURL(name: String, partitionId: String, appGroupId: String? = nil) -> URL? {
guard let baseURL = systemDirectory(appGroupId: appGroupId) else {
return nil
}

let components = [rootDirectoryName, versionDirectoryName, appId, name]
let components = [rootDirectoryName, versionDirectoryName, partitionId, name]
return baseURL.appendingPathComponent(components.joined(separator: "/"))
}

/// Returns the subdirectory for the storage
/// ```
/// io.embrace.data/<version>/<app-id>/storage
/// io.embrace.data/<version>/<partition-id>/storage
/// ```
static func storageDirectoryURL(
appId: String,
partitionId: String,
appGroupId: String? = nil) -> URL? {
return directoryURL(name: storageDirectoryName, appId: appId, appGroupId: appGroupId)
return directoryURL(
name: storageDirectoryName,
partitionId: partitionId,
appGroupId: appGroupId
)
}

/// Returns the subdirectory for upload data
/// ```
/// io.embrace.data/<version>/<app-id>/uploads
/// io.embrace.data/<version>/<partition-id>/uploads
/// ```
static func uploadsDirectoryPath(
appId: String,
partitionIdentifier: String,
appGroupId: String? = nil) -> URL? {
return directoryURL(name: uploadsDirectoryName, appId: appId, appGroupId: appGroupId)
return directoryURL(
name: uploadsDirectoryName,
partitionId: partitionIdentifier,
appGroupId: appGroupId
)
}

/// Returns the subdirectory for data capture
/// ```
/// io.embrace.data/<version>/<app-id>/capture
/// io.embrace.data/<version>/<partition-id>/capture
/// ```
static func captureDirectoryURL(appId: String, appGroupId: String? = nil) -> URL? {
return directoryURL(name: captureDirectoryName, appId: appId, appGroupId: appGroupId)
static func captureDirectoryURL(partitionIdentifier: String, appGroupId: String? = nil) -> URL? {
return directoryURL(
name: captureDirectoryName,
partitionId: partitionIdentifier,
appGroupId: appGroupId
)
}
}
16 changes: 13 additions & 3 deletions Sources/EmbraceCore/Internal/Embrace+Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,25 @@ import EmbraceConfigInternal
import EmbraceCommonInternal

extension Embrace {

/// Creates `EmbraceConfig` object
static func createConfig(
options: Embrace.Options,
deviceId: String
) -> EmbraceConfig {
) -> EmbraceConfig? {

guard let appId = options.appId else {
return nil
}

guard let endpoints = options.endpoints else {
return nil
}

let configOptions = EmbraceConfig.Options(
apiBaseUrl: options.endpoints.configBaseURL,
apiBaseUrl: endpoints.configBaseURL,
queue: DispatchQueue(label: "com.embrace.config"),
appId: options.appId,
appId: appId,
deviceId: deviceId,
osVersion: EMBDevice.appVersion ?? "",
sdkVersion: EmbraceMeta.sdkVersion,
Expand Down
37 changes: 21 additions & 16 deletions Sources/EmbraceCore/Internal/Embrace+Setup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,43 @@ import EmbraceObjCUtilsInternal

extension Embrace {
static func createStorage(options: Embrace.Options) throws -> EmbraceStorage {

let partitionId = options.appId ?? EmbraceFileSystem.defaultPartitionId
if let storageUrl = EmbraceFileSystem.storageDirectoryURL(
appId: options.appId,
partitionId: partitionId,
appGroupId: options.appGroupId
) {
do {
let storageOptions = EmbraceStorage.Options(baseUrl: storageUrl, fileName: "db.sqlite")
let storage = try EmbraceStorage(options: storageOptions, logger: Embrace.logger)
try storage.performMigration()
return storage
} catch {
throw EmbraceSetupError.failedStorageCreation("Failed to create EmbraceStorage")
}
let storageOptions = EmbraceStorage.Options(baseUrl: storageUrl, fileName: "db.sqlite")
let storage = try EmbraceStorage(options: storageOptions, logger: Embrace.logger)
try storage.performMigration()
return storage
} else {
throw EmbraceSetupError.failedStorageCreation("Failed to create Storage Directory with appId: '\(options.appId)' appGroupId: '\(options.appGroupId ?? "")'")
throw EmbraceSetupError.failedStorageCreation(partitionId: partitionId, appGroupId: options.appGroupId)
}
}

static func createUpload(options: Embrace.Options, deviceId: String) -> EmbraceUpload? {
guard let appId = options.appId else {
return nil
}

// endpoints
let baseUrl = EMBDevice.isDebuggerAttached ?
options.endpoints.developmentBaseURL : options.endpoints.baseURL
guard let endpoints = options.endpoints else {
return nil
}

let baseUrl = EMBDevice.isDebuggerAttached ? endpoints.developmentBaseURL : endpoints.baseURL
guard let spansURL = URL.spansEndpoint(basePath: baseUrl),
let logsURL = URL.logsEndpoint(basePath: baseUrl) else {
Embrace.logger.error("Failed to initialize endpoints!")
return nil
}

let endpoints = EmbraceUpload.EndpointOptions(spansURL: spansURL, logsURL: logsURL)
let uploadEndpoints = EmbraceUpload.EndpointOptions(spansURL: spansURL, logsURL: logsURL)

// cache
guard let cacheUrl = EmbraceFileSystem.uploadsDirectoryPath(
appId: options.appId,
partitionIdentifier: appId,
appGroupId: options.appGroupId
),
let cache = EmbraceUpload.CacheOptions(cacheBaseUrl: cacheUrl)
Expand All @@ -53,13 +58,13 @@ extension Embrace {

// metadata
let metadata = EmbraceUpload.MetadataOptions(
apiKey: options.appId,
apiKey: appId,
userAgent: EmbraceMeta.userAgent,
deviceId: deviceId.filter { c in c.isHexDigit }
)

do {
let options = EmbraceUpload.Options(endpoints: endpoints, cache: cache, metadata: metadata)
let options = EmbraceUpload.Options(endpoints: uploadEndpoints, cache: cache, metadata: metadata)
let queue = DispatchQueue(label: "com.embrace.upload", attributes: .concurrent)

return try EmbraceUpload(options: options, logger: Embrace.logger, queue: queue)
Expand Down
Loading

0 comments on commit bd3c780

Please sign in to comment.