mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 01:08:39 +09:00
Dactyloidae iOS initial commit
This commit is contained in:
parent
daa6179d22
commit
7154a0497e
2123 changed files with 197052 additions and 0 deletions
163
mobile/ios/Shared/SentryIntegration.swift
Normal file
163
mobile/ios/Shared/SentryIntegration.swift
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import Foundation
|
||||
import Sentry
|
||||
|
||||
public enum SentryTag: String {
|
||||
case swiftData = "SwiftData"
|
||||
case browserDB = "BrowserDB"
|
||||
case notificationService = "NotificationService"
|
||||
case unifiedTelemetry = "UnifiedTelemetry"
|
||||
case general = "General"
|
||||
case tabManager = "TabManager"
|
||||
case bookmarks = "Bookmarks"
|
||||
}
|
||||
|
||||
public class Sentry {
|
||||
public static let shared = Sentry()
|
||||
|
||||
public static var crashedLastLaunch: Bool {
|
||||
return Client.shared?.crashedLastLaunch() ?? false
|
||||
}
|
||||
|
||||
private let SentryDSNKey = "SentryDSN"
|
||||
private let SentryDeviceAppHashKey = "SentryDeviceAppHash"
|
||||
private let DefaultDeviceAppHash = "0000000000000000000000000000000000000000"
|
||||
private let DeviceAppHashLength = UInt(20)
|
||||
|
||||
private var enabled = false
|
||||
|
||||
private var attributes: [String: Any] = [:]
|
||||
|
||||
public func setup(sendUsageData: Bool) {
|
||||
assert(!enabled, "Sentry.setup() should only be called once")
|
||||
|
||||
if DeviceInfo.isSimulator() {
|
||||
Logger.browserLogger.debug("Not enabling Sentry; Running in Simulator")
|
||||
return
|
||||
}
|
||||
|
||||
if !sendUsageData {
|
||||
Logger.browserLogger.debug("Not enabling Sentry; Not enabled by user choice")
|
||||
return
|
||||
}
|
||||
|
||||
guard let dsn = Bundle.main.object(forInfoDictionaryKey: SentryDSNKey) as? String, !dsn.isEmpty else {
|
||||
Logger.browserLogger.debug("Not enabling Sentry; Not configured in Info.plist")
|
||||
return
|
||||
}
|
||||
|
||||
Logger.browserLogger.debug("Enabling Sentry crash handler")
|
||||
|
||||
do {
|
||||
Client.shared = try Client(dsn: dsn)
|
||||
try Client.shared?.startCrashHandler()
|
||||
enabled = true
|
||||
|
||||
// If we have not already for this install, generate a completely random identifier
|
||||
// for this device. It is stored in the app group so that the same value will
|
||||
// be used for both the main application and the app extensions.
|
||||
if let defaults = UserDefaults(suiteName: AppInfo.sharedContainerIdentifier), defaults.string(forKey: SentryDeviceAppHashKey) == nil {
|
||||
defaults.set(Bytes.generateRandomBytes(DeviceAppHashLength).hexEncodedString, forKey: SentryDeviceAppHashKey)
|
||||
defaults.synchronize()
|
||||
}
|
||||
|
||||
// For all outgoing reports, override the default device identifier with our own random
|
||||
// version. Default to a blank (zero) identifier in case of errors.
|
||||
Client.shared?.beforeSerializeEvent = { event in
|
||||
let deviceAppHash = UserDefaults(suiteName: AppInfo.sharedContainerIdentifier)?.string(forKey: self.SentryDeviceAppHashKey)
|
||||
event.context?.appContext?["device_app_hash"] = deviceAppHash ?? self.DefaultDeviceAppHash
|
||||
|
||||
var attributes = event.extra ?? [:]
|
||||
attributes.merge(with: self.attributes)
|
||||
event.extra = attributes
|
||||
}
|
||||
} catch let error {
|
||||
Logger.browserLogger.error("Failed to initialize Sentry: \(error)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public func crash() {
|
||||
Client.shared?.crash()
|
||||
}
|
||||
|
||||
/*
|
||||
This is the behaviour we want for Sentry logging
|
||||
.info .error .severe
|
||||
Debug y y y
|
||||
Beta y y y
|
||||
Relase n n y
|
||||
*/
|
||||
private func shouldNotSendEventFor(_ severity: SentrySeverity) -> Bool {
|
||||
return !enabled || (AppConstants.BuildChannel == .release && severity != .fatal)
|
||||
}
|
||||
|
||||
private func makeEvent(message: String, tag: String, severity: SentrySeverity, extra: [String: Any]?) -> Event {
|
||||
let event = Event(level: severity)
|
||||
event.message = message
|
||||
event.tags = ["tag": tag]
|
||||
if let extra = extra {
|
||||
event.extra = extra
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
public func send(message: String, tag: SentryTag = .general, severity: SentrySeverity = .info, extra: [String: Any]? = nil, description: String? = nil, completion: SentryRequestFinished? = nil) {
|
||||
// Build the dictionary
|
||||
var extraEvents: [String: Any] = [:]
|
||||
if let paramEvents = extra {
|
||||
extraEvents.merge(with: paramEvents)
|
||||
}
|
||||
if let extraString = description {
|
||||
extraEvents.merge(with: ["errorDescription": extraString])
|
||||
}
|
||||
printMessage(message: message, extra: extraEvents)
|
||||
|
||||
// Only report fatal errors on release
|
||||
if shouldNotSendEventFor(severity) {
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
|
||||
let event = makeEvent(message: message, tag: tag.rawValue, severity: severity, extra: extraEvents)
|
||||
Client.shared?.send(event: event, completion: completion)
|
||||
}
|
||||
|
||||
public func sendWithStacktrace(message: String, tag: SentryTag = .general, severity: SentrySeverity = .info, extra: [String: Any]? = nil, description: String? = nil, completion: SentryRequestFinished? = nil) {
|
||||
var extraEvents: [String: Any] = [:]
|
||||
if let paramEvents = extra {
|
||||
extraEvents.merge(with: paramEvents)
|
||||
}
|
||||
if let extraString = description {
|
||||
extraEvents.merge(with: ["errorDescription": extraString])
|
||||
}
|
||||
printMessage(message: message, extra: extraEvents)
|
||||
|
||||
// Do not send messages to Sentry if disabled OR if we are not on beta and the severity isnt severe
|
||||
if shouldNotSendEventFor(severity) {
|
||||
completion?(nil)
|
||||
return
|
||||
}
|
||||
Client.shared?.snapshotStacktrace {
|
||||
let event = self.makeEvent(message: message, tag: tag.rawValue, severity: severity, extra: extraEvents)
|
||||
Client.shared?.appendStacktrace(to: event)
|
||||
event.debugMeta = nil
|
||||
Client.shared?.send(event: event, completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
public func addAttributes(_ attributes: [String: Any]) {
|
||||
self.attributes.merge(with: attributes)
|
||||
}
|
||||
|
||||
private func printMessage(message: String, extra: [String: Any]? = nil) {
|
||||
let string = extra?.reduce("") { (result: String, arg1) in
|
||||
let (key, value) = arg1
|
||||
return "\(result), \(key): \(value)"
|
||||
}
|
||||
Logger.browserLogger.debug("Sentry: \(message) \(string ??? "")")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue