Various logging fixes (#164)

Various logging fixes:
* imported the ObjCWrapper and updated the MXLogger. Also added back support for app containers
* updated MXLog.swift from El and fixed/improved its logging format
* updated most app log strings
* Remove unnecessary swiftlint rule
* Various tweaks following code review
* Added back type annoation on MXLogger logFiles method
* Fix generated Swift-ObjC header name
This commit is contained in:
Stefan Ceriu
2022-08-30 18:05:21 +03:00
committed by GitHub
parent c92e6c2092
commit 39be67cec6
24 changed files with 288 additions and 102 deletions
+10
View File
@@ -68,6 +68,7 @@
297CD0A27C87B0C50FF192EE /* RoomTimelineViewFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEE384418EB1FEDFA62C9CD0 /* RoomTimelineViewFactoryProtocol.swift */; }; 297CD0A27C87B0C50FF192EE /* RoomTimelineViewFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEE384418EB1FEDFA62C9CD0 /* RoomTimelineViewFactoryProtocol.swift */; };
29AEE68A604940180AB9EBFF /* MockRoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDAC8895AB2B77B47703AE /* MockRoomSummary.swift */; }; 29AEE68A604940180AB9EBFF /* MockRoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDAC8895AB2B77B47703AE /* MockRoomSummary.swift */; };
29EE1791E0AFA1ABB7F23D2F /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 1BCD21310B997A6837B854D6 /* GZIP */; }; 29EE1791E0AFA1ABB7F23D2F /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 1BCD21310B997A6837B854D6 /* GZIP */; };
2A90D9F91A836E30B7D78838 /* MXLogObjcWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 54E438DBCBDC7A41B95DDDD9 /* MXLogObjcWrapper.m */; };
2BA59D0AEFB4B82A2EC2A326 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 04C28663564E008DB32B5972 /* Introspect */; }; 2BA59D0AEFB4B82A2EC2A326 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 04C28663564E008DB32B5972 /* Introspect */; };
2BAA5B222856068158D0B3C6 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = B1E8B697DF78FE7F61FC6CA4 /* MatrixRustSDK */; }; 2BAA5B222856068158D0B3C6 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = B1E8B697DF78FE7F61FC6CA4 /* MatrixRustSDK */; };
2C0CE61E5DC177938618E0B1 /* RootRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90733775209F4D4D366A268F /* RootRouterType.swift */; }; 2C0CE61E5DC177938618E0B1 /* RootRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90733775209F4D4D366A268F /* RootRouterType.swift */; };
@@ -348,6 +349,7 @@
04E1273CC3BC3E471AF87BE5 /* UserIndicatorQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorQueueTests.swift; sourceTree = "<group>"; }; 04E1273CC3BC3E471AF87BE5 /* UserIndicatorQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorQueueTests.swift; sourceTree = "<group>"; };
054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionUITests.swift; sourceTree = "<group>"; }; 054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionUITests.swift; sourceTree = "<group>"; };
057B747CF045D3C6C30EAB2C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 057B747CF045D3C6C30EAB2C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
0776771332259AB1C9661430 /* MXLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXLog.h; sourceTree = "<group>"; };
086B997409328F091EBA43CE /* RoomScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenUITests.swift; sourceTree = "<group>"; }; 086B997409328F091EBA43CE /* RoomScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenUITests.swift; sourceTree = "<group>"; };
08F64963396A6A23538EFCEC /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = is; path = is.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 08F64963396A6A23538EFCEC /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = is; path = is.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderAvatarImage.swift; sourceTree = "<group>"; }; 0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderAvatarImage.swift; sourceTree = "<group>"; };
@@ -425,6 +427,7 @@
3A4427F9E0571B4E6E048A2B /* KeychainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = "<group>"; }; 3A4427F9E0571B4E6E048A2B /* KeychainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = "<group>"; };
3ACBDC1D28EFB7789EB467E0 /* MockRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomProxy.swift; sourceTree = "<group>"; }; 3ACBDC1D28EFB7789EB467E0 /* MockRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomProxy.swift; sourceTree = "<group>"; };
3B5B535DA49C54523FF7A412 /* nn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nn; path = nn.lproj/Localizable.strings; sourceTree = "<group>"; }; 3B5B535DA49C54523FF7A412 /* nn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nn; path = nn.lproj/Localizable.strings; sourceTree = "<group>"; };
3BFEC43A1A0769F1EAC62873 /* MXLogObjcWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXLogObjcWrapper.h; sourceTree = "<group>"; };
3CDF9E55650D6035D6536538 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "nb-NO"; path = "nb-NO.lproj/Localizable.stringsdict"; sourceTree = "<group>"; }; 3CDF9E55650D6035D6536538 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "nb-NO"; path = "nb-NO.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
3D487C1185D658F8B15B8F55 /* SettingsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModelTests.swift; sourceTree = "<group>"; }; 3D487C1185D658F8B15B8F55 /* SettingsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModelTests.swift; sourceTree = "<group>"; };
3D4DD336905C72F95EAF34B7 /* ElementX-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ElementX-Bridging-Header.h"; sourceTree = "<group>"; }; 3D4DD336905C72F95EAF34B7 /* ElementX-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ElementX-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -477,6 +480,7 @@
529513218340CC8419273165 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; }; 529513218340CC8419273165 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
534A5C8FCDE2CBC50266B9F2 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = gl; path = gl.lproj/Localizable.stringsdict; sourceTree = "<group>"; }; 534A5C8FCDE2CBC50266B9F2 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = gl; path = gl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; }; 536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
54E438DBCBDC7A41B95DDDD9 /* MXLogObjcWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXLogObjcWrapper.m; sourceTree = "<group>"; };
55BC11560C8A2598964FFA4C /* bs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bs; path = bs.lproj/Localizable.strings; sourceTree = "<group>"; }; 55BC11560C8A2598964FFA4C /* bs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bs; path = bs.lproj/Localizable.strings; sourceTree = "<group>"; };
55D7187F6B0C0A651AC3DFFA /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = in; path = in.lproj/Localizable.strings; sourceTree = "<group>"; }; 55D7187F6B0C0A651AC3DFFA /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = in; path = in.lproj/Localizable.strings; sourceTree = "<group>"; };
56F01DD1BBD4450E18115916 /* LabelledActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelledActivityIndicatorView.swift; sourceTree = "<group>"; }; 56F01DD1BBD4450E18115916 /* LabelledActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelledActivityIndicatorView.swift; sourceTree = "<group>"; };
@@ -821,9 +825,12 @@
06501F0E978B2D5C92771DC7 /* Logging */ = { 06501F0E978B2D5C92771DC7 /* Logging */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0776771332259AB1C9661430 /* MXLog.h */,
111B698739E3410E2CDB7144 /* MXLog.swift */, 111B698739E3410E2CDB7144 /* MXLog.swift */,
5872785B9C7934940146BFBA /* MXLogger.h */, 5872785B9C7934940146BFBA /* MXLogger.h */,
EF188681D6B6068CFAEAFC3F /* MXLogger.m */, EF188681D6B6068CFAEAFC3F /* MXLogger.m */,
3BFEC43A1A0769F1EAC62873 /* MXLogObjcWrapper.h */,
54E438DBCBDC7A41B95DDDD9 /* MXLogObjcWrapper.m */,
); );
path = Logging; path = Logging;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -2180,6 +2187,7 @@
49E9B99CB6A275C7744351F0 /* LoginViewModel.swift in Sources */, 49E9B99CB6A275C7744351F0 /* LoginViewModel.swift in Sources */,
2F30EFEB7BD39242D1AD96F3 /* LoginViewModelProtocol.swift in Sources */, 2F30EFEB7BD39242D1AD96F3 /* LoginViewModelProtocol.swift in Sources */,
B94368839BDB69172E28E245 /* MXLog.swift in Sources */, B94368839BDB69172E28E245 /* MXLog.swift in Sources */,
2A90D9F91A836E30B7D78838 /* MXLogObjcWrapper.m in Sources */,
BCC3EDB7AD0902797CB4BBC2 /* MXLogger.m in Sources */, BCC3EDB7AD0902797CB4BBC2 /* MXLogger.m in Sources */,
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */, 67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */,
EA1E7949533E19C6D862680A /* MediaProvider.swift in Sources */, EA1E7949533E19C6D862680A /* MediaProvider.swift in Sources */,
@@ -2565,6 +2573,7 @@
PRODUCT_NAME = ElementX; PRODUCT_NAME = ElementX;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h";
SWIFT_OBJC_INTERFACE_HEADER_NAME = "GeneratedInterface-Swift.h";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Release; name = Release;
@@ -2588,6 +2597,7 @@
PRODUCT_NAME = ElementX; PRODUCT_NAME = ElementX;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h";
SWIFT_OBJC_INTERFACE_HEADER_NAME = "GeneratedInterface-Swift.h";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
}; };
name = Debug; name = Debug;
+2 -2
View File
@@ -327,7 +327,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
} }
private func processScreenshotDetection(image: UIImage?, error: Error?) { private func processScreenshotDetection(image: UIImage?, error: Error?) {
MXLog.debug("[AppCoordinator] processScreenshotDetection: \(String(describing: image)), error: \(String(describing: error))") MXLog.debug("Detected screenshot: \(String(describing: image)), error: \(String(describing: error))")
let alert = UIAlertController(title: ElementL10n.screenshotDetectedTitle, let alert = UIAlertController(title: ElementL10n.screenshotDetectedTitle,
message: ElementL10n.screenshotDetectedMessage, message: ElementL10n.screenshotDetectedMessage,
@@ -363,7 +363,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
@objc @objc
private func dismissBugReportScreen() { private func dismissBugReportScreen() {
MXLog.debug("[AppCoorrdinator] dismissBugReportScreen") MXLog.debug("dismissBugReportScreen")
guard let bugReportCoordinator = childCoordinators.first(where: { $0 is BugReportCoordinator }) else { guard let bugReportCoordinator = childCoordinators.first(where: { $0 is BugReportCoordinator }) else {
return return
@@ -20,9 +20,7 @@ import Foundation
public extension DTHTMLElement { public extension DTHTMLElement {
/// Sanitize the element using the given parameters. /// Sanitize the element using the given parameters.
/// - Parameters: /// - Parameters:
/// - allowedHTMLTags: An array of tags that are allowed. All other tags will be removed.
/// - font: The default font to use when resetting the content of any unsupported tags. /// - font: The default font to use when resetting the content of any unsupported tags.
/// - imageHandler: An optional image handler to be run on `img` tags (if allowed) to update the `src` attribute.
@objc func sanitize(font: UIFont) { @objc func sanitize(font: UIFont) {
if let name = name, !Self.allowedHTMLTags.contains(name) { if let name = name, !Self.allowedHTMLTags.contains(name) {
// This is an unsupported tag. // This is an unsupported tag.
+49
View File
@@ -0,0 +1,49 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "MXLogObjcWrapper.h"
#define MXLogVerbose(message, ...) { \
[MXLogObjcWrapper logVerbose:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogDebug(message, ...) { \
[MXLogObjcWrapper logDebug:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogInfo(message, ...) { \
[MXLogObjcWrapper logInfo:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogWarning(message, ...) { \
[MXLogObjcWrapper logWarning:[NSString stringWithFormat: message, ##__VA_ARGS__] file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__]; \
}
#define MXLogError(message) { \
[MXLogObjcWrapper logError:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:nil]; \
}
#define MXLogErrorDetails(message, details) { \
[MXLogObjcWrapper logError:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:details]; \
}
#define MXLogFailure(message) { \
[MXLogObjcWrapper logFailure:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:nil]; \
}
#define MXLogFailureDetails(message, details) { \
[MXLogObjcWrapper logFailure:message file:@__FILE__ function:[NSString stringWithFormat:@"%s", __FUNCTION__] line:__LINE__ context:details]; \
}
+55 -29
View File
@@ -67,8 +67,8 @@ private var logger: SwiftyBeaver.Type = {
} }
public static func verbose(_ message: @autoclosure () -> Any, public static func verbose(_ message: @autoclosure () -> Any,
_ file: String = #file, file: String = #file,
_ function: String = #function, function: String = #function,
line: Int = #line, line: Int = #line,
context: Any? = nil) { context: Any? = nil) {
logger.verbose(message(), file, function, line: line, context: context) logger.verbose(message(), file, function, line: line, context: context)
@@ -80,8 +80,8 @@ private var logger: SwiftyBeaver.Type = {
} }
public static func debug(_ message: @autoclosure () -> Any, public static func debug(_ message: @autoclosure () -> Any,
_ file: String = #file, file: String = #file,
_ function: String = #function, function: String = #function,
line: Int = #line, line: Int = #line,
context: Any? = nil) { context: Any? = nil) {
logger.debug(message(), file, function, line: line, context: context) logger.debug(message(), file, function, line: line, context: context)
@@ -93,8 +93,8 @@ private var logger: SwiftyBeaver.Type = {
} }
public static func info(_ message: @autoclosure () -> Any, public static func info(_ message: @autoclosure () -> Any,
_ file: String = #file, file: String = #file,
_ function: String = #function, function: String = #function,
line: Int = #line, line: Int = #line,
context: Any? = nil) { context: Any? = nil) {
logger.info(message(), file, function, line: line, context: context) logger.info(message(), file, function, line: line, context: context)
@@ -106,8 +106,8 @@ private var logger: SwiftyBeaver.Type = {
} }
public static func warning(_ message: @autoclosure () -> Any, public static func warning(_ message: @autoclosure () -> Any,
_ file: String = #file, file: String = #file,
_ function: String = #function, function: String = #function,
line: Int = #line, line: Int = #line,
context: Any? = nil) { context: Any? = nil) {
logger.warning(message(), file, function, line: line, context: context) logger.warning(message(), file, function, line: line, context: context)
@@ -118,32 +118,57 @@ private var logger: SwiftyBeaver.Type = {
logger.warning(message, file, function, line: line) logger.warning(message, file, function, line: line)
} }
public static func error(_ message: @autoclosure () -> Any, /// Log error with additional details
_ file: String = #file, ///
_ function: String = #function, /// - Parameters:
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
/// - context: Additional context-dependent details about the issue
public static func error(_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line, line: Int = #line,
context: Any? = nil) { context: Any? = nil) {
logger.error(message(), file, function, line: line, context: context) logger.error(message, file, function, line: line, context: context)
} }
@available(swift, obsoleted: 5.4) @available(swift, obsoleted: 5.4)
@objc public static func logError(_ message: String, file: String, function: String, line: Int) { @objc public static func logError(_ message: String,
logger.error(message, file, function, line: line) file: String,
function: String,
line: Int,
context: Any? = nil) {
logger.error(message, file, function, line: line, context: context)
} }
public static func failure(_ message: @autoclosure () -> Any, /// Log failure with additional details
_ file: String = #file, ///
_ function: String = #function, /// A failure is any type of programming error which should never occur in production. In `DEBUG` configuration
/// any failure will raise `assertionFailure`
///
/// - Parameters:
/// - message: Description of the error without any variables (this is to improve error aggregations by type)
/// - context: Additional context-dependent details about the issue
public static func failure(_ message: String,
file: String = #file,
function: String = #function,
line: Int = #line, line: Int = #line,
context: Any? = nil) { context: Any? = nil) {
logger.error(message(), file, function, line: line, context: context) logger.error(message, file, function, line: line, context: context)
assertionFailure("\(message())") #if DEBUG
assertionFailure("\(message)")
#endif
} }
@available(swift, obsoleted: 5.4) @available(swift, obsoleted: 5.4)
@objc public static func logFailure(_ message: String, file: String, function: String, line: Int) { @objc public static func logFailure(_ message: String,
logger.error(message, file, function, line: line) file: String,
assertionFailure(message) function: String,
line: Int,
context: Any? = nil) {
logger.error(message, file, function, line: line, context: context)
#if DEBUG
assertionFailure("\(message)")
#endif
} }
// MARK: - Private // MARK: - Private
@@ -152,24 +177,27 @@ private var logger: SwiftyBeaver.Type = {
if let subLogName = configuration.subLogName { if let subLogName = configuration.subLogName {
MXLogger.setSubLogName(subLogName) MXLogger.setSubLogName(subLogName)
} }
MXLogger.redirectNSLog(toFiles: configuration.redirectLogsToFiles, MXLogger.redirectNSLog(toFiles: configuration.redirectLogsToFiles,
numberOfFiles: configuration.maxLogFilesCount, numberOfFiles: configuration.maxLogFilesCount,
sizeLimit: configuration.logFilesSizeLimit) sizeLimit: configuration.logFilesSizeLimit)
guard configuration.logLevel != .none else { guard configuration.logLevel != .none else {
logger.removeAllDestinations()
return return
} }
logger.removeAllDestinations()
let consoleDestination = ConsoleDestination() let consoleDestination = ConsoleDestination()
consoleDestination.useNSLog = true consoleDestination.useNSLog = true
consoleDestination.asynchronously = false consoleDestination.asynchronously = false
consoleDestination.format = "$M" consoleDestination.format = "$C$N.$F:$l $M $X$c" // See https://docs.swiftybeaver.com/article/20-custom-format
consoleDestination.levelColor.verbose = "" consoleDestination.levelColor.verbose = ""
consoleDestination.levelColor.debug = "" consoleDestination.levelColor.debug = ""
consoleDestination.levelColor.info = "" consoleDestination.levelColor.info = ""
consoleDestination.levelColor.warning = "⚠️" consoleDestination.levelColor.warning = "⚠️ "
consoleDestination.levelColor.error = "🚨" consoleDestination.levelColor.error = "🚨 "
switch configuration.logLevel { switch configuration.logLevel {
case .verbose: case .verbose:
@@ -185,8 +213,6 @@ private var logger: SwiftyBeaver.Type = {
case .none: case .none:
break break
} }
logger.removeAllDestinations()
logger.addDestination(consoleDestination) logger.addDestination(consoleDestination)
} }
} }
@@ -0,0 +1,40 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
An `MXLog` Objective-C wrapper used to allow calling Swift methods from the variadic macros defined in `MXLog.h`
*/
@interface MXLogObjcWrapper : NSObject
+ (void)logVerbose:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logDebug:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logInfo:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logWarning:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line;
+ (void)logError:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(nullable id)context;
+ (void)logFailure:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(nullable id)context;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,52 @@
//
// Copyright 2021 The Matrix.org Foundation C.I.C
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "MXLogObjcWrapper.h"
#import "GeneratedInterface-Swift.h"
@implementation MXLogObjcWrapper
+ (void)logVerbose:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logVerbose:message file:file function:function line:line];
}
+ (void)logDebug:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logDebug:message file:file function:function line:line];
}
+ (void)logInfo:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logInfo:message file:file function:function line:line];
}
+ (void)logWarning:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line
{
[MXLog logWarning:message file:file function:function line:line];
}
+ (void)logError:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(id)context
{
[MXLog logError:message file:file function:function line:line context:context];
}
+ (void)logFailure:(NSString *)message file:(NSString *)file function:(NSString *)function line:(NSUInteger)line context:(id)context
{
[MXLog logFailure:message file:file function:function line:line context:context];
}
@end
+29 -29
View File
@@ -16,7 +16,8 @@
*/ */
#import "MXLogger.h" #import "MXLogger.h"
#import <UIKit/UIKit.h> #import "MXLog.h"
#import "GeneratedInterface-Swift.h"
// stderr so it can be restored // stderr so it can be restored
int stderrSave = 0; int stderrSave = 0;
@@ -80,24 +81,24 @@ static NSString *subLogName;
if ([fileManager fileExistsAtPath:nsLogPathOlder]) if ([fileManager fileExistsAtPath:nsLogPathOlder])
{ {
// Temp log // Temp log
[log appendFormat:@"[MXLogger] redirectNSLogToFiles: removeItemAtPath: %@\n", nsLogPathOlder]; [log appendFormat:@"removeItemAtPath: %@\n", nsLogPathOlder];
NSError *error; NSError *error;
[fileManager removeItemAtPath:nsLogPathOlder error:&error]; [fileManager removeItemAtPath:nsLogPathOlder error:&error];
if (error) if (error)
{ {
[log appendFormat:@"[MXLogger] ERROR: removeItemAtPath: %@. Error: %@\n", nsLogPathOlder, error]; [log appendFormat:@"removeItemAtPath: %@. Error: %@\n", nsLogPathOlder, error];
} }
} }
// Temp log // Temp log
[log appendFormat:@"[MXLogger] redirectNSLogToFiles: moveItemAtPath: %@ toPath: %@\n", nsLogPathCurrent, nsLogPathOlder]; [log appendFormat:@"moveItemAtPath: %@ toPath: %@\n", nsLogPathCurrent, nsLogPathOlder];
NSError *error; NSError *error;
[fileManager moveItemAtPath:nsLogPathCurrent toPath:nsLogPathOlder error:&error]; [fileManager moveItemAtPath:nsLogPathCurrent toPath:nsLogPathOlder error:&error];
if (error) if (error)
{ {
[log appendFormat:@"[MXLogger] ERROR: moveItemAtPath: %@ toPath: %@. Error: %@\n", nsLogPathCurrent, nsLogPathOlder, error]; [log appendFormat:@"moveItemAtPath: %@ toPath: %@. Error: %@\n", nsLogPathCurrent, nsLogPathOlder, error];
} }
} }
} }
@@ -108,11 +109,11 @@ static NSString *subLogName;
NSString *nsLogPath = [logsFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"console%@.log", subLogName]]; NSString *nsLogPath = [logsFolderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"console%@.log", subLogName]];
freopen([nsLogPath fileSystemRepresentation], "w+", stderr); freopen([nsLogPath fileSystemRepresentation], "w+", stderr);
// MXLogDebug(@"[MXLogger] redirectNSLogToFiles: YES"); MXLogDebug(@"redirectNSLogToFiles: YES");
if (log.length) if (log.length)
{ {
// We can now log into files // We can now log into files
// MXLogDebug(@"%@", log); MXLogDebug(@"%@", log);
} }
[self removeExtraFilesFromCount:numberOfFiles]; [self removeExtraFilesFromCount:numberOfFiles];
@@ -162,7 +163,7 @@ static NSString *subLogName;
} }
} }
// MXLogDebug(@"[MXLogger] logFiles: %@", logFiles); MXLogDebug(@"logFiles: %@", logFiles);
return logFiles; return logFiles;
} }
@@ -200,13 +201,12 @@ static void handleUncaughtException(NSException *exception)
NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString]; NSString *version = [[NSProcessInfo processInfo] operatingSystemVersionString];
#endif #endif
NSArray *backtrace = [exception callStackSymbols]; NSArray *backtrace = [exception callStackSymbols];
NSString *description = [NSString stringWithFormat:@"%.0f - %@\n%@\nApplication: %@ (%@)\nApplication version: %@\nMatrix SDK version: %@\nBuild: %@\n%@ %@\n\nMain thread: %@\n%@\n", NSString *description = [NSString stringWithFormat:@"%.0f - %@\n%@\nApplication: %@ (%@)\nApplication version: %@\nBuild: %@\n%@ %@\n\nMain thread: %@\n%@\n",
[[NSDate date] timeIntervalSince1970], [[NSDate date] timeIntervalSince1970],
[NSDate date], [NSDate date],
exception.description, exception.description,
app, appId, app, appId,
appVersion, appVersion,
@"",
buildVersion, buildVersion,
model, version, model, version,
[NSThread isMainThread] ? @"YES" : @"NO", [NSThread isMainThread] ? @"YES" : @"NO",
@@ -220,8 +220,9 @@ static void handleUncaughtException(NSException *exception)
encoding:NSStringEncodingConversionAllowLossy encoding:NSStringEncodingConversionAllowLossy
error:nil]; error:nil];
NSLog(@"[MXLogger] handleUncaughtException:\n%@", description); MXLogErrorDetails(@"handleUncaughtException", @{
// MXLogError(@"[MXLogger] handleUncaughtException:\n%@", description); @"description": description ?: @"unknown"
});
} }
// Signals emitted by the app are handled here // Signals emitted by the app are handled here
@@ -302,16 +303,16 @@ static NSString* crashLogPath(void)
{ {
NSString *logsFolderPath = nil; NSString *logsFolderPath = nil;
// NSURL *sharedContainerURL = [[NSFileManager defaultManager] applicationGroupContainerURL]; NSURL *sharedContainerURL = [[NSFileManager defaultManager] appGroupContainerURL];
// if (sharedContainerURL) if (sharedContainerURL)
// { {
// logsFolderPath = [sharedContainerURL path]; logsFolderPath = [sharedContainerURL path];
// } }
// else else
// { {
NSArray<NSURL *> *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]; NSArray<NSURL *> *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
logsFolderPath = paths[0].path; logsFolderPath = paths[0].path;
// } }
return logsFolderPath; return logsFolderPath;
} }
@@ -332,7 +333,7 @@ static NSString* crashLogPath(void)
if ([fileManager fileExistsAtPath:logFile]) if ([fileManager fileExistsAtPath:logFile])
{ {
[fileManager removeItemAtPath:logFile error:nil]; [fileManager removeItemAtPath:logFile error:nil];
// MXLogDebug(@"[MXLogger] removeExtraFilesFromCount: %@. removeItemAtPath: %@\n", @(count), logFile); MXLogDebug(@"removeExtraFilesFromCount: %@. removeItemAtPath: %@\n", @(count), logFile);
} }
else else
{ {
@@ -374,19 +375,18 @@ static NSString* crashLogPath(void)
if (removeFiles) if (removeFiles)
{ {
// MXLogDebug(@"[MXLogger] removeFilesAfterSizeLimit: Remove files from index %@ because logs are too large (%@ for a limit of %@)\n", MXLogDebug(@"removeFilesAfterSizeLimit: Remove files from index %@ because logs are too large (%@ for a limit of %@)\n",
// @(index), @(index),
// [NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary], [NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary],
// [NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]); [NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]);
[self removeExtraFilesFromCount:index]; [self removeExtraFilesFromCount:index];
} }
else else
{ {
// MXLogDebug(@"[MXLogger] removeFilesAfterSizeLimit: No need: %@ for a limit of %@\n", MXLogDebug(@"removeFilesAfterSizeLimit: No need: %@ for a limit of %@\n",
// [NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary], [NSByteCountFormatter stringFromByteCount:logSize countStyle:NSByteCountFormatterCountStyleBinary],
// [NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]); [NSByteCountFormatter stringFromByteCount:sizeLimit countStyle:NSByteCountFormatterCountStyleBinary]);
} }
} }
@end @end
@@ -67,17 +67,17 @@ final class NavigationRouter: NSObject, NavigationRouterType {
// MARK: - Public // MARK: - Public
func present(_ module: Presentable, animated: Bool = true) { func present(_ module: Presentable, animated: Bool = true) {
MXLog.debug("[NavigationRouter] Present \(module)") MXLog.debug("Present \(module)")
navigationController.present(module.toPresentable(), animated: animated, completion: nil) navigationController.present(module.toPresentable(), animated: animated, completion: nil)
} }
func dismissModule(animated: Bool = true, completion: (() -> Void)? = nil) { func dismissModule(animated: Bool = true, completion: (() -> Void)? = nil) {
MXLog.debug("[NavigationRouter] Dismiss presented module") MXLog.debug("Dismiss presented module")
navigationController.dismiss(animated: animated, completion: completion) navigationController.dismiss(animated: animated, completion: completion)
} }
func setRootModule(_ module: Presentable, hideNavigationBar: Bool = false, animated: Bool = false, popCompletion: (() -> Void)? = nil) { func setRootModule(_ module: Presentable, hideNavigationBar: Bool = false, animated: Bool = false, popCompletion: (() -> Void)? = nil) {
MXLog.debug("[NavigationRouter] Set root module \(module)") MXLog.debug("Set root module \(module)")
let controller = module.toPresentable() let controller = module.toPresentable()
@@ -116,7 +116,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func setModules(_ modules: [NavigationModule], hideNavigationBar: Bool, animated: Bool) { func setModules(_ modules: [NavigationModule], hideNavigationBar: Bool, animated: Bool) {
MXLog.debug("[NavigationRouter] Set modules \(modules)") MXLog.debug("Set modules \(modules)")
let controllers = modules.map { module -> UIViewController in let controllers = modules.map { module -> UIViewController in
let controller = module.presentable.toPresentable() let controller = module.presentable.toPresentable()
@@ -154,7 +154,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func popToRootModule(animated: Bool) { func popToRootModule(animated: Bool) {
MXLog.debug("[NavigationRouter] Pop to root module") MXLog.debug("Pop to root module")
let controllers = navigationController.viewControllers let controllers = navigationController.viewControllers
@@ -174,7 +174,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func popToModule(_ module: Presentable, animated: Bool) { func popToModule(_ module: Presentable, animated: Bool) {
MXLog.debug("[NavigationRouter] Pop to module \(module)") MXLog.debug("Pop to module \(module)")
let controller = module.toPresentable() let controller = module.toPresentable()
let controllersBeforePop = navigationController.viewControllers let controllersBeforePop = navigationController.viewControllers
@@ -195,7 +195,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func push(_ module: Presentable, animated: Bool = true, popCompletion: (() -> Void)? = nil) { func push(_ module: Presentable, animated: Bool = true, popCompletion: (() -> Void)? = nil) {
MXLog.debug("[NavigationRouter] Push module \(module)") MXLog.debug("Push module \(module)")
let controller = module.toPresentable() let controller = module.toPresentable()
@@ -219,7 +219,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func push(_ modules: [NavigationModule], animated: Bool) { func push(_ modules: [NavigationModule], animated: Bool) {
MXLog.debug("[NavigationRouter] Push modules \(modules)") MXLog.debug("Push modules \(modules)")
// Avoid pushing any UINavigationController onto stack // Avoid pushing any UINavigationController onto stack
guard modules.first(where: { $0.presentable.toPresentable() is UINavigationController }) == nil else { guard modules.first(where: { $0.presentable.toPresentable() is UINavigationController }) == nil else {
@@ -249,7 +249,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func popModule(animated: Bool = true) { func popModule(animated: Bool = true) {
MXLog.debug("[NavigationRouter] Pop module") MXLog.debug("Pop module")
if let lastController = navigationController.viewControllers.last { if let lastController = navigationController.viewControllers.last {
willPopViewController(lastController) willPopViewController(lastController)
@@ -261,7 +261,7 @@ final class NavigationRouter: NSObject, NavigationRouterType {
} }
func popAllModules(animated: Bool) { func popAllModules(animated: Bool) {
MXLog.debug("[NavigationRouter] Pop all modules") MXLog.debug("Pop all modules")
let controllersToPop = navigationController.viewControllers.reversed() let controllersToPop = navigationController.viewControllers.reversed()
@@ -360,7 +360,7 @@ extension NavigationRouter: UINavigationControllerDelegate {
return return
} }
MXLog.debug("[NavigationRouter] Popped module: \(poppedViewController)") MXLog.debug("Popped module: \(poppedViewController)")
didPopViewController(poppedViewController) didPopViewController(poppedViewController)
} }
@@ -95,7 +95,7 @@ class AuthenticationCoordinator: Coordinator, Presentable {
case .updated: case .updated:
self.showLoginScreen() self.showLoginScreen()
case .dismiss: case .dismiss:
MXLog.failure("[AuthenticationCoordinator] ServerSelectionScreen is requesting dismiss when part of a stack.") MXLog.failure("ServerSelectionScreen is requesting dismiss when part of a stack.")
} }
} }
@@ -76,11 +76,11 @@ final class LoginCoordinator: Coordinator, Presentable {
// MARK: - Public // MARK: - Public
func start() { func start() {
MXLog.debug("[LoginCoordinator] did start.") MXLog.debug("Did start.")
loginViewModel.callback = { [weak self] action in loginViewModel.callback = { [weak self] action in
guard let self = self else { return } guard let self = self else { return }
MXLog.debug("[LoginCoordinator] LoginViewModel did callback with result: \(action).") MXLog.debug("LoginViewModel did callback with result: \(action).")
switch action { switch action {
case .selectServer: case .selectServer:
@@ -204,7 +204,7 @@ final class LoginCoordinator: Coordinator, Presentable {
/// Presents the server selection screen as a modal. /// Presents the server selection screen as a modal.
private func presentServerSelectionScreen() { private func presentServerSelectionScreen() {
MXLog.debug("[LoginCoordinator] presentServerSelectionScreen") MXLog.debug("PresentServerSelectionScreen")
let parameters = ServerSelectionCoordinatorParameters(authenticationService: authenticationService, let parameters = ServerSelectionCoordinatorParameters(authenticationService: authenticationService,
hasModalPresentation: true) hasModalPresentation: true)
let coordinator = ServerSelectionCoordinator(parameters: parameters) let coordinator = ServerSelectionCoordinator(parameters: parameters)
@@ -64,11 +64,11 @@ final class ServerSelectionCoordinator: Coordinator, Presentable {
// MARK: - Public // MARK: - Public
func start() { func start() {
MXLog.debug("[ServerSelectionCoordinator] did start.") MXLog.debug("Did start.")
serverSelectionViewModel.callback = { [weak self] action in serverSelectionViewModel.callback = { [weak self] action in
guard let self = self else { return } guard let self = self else { return }
MXLog.debug("[ServerSelectionCoordinator] ServerSelectionViewModel did callback with action: \(action).") MXLog.debug("ServerSelectionViewModel did callback with action: \(action).")
switch action { switch action {
case .confirm(let homeserverAddress): case .confirm(let homeserverAddress):
@@ -57,10 +57,10 @@ final class BugReportCoordinator: Coordinator, Presentable {
// MARK: - Public // MARK: - Public
func start() { func start() {
MXLog.debug("[BugReportCoordinator] did start.") MXLog.debug("Did start.")
bugReportViewModel.callback = { [weak self] result in bugReportViewModel.callback = { [weak self] result in
guard let self = self else { return } guard let self = self else { return }
MXLog.debug("[BugReportCoordinator] BugReportViewModel did complete with result: \(result).") MXLog.debug("BugReportViewModel did complete with result: \(result).")
switch result { switch result {
case .submitStarted: case .submitStarted:
self.startLoading() self.startLoading()
@@ -47,10 +47,10 @@ class BugReportViewModel: BugReportViewModelType, BugReportViewModelProtocol {
includeCrashLog: true, includeCrashLog: true,
githubLabels: BuildSettings.bugReportGHLabels, githubLabels: BuildSettings.bugReportGHLabels,
files: files) files: files)
MXLog.info("[BugReportViewModel] submitBugReport succeeded, result: \(result.reportUrl)") MXLog.info("SubmitBugReport succeeded, result: \(result.reportUrl)")
callback?(.submitFinished) callback?(.submitFinished)
} catch { } catch {
MXLog.error("[BugReportViewModel] submitBugReport failed: \(error)") MXLog.error("SubmitBugReport failed: \(error)")
callback?(.submitFailed(error: error)) callback?(.submitFailed(error: error))
} }
} }
@@ -49,7 +49,7 @@ final class SessionVerificationCoordinator: Coordinator, Presentable {
// MARK: - Public // MARK: - Public
func start() { func start() {
MXLog.debug("[SessionVerificationCoordinator] did start.") MXLog.debug("Did start.")
sessionVerificationViewModel.callback = { [weak self] action in sessionVerificationViewModel.callback = { [weak self] action in
guard let self = self else { return } guard let self = self else { return }
@@ -51,7 +51,7 @@ class SessionVerificationViewModel: SessionVerificationViewModelType, SessionVer
switch callback { switch callback {
case .receivedVerificationData(let emojis): case .receivedVerificationData(let emojis):
guard self.stateMachine.state == .requestingVerification else { guard self.stateMachine.state == .requestingVerification else {
MXLog.warning("[SessionVerificationViewModel] callbacks: Ignoring receivedVerificationData due to invalid state.") MXLog.warning("Callbacks: Ignoring receivedVerificationData due to invalid state.")
return return
} }
@@ -58,7 +58,7 @@ final class SettingsCoordinator: Coordinator, Presentable {
settingsViewModel.callback = { [weak self] result in settingsViewModel.callback = { [weak self] result in
guard let self = self else { return } guard let self = self else { return }
MXLog.debug("[SettingsCoordinator] SettingsViewModel did complete with result: \(result).") MXLog.debug("SettingsViewModel did complete with result: \(result).")
switch result { switch result {
case .reportBug: case .reportBug:
self.presentBugReportScreen() self.presentBugReportScreen()
@@ -47,9 +47,9 @@ final class SplashScreenCoordinator: Coordinator, Presentable {
// MARK: - Public // MARK: - Public
func start() { func start() {
MXLog.debug("[SplashScreenCoordinator] did start.") MXLog.debug("Did start.")
splashScreenViewModel.callback = { [weak self] action in splashScreenViewModel.callback = { [weak self] action in
MXLog.debug("[SplashScreenCoordinator] SplashScreenViewModel did complete with result: \(action).") MXLog.debug("SplashScreenViewModel did complete with result: \(action).")
guard let self = self else { return } guard let self = self else { return }
switch action { switch action {
case .login: case .login:
@@ -57,7 +57,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
} }
if identifier == .invalid { if identifier == .invalid {
MXLog.verbose("[UIKitBackgroundTask] Do not start background task: \(name), as OS declined") MXLog.verbose("Do not start background task: \(name), as OS declined")
// call expiration handler immediately // call expiration handler immediately
expirationHandler?(self) expirationHandler?(self)
return nil return nil
@@ -68,7 +68,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
reuse() reuse()
} }
MXLog.verbose("[UIKitBackgroundTask] Start background task #\(identifier.rawValue) - \(name)") MXLog.verbose("Start background task #\(identifier.rawValue) - \(name)")
} }
func reuse() { func reuse() {
@@ -91,7 +91,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol {
private func endTask() { private func endTask() {
if identifier != .invalid { if identifier != .invalid {
MXLog.verbose("[UIKitBackgroundTask] End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)") MXLog.verbose("End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)")
application.endBackgroundTask(identifier) application.endBackgroundTask(identifier)
identifier = .invalid identifier = .invalid
@@ -32,12 +32,12 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
isReusable: Bool, isReusable: Bool,
expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? { expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? {
guard let application = application else { guard let application = application else {
MXLog.verbose("[UIKitBackgroundTaskService] Do not start background task: \(name). Application is nil") MXLog.verbose("Do not start background task: \(name). Application is nil")
return nil return nil
} }
if avoidStartingNewTasks(for: application) { if avoidStartingNewTasks(for: application) {
MXLog.verbose("[UIKitBackgroundTaskService] Do not start background task: \(name), as not enough time exists") MXLog.verbose("Do not start background task: \(name), as not enough time exists")
// call expiration handler immediately // call expiration handler immediately
expirationHandler?() expirationHandler?()
return nil return nil
@@ -78,7 +78,7 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol {
let appState = application.applicationState let appState = application.applicationState
let remainingTime = readableBackgroundTimeRemaining(application.backgroundTimeRemaining) let remainingTime = readableBackgroundTimeRemaining(application.backgroundTimeRemaining)
MXLog.verbose("[UIKitBackgroundTaskService] Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)") MXLog.verbose("Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)")
return result return result
} }
@@ -30,6 +30,7 @@ class BugReportService: BugReportServiceProtocol {
private let sentryEndpoint: String private let sentryEndpoint: String
private let applicationId: String private let applicationId: String
private let session: URLSession private let session: URLSession
private var lastCrashEventId: String?
init(withBaseUrlString baseUrlString: String, init(withBaseUrlString baseUrlString: String,
sentryEndpoint: String, sentryEndpoint: String,
@@ -63,8 +64,9 @@ class BugReportService: BugReportServiceProtocol {
return event return event
} }
options.onCrashedLastRun = { event in options.onCrashedLastRun = { [weak self] event in
MXLog.debug("Sentry detected application was crashed: \(event)") MXLog.debug("Sentry detected application was crashed: \(event)")
self?.lastCrashEventId = event.eventId.sentryIdString
} }
} }
@@ -84,12 +86,13 @@ class BugReportService: BugReportServiceProtocol {
SentrySDK.crash() SentrySDK.crash()
} }
// swiftlint: disable function_body_length
func submitBugReport(text: String, func submitBugReport(text: String,
includeLogs: Bool, includeLogs: Bool,
includeCrashLog: Bool, includeCrashLog: Bool,
githubLabels: [String], githubLabels: [String],
files: [URL]) async throws -> SubmitBugReportResponse { files: [URL]) async throws -> SubmitBugReportResponse {
MXLog.debug("[BugReportService] submitBugReport") MXLog.debug("submitBugReport")
var params = [ var params = [
MultipartFormData(key: "text", type: .text(value: text)) MultipartFormData(key: "text", type: .text(value: text))
@@ -106,6 +109,11 @@ class BugReportService: BugReportServiceProtocol {
params.append(MultipartFormData(key: "compressed-log", type: .file(url: url))) params.append(MultipartFormData(key: "compressed-log", type: .file(url: url)))
} }
} }
if let crashEventId = lastCrashEventId {
params.append(MultipartFormData(key: "crash_report", type: .text(value: "<https://sentry.tools.element.io/organizations/element/issues/?project=44&query=\(crashEventId)>")))
}
for url in files { for url in files {
params.append(MultipartFormData(key: "file", type: .file(url: url))) params.append(MultipartFormData(key: "file", type: .file(url: url)))
} }
@@ -142,9 +150,11 @@ class BugReportService: BugReportServiceProtocol {
if !result.reportUrl.isEmpty { if !result.reportUrl.isEmpty {
MXLogger.deleteCrashLog() MXLogger.deleteCrashLog()
lastCrashEventId = nil
} }
return result return result
} } // swiftlint: enable function_body_length
// MARK: - Private // MARK: - Private
@@ -179,7 +189,7 @@ class BugReportService: BugReportServiceProtocol {
private func zipFiles(includeLogs: Bool, private func zipFiles(includeLogs: Bool,
includeCrashLog: Bool) async throws -> [URL] { includeCrashLog: Bool) async throws -> [URL] {
MXLog.debug("[BugReportService] zipFiles: includeLogs: \(includeLogs), includeCrashLog: \(includeCrashLog)") MXLog.debug("zipFiles: includeLogs: \(includeLogs), includeCrashLog: \(includeCrashLog)")
var filesToCompress: [URL] = [] var filesToCompress: [URL] = []
if includeLogs, let logFiles = MXLogger.logFiles() { if includeLogs, let logFiles = MXLogger.logFiles() {
@@ -217,7 +227,7 @@ class BugReportService: BugReportServiceProtocol {
zippedFiles.append(zippedFileURL) zippedFiles.append(zippedFileURL)
} }
MXLog.debug("[BugReportService] zipFiles: totalSize: \(totalSize), totalZippedSize: \(totalZippedSize)") MXLog.debug("zipFiles: totalSize: \(totalSize), totalZippedSize: \(totalZippedSize)")
return zippedFiles return zippedFiles
} }
@@ -18,7 +18,7 @@ import Foundation
extension FileManager { extension FileManager {
/// The URL of the primary app group container. /// The URL of the primary app group container.
var appGroupContainerURL: URL? { @objc var appGroupContainerURL: URL? {
containerURL(forSecurityApplicationGroupIdentifier: ElementInfoPlist.appGroupIdentifier) containerURL(forSecurityApplicationGroupIdentifier: ElementInfoPlist.appGroupIdentifier)
} }
} }
+1
View File
@@ -56,6 +56,7 @@ targets:
DEVELOPMENT_TEAM: 7J4U792NQT DEVELOPMENT_TEAM: 7J4U792NQT
CODE_SIGN_ENTITLEMENTS: ElementX/SupportingFiles/ElementX.entitlements CODE_SIGN_ENTITLEMENTS: ElementX/SupportingFiles/ElementX.entitlements
SWIFT_OBJC_BRIDGING_HEADER: ElementX/SupportingFiles/ElementX-Bridging-Header.h SWIFT_OBJC_BRIDGING_HEADER: ElementX/SupportingFiles/ElementX-Bridging-Header.h
SWIFT_OBJC_INTERFACE_HEADER_NAME: GeneratedInterface-Swift.h
preBuildScripts: preBuildScripts:
- name: 🛠 SwiftGen - name: 🛠 SwiftGen
@@ -59,10 +59,10 @@ final class TemplateCoordinator: Coordinator, Presentable {
// MARK: - Public // MARK: - Public
func start() { func start() {
MXLog.debug("[TemplateCoordinator] did start.") MXLog.debug("Did start.")
templateViewModel.callback = { [weak self] action in templateViewModel.callback = { [weak self] action in
guard let self = self else { return } guard let self = self else { return }
MXLog.debug("[TemplateCoordinator] TemplateViewModel did complete with result: \(action).") MXLog.debug("TemplateViewModel did complete with result: \(action).")
switch action { switch action {
case .accept: case .accept:
self.callback?(.accept) self.callback?(.accept)