123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2019-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- import Foundation
- import CocoaLumberjackSwift
- import Sentry
- @objc class SentryClient: NSObject {
-
- private static let sentryNotEnabled = "SENTRY_NOT_ENABLED"
-
- @objc override init() {
- super.init()
- }
-
- /**
- Create Sentry and start crash handler.
-
- - Parameters:
- - rootViewController: Parent view controller
- */
- @objc func start(rootViewController: UIViewController?) {
- guard SentryClient.isEnabled(),
- let sentryDsn = BundleUtil.object(forInfoDictionaryKey: "SentryClientDsn") as? String else {
-
- return
- }
-
- do {
- let options = try Sentry.Options(dict: ["dsn": sentryDsn])
- options.beforeSend = { event in
- if let appDevice = event.context?["app"]?["device_app_hash"] as? String {
- // Save anonymous app device, it will be displayed under Settings - Advanced
- UserSettings.shared()?.sentryAppDevice = appDevice
- // Send app device hash to count users per event on sentry ui
- let user = User(userId: appDevice)
- event.user = user
- }
- if event.exceptions?.first?.value != nil {
- event.exceptions?.first?.value = self.redact(exceptionDescription: event.exceptions!.first!.value)
- }
-
- var send: Bool = false
-
- let dispatch = DispatchGroup()
- dispatch.enter()
- DispatchQueue.main.async {
- let confirm = UIAlertController(title: String(format: BundleUtil.localizedString(forKey: "sentry_crash_send_title"), "Threema"), message: BundleUtil.localizedString(forKey: "sentry_crash_send_description"), preferredStyle: .alert)
- confirm.addTextField { (textField) in
- textField.placeholder = BundleUtil.localizedString(forKey: "sentry_crash_comment_placeholder")
- }
- confirm.addAction(UIAlertAction(title: BundleUtil.localizedString(forKey: "sentry_crash_send_yes"), style: .default, handler: { (a) -> Void in
- if let textField = confirm.textFields?.first {
- event.message = textField.text ?? ""
- }
- send = true
- dispatch.leave()
- }))
- confirm.addAction(UIAlertAction(title: BundleUtil.localizedString(forKey: "sentry_crash_send_no"), style: .cancel, handler: { (a) -> Void in
- dispatch.leave()
- }))
- if let vc = rootViewController {
- DispatchQueue.main.async {
- vc.present(confirm, animated: true, completion: nil)
- }
- }
- else {
- dispatch.leave()
- }
- }
-
- dispatch.wait()
-
- if send {
- return event
- }
- return nil
- }
- SentrySDK.start(options: options)
-
- } catch {
- DDLogError("Could not start Sentry!")
- }
- }
-
- private func redact(exceptionDescription : String) -> String {
- let keys = ["encryptionKey", "k:", "password", "blobId", "blobThumbnailId", "\"k\""]
-
- var linesArray = exceptionDescription.linesArray
- for i in 0..<linesArray.count {
- for k in keys {
- if linesArray[i].contains(k) {
- let range = linesArray[i].range(of: k)!
- linesArray[i] = linesArray[i][..<range.lowerBound] + "***redacted***"
- }
- }
- }
- return linesArray.joined(separator: "\n")
- }
-
- /**
- Is Sentry enabled or not dependent on is file "SENTRY_NOT_ENABLED" exists in App documents directory. When the App crashes on start because of Sentry start handler, can the file adding per iTunes to disable it.
-
- - Returns: true -> start Sentry crash handler
- */
- private static func isEnabled() -> Bool {
- return !FileUtility.isExists(fileUrl: FileUtility.appDocumentsDirectory?.appendingPathComponent(sentryNotEnabled))
- }
- }
|