The problem: Some class etc. definitions cannot help but grow very large, into thousands of lines. It can feel intimidating, annoying and wearisome to scroll through everything when you just need to focus on a specific subset of functionality.
Example: Take a class for scenes in a cross-platform game. It has tons of methods and properties for each category of functionality: setting up the graphics engine, handling physics, managing audio and music, processing touch input for iOS, keyboard input for macOS, and so on.
It really doesn't make sense to lump them all in one big file. There just is no way to group everything nicely; you have to put physics properties at the top, next to the input properties, far away from the physics-handling methods. Or you have to put physics properties next to the physics methods, in the middle of the file. You can't always break such a class into multiple classes either, without incurring performance penalties or rewriting everything (because all those things are the job of the scene, so everything else, including the operating system, sends them to the scene, like input events.)
Ideal world: I just want to be able to â` to cycle through windows (which may be on different screens or spaces) and just see one set of related properties and methods at a time. When I want to update just the iOS-specific methods, I don't want to come across macOS-specific stuff.
Xcode doesn't really have a good solution for that; // MARK: -
doesn't help much in a menu with 100s of items, taller than a 5K screen. Filtering the list by typing some text or using âF every time is cumbersome as well, and doesn't always work, because of similar names, or even duplicate names in case of platform-specific code surrounded by #if os(etc)
.
Current workarounds: Extensions. See https://twitter.com/johnsundell/status/897186531592556545
But using the semantics of an "extension" for some simple code organization feels kludgy and seems bug-prone. See: Rule Request: Warning for extensions used for grouping code ¡ Issue #1767 ¡ realm/SwiftLint ¡ GitHub
Take the previous example of a game scene. A touch event is like override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { ... }
But wait, the Swift manual says "Extensions can add new functionality to a type, but they cannot override existing functionality." and yet, override
-ing a method like that in an extension compiles (and as far as I can tell, runs) happily.
Is the manual wrong? Are we not supposed to be using extensions to implement API-event-handling methods like that? The cross-platform game template in Xcode also uses extensions like that, for iOS/macOS input handling, but in the same file (so it defeats the desired ideal behavior above.)