Функция OSLogStore `getEntries(with:, at:, match: predicate)` завершается с ошибкой для типов предикатов "messageType INIOS

Программируем под IOS
Ответить
Anonymous
 Функция OSLogStore `getEntries(with:, at:, match: predicate)` завершается с ошибкой для типов предикатов "messageType IN

Сообщение Anonymous »

Для некоторых полей, отличных от messageType, условие «IN» работает нормально.
Вот быстрый пример для проверки:
public extension Logger {
static let appSubsystem = Bundle.main.bundleIdentifier!
static func fetch(since date: Date) async throws -> [String] {
let store = try OSLogStore(scope: .currentProcessIdentifier)
let position = store.position(date: date)

// This does NOT work.
// let predicate = NSPredicate(format: "(subsystem == %@) && (messageType IN %@)", Logger.appSubsystem, ["error", "fault"])
// This, however, works.
let predicate = NSPredicate(format: "(subsystem IN %@) && (messageType == %@)", [Logger.appSubsystem], "error")

let entries = try store.getEntries(/* with: [.reverse], */ at: position,
matching: predicate)
var logs: [String] = []
for entry in entries {
try Task.checkCancellation()
if let log = entry as? OSLogEntryLog {
logs.append("""
\(entry.date):\(log.subsystem):\
\(log.category):\(log.level): \
\(entry.composedMessage)\n
""")
} else {
logs.append("\(entry.date): \(entry.composedMessage)\n")
}
}

if logs.isEmpty { logs = ["Nothing found"] }
return logs
}
}

Вот небольшой экран SwiftUI, который поможет воспроизвести проблему.
import SwiftUI
import OSLog

struct LogView: View {
@State private var text = "Loading..."
@State private var task: Task?
@State private var isLoading = false
@State private var selectedLogLevel: OSLogEntryLog.Level = .undefined
private let logLevels: [OSLogEntryLog.Level] = [.undefined, .debug, .info, .notice, .error, .fault]
let logger = Logger(subsystem: Logger.appSubsystem, category: "main")

var body: some View {
VStack {
HStack {
Button(isLoading ? "Cancel" : "Refresh") {
if isLoading {
task?.cancel()
} else {
task = Task {
text = await fetchLogs()
isLoading = false
}
}
}
ProgressView()
.opacity(isLoading ? 1 : 0)
Picker(selection: $selectedLogLevel, label: Text("Choose Log Level")) {
ForEach(logLevels) { logLevel in
Text(logLevel.description)
.tag(logLevel)
}
}
Button("Log") {
logMessage(selectedLogLevel: selectedLogLevel)
}
}

ScrollView {
Text(text)
.textSelection(.enabled)
.fontDesign(.monospaced)
.padding()
}
}
.onAppear {
isLoading = true
task = Task {
text = await fetchLogs()
isLoading = false
}
}
}
}

private extension LogView {
@MainActor
func fetchLogs() async -> String {
let calendar = Calendar.current
guard let hourAgo = calendar.date(byAdding: .hour,
value: -1, to: Date.now) else {
return "Invalid calendar"
}

do {
let logs = try await Logger.fetch(since: hourAgo)
return logs.joined()
} catch {
return error.localizedDescription
}
}

func logMessage(selectedLogLevel: OSLogEntryLog.Level) {
switch(selectedLogLevel) {
case .undefined:
logger.log("Default log message")
case .debug:
logger.debug("Debug log message")
case .info:
logger.info("Info log message")
// case .warning:
// logger.warning("Warning log message")
case .notice:
logger.notice("Notice log message")
case .error:
logger.error("Error log message")
case .fault:
logger.fault("Fault log message")

@unknown default:
logger.log("Default log message")
}
}
}

extension OSLogEntryLog.Level: @retroactive CustomStringConvertible {
public var description: String {
switch self {
case .undefined: "undefined"
case .debug: "debug"
case .info: "info"
case .notice: "notice"
case .error: "error"
case .fault: "fault"
@unknown default: "default"
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... or-message
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»