How can I use NSError in my iPhone App?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In iOS development, NSError is the Objective-C error representation used widely across Apple frameworks. Swift prefers native Error types, but bridging to NSError remains essential when using Cocoa APIs, legacy code, and interoperability layers. Understanding both models helps you design better error handling and user-facing recovery flows.
Core Structure of NSError
NSError includes:
- domain string
- integer code
userInfodictionary for context
Domain plus code provides stable machine-readable categorization.
Bridging Between Swift Error and NSError
Any Swift error can be cast to NSError.
This is useful for logging and Objective-C API boundaries.
Handling Cocoa API Errors
Many Foundation APIs expose throwing methods or completion handlers that surface NSError semantics.
Inspecting domain and code helps map technical failures to user messages.
User-Friendly Error Mapping
Do not show raw technical text directly. Map internal errors to clear user language.
This keeps UX consistent across app modules.
Logging and Diagnostics
For crash and reliability analysis, log structured fields:
- domain
- code
- operation context
- request identifier
Structured logs are far more useful than free-form text when investigating incidents.
In privacy-sensitive apps, sanitize userInfo before uploading telemetry.
Designing Custom Error Domains
If you create custom NSError, use reverse-domain naming and stable code values. Keep code meanings documented so server teams, support teams, and analytics dashboards interpret failures consistently.
This prevents long-term ambiguity in multi-team products.
NSError with Completion Handlers
Many Cocoa APIs still surface optional NSError in completion callbacks.
Understanding this pattern is important when integrating older SDKs in modern Swift codebases.
Converting NSError to Domain-Specific Swift Errors
A practical architecture is to convert raw framework errors into app-specific enums at service boundaries. That keeps UI and business logic independent from low-level domains and codes, while still preserving diagnostic information for logs. This conversion layer improves maintainability as dependencies evolve.
Testing Error Paths
Unit tests should verify domain and code mapping logic, not only localized messages. Stable error classification is crucial for analytics and retry behavior. Add explicit tests for offline, timeout, and authorization scenarios to keep failure handling predictable.
UI Presentation Consistency
Centralize error-to-alert translation in one presenter component so messages, titles, and retry actions are consistent across screens. Consistency reduces user confusion and simplifies localization updates.
Common Pitfalls
- Treating localized description as stable machine-readable identifier.
- Exposing raw technical error text directly to end users.
- Ignoring domain and code and relying on string matching.
- Mixing inconsistent custom domains across modules.
- Logging sensitive values from
userInfowithout redaction.
Summary
NSErrorremains important in iOS interoperability and framework integration.- Use domain and code for deterministic error classification.
- Bridge Swift
ErrortoNSErrorwhen needed. - Map technical failures to user-friendly messages.
- Keep error logging structured and privacy-aware.

