Although I knew there’s a “cookbook” book series, I haven’t read any of these before I read Erica Sadun’s The Swift Developer’s Handbook. The code listings are called “recipes”, and most of the time rightly so: I bet I copied about a dozen of the recipes into my own handy code snippet index to extend Swift’s capabilities with super useful things like safe Array indexes.
That’s a recent question from the comments put in my own words. A view model that encapsulates the display state sounds promising at first. But when you don’t have a simple view that displays one thing, how do you model that in code? How do you model a sequence of view controllers, for example a more complex checkout process?
I’d make that not private but internal and group these in a struct to separate them from other Selector stuff:
extensionSelector{// One for each view module ...structBanana{staticletchangeSizeTapped=#selector(BananaViewController.changeSizeTapped(_:))}structPotato{staticletpeelSelected=#selector(PotatoViewController.peelSelected(_:))}}// ...button.addTarget(self,action:.Potato.peelSelected,forControlEvents:.TouchUpInside)
I have uploaded updated versions of all my books today so you can enjoy the latest Swift 2.2 syntax. If you bought from my store, you can download the latest version using the link you received in your order confirmation mail. Lost it? No problem, I’ll re-send it to you if you get in touch via e-mail.
Something short and sweet I want to share with you because I love how it reads: restoringSelection is a function that takes a block and performs whatever the block does while restoring the current selection in a table view (here: NSTableView). Here’s the implementation. The resulting code from above reads so much nicer than querying selection() first and restoring it afterwards. It communicates very clearly that some state from before will be preserved (or restored).
They discuss general project architecture, using tools to generate module files, and how passing data from one Wireframe to another works in their app.
I haven’t used VIPER in an iOS app, yet, but I used the concept in the Word Counter. There, nothing’s disposed after setup, so I have all Wireframes and their components setup once upon launch. The authors use Wireframes as factories for view controllers.
A Note about Syncing Changes: Where to Handle Sync Events
Further down, under “How to deal with listening changes from backend?”, the authors show how synchronization changes take effect.
The SynchronizerService merges changes into the Core Data stack,
the Core Data Stack sends a notification,
the Interactor receives the notification,
and changes are then pushed through the Presenter to the View.
This works, but I find the decision to be weird. Now the Interactor prepares data when requested and pushes changes upon synchronization events.
Usually, the Presenter is created in such a way that it both presents data to the view and handles events from the view. You can split this into two objects, let’s say Presenter and EventHandler. Then it becomes clear that the EventHandler can deal with events both from UI interaction and from syncing. It’s the best fit to translate any event into a command for the Interactor so it does its job.
I thought it’d be straigthforward and simple to make a NSMenuItem from the main menu implement a toggle – be it a checkmark or switching “Show X” with “Hide X” conditionally. Turns out that’s not quite as simple as I had hoped. Cocoa bindings would work but make things complicated. Most stuff on the web uses view tags to find items in menus. That’s not my favorite solution for anything. menuNeedsUpdate wasn’t called when I had hoped it would, either. So I tried a few different setups and settled with a boring and verbose way to switch “Show X” and “Hide X” depending on a boolean flag the current NSDocument window exposes.
Krzysztof Zabłocki (@merowing_) shared his approach to “Behaviors” in a Slack channel the other day. These are functional extensions to view controllers that you can wire via Interface Builder (!) to inject behavior into a scene.
When you implement CollectionType or SequenceType in custom types, you get a lot for free with just a few steps, like being able to use map on the collection. Any CollectionType implementation comes with enumerate() which, when you iterate over the result, wraps each element of the collection in a tuple with its index:
I’d like to officially announce my next project: TableFlip. Open any Markdown file with TableFlip and you can visually edit the tabular data included. Save and the Markdown file is updated. It’s that simple. It’s also Markdown-aware simple table data editing app. It’s fast and lean and pretty. No need to fire up monstrosities like Excel for Mac or even Apple’s own Numbers to edit simple data that naturally fits the 2D-arrangement of a table.
This is mostly a reminder for my future self: It doesn’t suffice to create a TXT file and add it to the target in the file inspector (⌘⌥1) to be able to read it as part of the bundle. You also have to drag it into the “Copy Bundle Resource” build phase of the target so it get, well, bundled into the product. (In my case, it was the test target.)
Create an empty file or add an existing file to the target’s group in Xcode and make it part of the proper target,
drag it into “Copy Bundle Resources” build phase,
load it using NSBundle(forClass: TheTestCase.self).URLForResource("filename", withExtension: "txt").
Storing PLIST or JSON files for structured data works just as well. I happen to require plain text flavors most of the time and always wonder why the loading fails for a couple of minutes.
I’m back from my vacation and very deep into programmin already. Before I left, my subconscious mind brought up the notion of a Lens (functional programming) while I was modelling tabular data in Swift and I think this is a very cool approach to keep value types clean and easy to test. I use lenses in my current project to provide a specialized interface to operate with the table. The lenses provide access to column and row iterators, independent of the table’s underlying data structure. This way the table doesn’t have to worry about all this stuff.