Error Localization in Swift: How to Make Error Understandable to the User

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Make Errors Speak the User's Language?

\n\n

Swift developers often face a problem: an error is thrown, but the user sees something like Error Domain=MyApp Code=42. This is technically correct, but completely useless for a human. On Stack Overflow, the question "How to provide a localized description with an Error type in Swift?" has gathered thousands of views — and for good reason.

\n\n

In this article, we'll break down how to turn dry error codes into clear, localized messages. You'll learn how to use the LocalizedError protocol, work with NSError, and properly prepare strings for different languages. Ready to make your app more user-friendly? Let's go!

\n\n

Why Plain Error Doesn't Work?

\n\n

In Swift, the Error protocol is a minimal contract. It requires neither a description nor localization. When you create your own error:

\n\n
enum NetworkError: Error {\n    case timeout\n    case serverError(code: Int)\n}
\n\n

...you only get the case name. Try calling localizedDescription:

\n\n
let error = NetworkError.timeout\nprint(error.localizedDescription) // "The operation couldn’t be completed. (NetworkError error 0.)"
\n\n

The system substitutes a standard phrase — uninformative and ugly. To give the user a meaningful message, you need to implement the LocalizedError protocol.

\n\n

Meet the LocalizedError Protocol

\n\n

LocalizedError extends Error and adds four optional properties:

\n\n
    \n
  • errorDescription — the main message for the user
  • \n
  • failureReason — the cause of the error (technical)
  • \n
  • recoverySuggestion — what the user should do
  • \n
  • helpAnchor — a link to help (rarely used)
  • \n
\n\n

The most important one is errorDescription. This is what system components (alerts, SwiftUI) display.

\n\n

Implementing a Localized Error

\n\n

Let's add LocalizedError to our NetworkError:

\n\n
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                "The server is not responding. Check your connection and try again.",\n                comment: "Timeout error"\n            )\n        case .serverError(let code):\n            let format = NSLocalizedString(\n                "Server error: %d. Please try again later.",\n                comment: "Server error with code"\n            )\n            return String(format: format, code)\n        case .noInternet:\n            return NSLocalizedString(\n                "No internet connection.",\n                comment: "No internet error"\n            )\n        }\n    }\n    \n    var failureReason: String? {\n        switch self {\n        case .timeout:\n            return NSLocalizedString(\n                "The server response timeout was exceeded.",\n                comment: "Timeout reason"\n            )\n        case .serverError(let code):\n            return NSLocalizedString(\n                "The server returned code \\(code).",\n                comment: "Server error reason"\n            )\n        case .noInternet:\n            return NSLocalizedString(\n                "No active internet connection.",\n                comment: "No internet reason"\n            )\n        }\n    }\n    \n    var recoverySuggestion: String? {\n        switch self {\n        case .timeout:\n            return NSLocalizedString(\n                "Check your Wi-Fi or mobile data and retry the request.",\n                comment: "Timeout recovery"\n            )\n        case .serverError:\n            return NSLocal                

Blogs

Book Recommendations