-
Notifications
You must be signed in to change notification settings - Fork 2
/
CaptureServices.swift
106 lines (88 loc) · 3.1 KB
/
CaptureServices.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//
// Copyright © 2023 Embrace Mobile, Inc. All rights reserved.
//
import Foundation
import EmbraceCaptureService
import EmbraceCommon
import EmbraceStorage
import EmbraceUpload
final class CaptureServices {
@ThreadSafe
var services: [CaptureService]
var context: CrashReporterContext
weak var crashReporter: CrashReporter?
init(options: Embrace.Options, storage: EmbraceStorage?, upload: EmbraceUpload?) throws {
// add required capture services
// adn remove duplicates
services = CaptureServiceFactory.addRequiredServices(to: options.services.unique)
// create context for crash reporter
context = CrashReporterContext(
appId: options.appId,
sdkVersion: EmbraceMeta.sdkVersion,
filePathProvider: EmbraceFilePathProvider(appId: options.appId, appGroupIdentifier: options.appGroupId),
notificationCenter: Embrace.notificationCenter
)
crashReporter = options.crashReporter
// upload action for crash reports
if let crashReporter = options.crashReporter {
crashReporter.onNewReport = { [weak crashReporter, weak storage, weak upload] report in
UnsentDataHandler.sendCrashLog(
report: report,
reporter: crashReporter,
session: nil,
storage: storage,
upload: upload,
otel: Embrace.client
)
}
}
// pass storage reference to capture services
// that generate resources
for service in services {
if let resourceService = service as? ResourceCaptureService {
resourceService.handler = storage
}
}
// subscribe to session start notification
// to update the crash reporter with the new session id
NotificationCenter.default.addObserver(
self,
selector: #selector(onSessionStart),
name: Notification.Name.embraceSessionDidStart,
object: nil
)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
func start() {
crashReporter?.install(context: context, logger: Embrace.logger)
for service in services {
service.install(otel: Embrace.client, logger: Embrace.logger)
service.start()
}
}
func stop() {
for service in services {
service.stop()
}
}
@objc func onSessionStart(notification: Notification) {
if let session = notification.object as? SessionRecord {
crashReporter?.currentSessionId = session.id.toString
}
}
}
private extension Array where Element == CaptureService {
var unique: [CaptureService] {
var unique = [String: CaptureService]()
for service in self {
let typeName = String(describing: type(of: service))
guard unique[typeName] == nil else {
continue
}
unique[typeName] = service
}
return Array(unique.values)
}
}