Introduction: why code review is important for a Swift developer
\n\nCode review is a process where one or more developers review code written by a colleague before it is merged into the main project branch. For beginner iOS/macOS developers, this is not just a formality, but a powerful tool for learning and improving code quality.
\n\nIn the Swift ecosystem, where strong typing and memory safety are paramount, code review helps identify not only logical errors but also issues with ARC (Automatic Reference Counting), optional types, and multithreading. In this article, we will break down what exactly to check in Swift code and how to give feedback that is useful and constructive.
\n\nKey aspects of code review in Swift
\n\n1. Code cleanliness and adherence to Swift style
\n\nFirst and foremost, the code must be readable. Swift has clear naming conventions described in Apple's API Design Guidelines. What to look for:
\n\n- \n
- Variable and function names should be clear and expressive. Avoid abbreviations like
btn— usesubmitButton. \n - Declaration order: properties, initializers, methods, subclasses. Use
// MARK:for grouping. \n - Use of spaces and indentation. The Swift community prefers 4 spaces (or 2 in some teams), but consistency is key. \n
- Avoid force unwrapping (
!) unless explicitly necessary. Preferguard letorif let. \n
Example of bad and good style:
\n\n// Bad\nvar x: String!\nfunc doSomething() { print(x!) }\n\n// Good\nvar username: String?\nfunc printUsername() {\n guard let name = username else { return }\n print(name)\n}\n\n\n2. Memory safety and ARC
\n\nSwift uses Automatic Reference Counting (ARC), but that doesn't mean you can forget about strong reference cycles. During code review, be sure to check:
\n\n- \n
- Closures: if a closure captures
self, andselfholds the closure, a cycle occurs. Use[weak self]or[unowned self]. \n - Delegates: they should almost always be weak (
weak var delegate). \n - Caches and observers: remove subscriptions to
NotificationCenteror KVO upon object deinitialization. \n
class NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n // DANGEROUS: strong reference to self\n URLSession.shared.dataTask(with: url) { data, _, _ in\n self.handleResponse(data) // cycle!\n }\n \n // SAFE\n URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in\n self?.handleResponse(data)\n }\n }\n}\n\n\n3. Error handling and optional types
\n\nSwift offers a powerful error handling system with do-catch and optional types. During code review, check:
- \n
- Are all errors handled? Use
try?only if you are prepared fornil. \n - Is
try!used in production code? This is almost always bad practice. \n - Are optional chains handled correctly? Avoid deep nesting of
if let— useguardfor early exit. \n
// Instead of this:\nif let data = response.data {\n if let json = try? JSONSerialization.jsonObject(with: data) {\n i