Wie bringt man Fehler dazu, die Sprache des Benutzers zu sprechen?
\n\nSwift-Entwickler stoßen oft auf ein Problem: Ein Fehler wird ausgelöst, aber der Benutzer sieht so etwas wie Error Domain=MyApp Code=42. Das ist technisch korrekt, aber für einen Menschen völlig nutzlos. Auf Stack Overflow hat die Frage "How to provide a localized description with an Error type in Swift?" Tausende von Aufrufen gesammelt – und das nicht ohne Grund.
In diesem Artikel werden wir untersuchen, wie man trockene Fehlercodes in verständliche, lokalisierte Meldungen umwandelt. Sie erfahren, wie Sie das Protokoll LocalizedError verwenden, mit NSError arbeiten und Zeichenfolgen für verschiedene Sprachen richtig vorbereiten. Bereit, Ihre App benutzerfreundlicher zu machen? Los geht's!
Warum funktioniert einfaches Error nicht?
\n\nIn Swift ist das Protokoll Error ein minimaler Vertrag. Es erfordert weder eine Beschreibung noch eine Lokalisierung. Wenn Sie Ihren eigenen Fehler erstellen:
enum NetworkError: Error {\n case timeout\n case serverError(code: Int)\n}\n\n...erhalten Sie nur den Namen des Falls. Versuchen Sie, localizedDescription aufzurufen:
let error = NetworkError.timeout\nprint(error.localizedDescription) // "The operation couldn’t be completed. (NetworkError error 0.)"\n\nDas System setzt einen Standard-Satz ein – nicht informativ und nicht schön. Um dem Benutzer eine sinnvolle Meldung zu geben, müssen Sie das Protokoll LocalizedError implementieren.
Lernen Sie kennen: Das Protokoll LocalizedError
\n\nLocalizedError erweitert Error und fügt vier optionale Eigenschaften hinzu:
- \n
errorDescription– die Hauptmeldung für den Benutzer \n failureReason– der Grund des Fehlers (technisch) \n recoverySuggestion– was der Benutzer tun soll \n helpAnchor– ein Link zur Hilfe (selten verwendet) \n
Das Wichtigste ist errorDescription. Genau das wird von Systemkomponenten (Alerts, SwiftUI) angezeigt.
Implementieren eines lokalisierten Fehlers
\n\nFügen wir LocalizedError zu unserem NetworkError hinzu:
enum NetworkError: LocalizedError {\n case timeout\n case serverError(code: Int)\n case noInternet\n \n var errorDescription: String? {\n switch self {\n case .timeout:\n return NSLocalizedString(\n "Сервер не отвечает. Проверьте соединение и попробуйте снова.",\n comment: "Timeout error"\n )\n case .serverError(let code):\n let format = NSLocalizedString(\n "Ошибка сервера: %d. Попробуйте позже.",\n comment: "Server error with code"\n )\n return String(format: format, code)\n case .noInternet:\n return NSLocalizedString(\n "Нет подключения к интернету.",\n comment: "No internet error"\n )\n }\n }\n \n var failureReason: String? {\n switch self {\n case .timeout:\n return NSLocalizedString(\n "Превышено время ожидания ответа от сервера.",\n comment: "Timeout reason"\n )\n case .serverError(let code):\n return NSLocalizedString(\n "Сервер вернул код \\(code).",\n comment: "Server error reason"\n )\n case .noInternet:\n return NSLocalizedString(\n "Отсутствует активное интернет-соединение.",\n comment: "No internet reason"\n )\n }\n }\n \n var recoverySuggestion: String? {\n switch self {\n case .timeout:\n return NSLocalizedString(\n "Проверьте Wi-Fi или мобильные данные и повторите запрос.",\n comment: "Timeout recovery"\n )\n case .serverError:\n return NSLocalizedString("Es ist ein Serverfehler aufgetreten. Bitte versuchen Sie es später erneut.", comment: "Serverfehler-Wiederherstellung")\n case .noInternet:\n return NSLocalizedString("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.", comment: "Kein Internet-Wiederherstellung")\n }\n }\n}