Fix various small errors when running in the Swift 6 language mode (#4109)

* Fix various small errors when running in the Swift 6 language mode

* Make the `TargetConfiguration` run on the main actor.

* Fixed a comment

* Add a comment as to why we can't make the whole NSE a main actor.

* Fix the unit tests

* Fix `blankLinesAtStartOfScope` swiftformat error.
This commit is contained in:
Stefan Ceriu
2025-05-13 11:43:47 +03:00
committed by GitHub
parent e1984ccdc0
commit 5af330cf6e
11 changed files with 47 additions and 45 deletions
@@ -7,6 +7,7 @@
import MatrixRustSDK
@MainActor
enum Target: String {
case mainApp = "elementx"
case nse
@@ -11,7 +11,7 @@ enum ExpiringTaskRunnerError: Error {
case timeout
}
actor ExpiringTaskRunner<T> {
actor ExpiringTaskRunner<T: Sendable> {
private var continuation: CheckedContinuation<T, Error>?
private var task: () async throws -> T
@@ -9,34 +9,34 @@ import Foundation
enum BlockquoteAttribute: AttributedStringKey {
typealias Value = Bool
static var name = "MXBlockquoteAttribute"
static let name = "MXBlockquoteAttribute"
}
enum UserIDAttribute: AttributedStringKey {
typealias Value = String
static var name = "MXUserIDAttribute"
static let name = "MXUserIDAttribute"
}
/// This attribute is used to help the composer convert a mention into to a markdown link before sending
/// the message. It doesn't interact mention pills, as these fetch display names live from the room.
enum UserDisplayNameAttribute: AttributedStringKey {
typealias Value = String
static var name = "MXUserDisplayNameAttribute"
static let name = "MXUserDisplayNameAttribute"
}
enum RoomDisplayNameAttribute: AttributedStringKey {
typealias Value = String
static var name = "MXRoomDisplayNameAttribute"
static let name = "MXRoomDisplayNameAttribute"
}
enum RoomIDAttribute: AttributedStringKey {
typealias Value = String
static var name = "MXRoomIDAttribute"
static let name = "MXRoomIDAttribute"
}
enum RoomAliasAttribute: AttributedStringKey {
typealias Value = String
static var name = "MXRoomAliasAttribute"
static let name = "MXRoomAliasAttribute"
}
enum EventOnRoomIDAttribute: AttributedStringKey {
@@ -45,7 +45,7 @@ enum EventOnRoomIDAttribute: AttributedStringKey {
let eventID: String
}
static var name = "MXEventOnRoomIDAttribute"
static let name = "MXEventOnRoomIDAttribute"
}
enum EventOnRoomAliasAttribute: AttributedStringKey {
@@ -54,12 +54,12 @@ enum EventOnRoomAliasAttribute: AttributedStringKey {
let eventID: String
}
static var name = "MXEventOnRoomAliasAttribute"
static let name = "MXEventOnRoomAliasAttribute"
}
enum AllUsersMentionAttribute: AttributedStringKey {
typealias Value = Bool
static var name = "MXAllUsersMentionAttribute"
static let name = "MXAllUsersMentionAttribute"
}
// periphery: ignore - required to make NSAttributedString to AttributedString conversion even if not used directly
+4 -6
View File
@@ -9,13 +9,11 @@
import Foundation
import MatrixRustSDK
/**
Logging utility that provies multiple logging levels as well as file output and rolling.
Its purpose is to provide a common entry for customizing logging and should be used throughout the code.
*/
/// Logging utility that provies multiple logging levels as well as file output and rolling.
/// Its purpose is to provide a common entry for customizing logging and should be used throughout the code.
enum MXLog {
private static var rootSpan: Span!
private static var currentTarget: String!
private nonisolated(unsafe) static var rootSpan: Span!
private nonisolated(unsafe) static var currentTarget: String!
static func configure(currentTarget: String) {
self.currentTarget = currentTarget
@@ -32,12 +32,12 @@ enum MatrixEntityRegex: String {
}
// swiftlint:disable force_try
static var homeserverRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.homeserver.rawValue, options: .caseInsensitive)
static var userIdentifierRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.userID.rawValue, options: .caseInsensitive)
static var roomAliasRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.roomAlias.rawValue, options: .caseInsensitive)
static var uriRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.uri.rawValue, options: .caseInsensitive)
static var allUsersRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.allUsers.rawValue)
static var linkRegex = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
static let homeserverRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.homeserver.rawValue, options: .caseInsensitive)
static let userIdentifierRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.userID.rawValue, options: .caseInsensitive)
static let roomAliasRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.roomAlias.rawValue, options: .caseInsensitive)
static let uriRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.uri.rawValue, options: .caseInsensitive)
static let allUsersRegex = try! NSRegularExpression(pattern: MatrixEntityRegex.allUsers.rawValue)
static let linkRegex = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
// swiftlint:enable force_try
static func isMatrixHomeserver(_ homeserver: String) -> Bool {
@@ -55,7 +55,6 @@ class EmojiPickerScreenViewModel: EmojiPickerScreenViewModelType, EmojiPickerScr
private func convert(emojiCategories: [EmojiCategory]) -> [EmojiPickerEmojiCategoryViewData] {
emojiCategories.compactMap { emojiCategory in
let emojisViewData: [EmojiPickerEmojiViewData] = emojiCategory.emojis.compactMap { emojiItem in
EmojiPickerEmojiViewData(id: emojiItem.id, value: emojiItem.unicode)
}
@@ -6,11 +6,12 @@
//
import Foundation
import MatrixRustSDK
@preconcurrency import MatrixRustSDK
/// A wrapper around Rust's `MediaFileHandle` type that provides us with a
/// media file that is stored unencrypted in a temporary location for previewing.
class MediaFileHandleProxy {
final class MediaFileHandleProxy: Sendable {
/// The underlying handle for the file.
private let handle: MediaFileHandleProtocol
@@ -7,9 +7,10 @@
import Combine
import Foundation
import MatrixRustSDK
import UIKit
@preconcurrency import MatrixRustSDK
private final class MediaRequest {
var continuations: [CheckedContinuation<Data, Error>] = []
}
@@ -6,9 +6,9 @@
//
import Foundation
import MatrixRustSDK
@preconcurrency import MatrixRustSDK
struct MediaSourceProxy: Hashable {
struct MediaSourceProxy: Hashable, Sendable {
/// The media source provided by Rust.
let underlyingSource: MediaSource
/// The media's mime type, used when loading the media's file.
+15 -13
View File
@@ -27,16 +27,18 @@ import UserNotifications
// called on the same instance of `NotificationService` as a previous
// notification.
private let settings: CommonSettingsProtocol = AppSettings()
private let keychainController = KeychainController(service: .sessions,
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
class NotificationServiceExtension: UNNotificationServiceExtension {
private var notificationHandler: NotificationHandler?
private let appHooks = AppHooks()
private let settings: CommonSettingsProtocol = AppSettings()
private let keychainController = KeychainController(service: .sessions,
accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier)
// We can make the whole NSE a MainActor after https://github.com/swiftlang/swift-evolution/blob/main/proposals/0371-isolated-synchronous-deinit.md
// otherwise we wouldn't be able to log the tag in the deinit.
deinit {
ExtensionLogger.logMemory(with: tag)
MXLog.info("\(tag) deinit")
@@ -61,15 +63,15 @@ class NotificationServiceExtension: UNNotificationServiceExtension {
return contentHandler(request.content)
}
Target.nse.configure(logLevel: settings.logLevel, traceLogPacks: settings.traceLogPacks)
MXLog.info("\(tag) #########################################")
ExtensionLogger.logMemory(with: tag)
MXLog.info("\(tag) Received payload: \(request.content.userInfo)")
Task {
await Target.nse.configure(logLevel: settings.logLevel, traceLogPacks: settings.traceLogPacks)
MXLog.info("\(tag) #########################################")
ExtensionLogger.logMemory(with: tag)
MXLog.info("\(tag) Received payload: \(request.content.userInfo)")
do {
let userSession = try await NSEUserSession(credentials: credentials,
roomID: roomID,
+4 -4
View File
@@ -22,7 +22,7 @@ class LoggingTests: XCTestCase {
let target = "tests"
XCTAssertTrue(Tracing.logFiles.isEmpty)
Target.tests.configure(logLevel: .info, traceLogPacks: [])
await Target.tests.configure(logLevel: .info, traceLogPacks: [])
// There is something weird with Rust logging where the file writing handle doesn't
// notice that the file it is writing to was deleted, so we can't run these checks
@@ -34,7 +34,7 @@ class LoggingTests: XCTestCase {
try validateTargetName(target)
try validateRoomSummaryContentIsRedacted()
try validateTimelineContentIsRedacted()
try await validateTimelineContentIsRedacted()
try validateRustMessageContentIsRedacted()
}
@@ -114,7 +114,7 @@ class LoggingTests: XCTestCase {
XCTAssertFalse(content.contains(heroName))
}
func validateTimelineContentIsRedacted() throws {
func validateTimelineContentIsRedacted() async throws {
// Given timeline items that contain text
let textAttributedString = "TextAttributed"
let textMessage = TextRoomTimelineItem(id: .randomEvent,
@@ -174,7 +174,7 @@ class LoggingTests: XCTestCase {
contentType: nil))
// When logging that value
Target.tests.configure(logLevel: .info, traceLogPacks: [])
await Target.tests.configure(logLevel: .info, traceLogPacks: [])
MXLog.info(textMessage)
MXLog.info(noticeMessage)