I’ll be on vacation for the next week. Maybe I cannot hold my breath and publish a post nonetheless, but I’ll try not to. Either way, for the next week everything from my store is 20% off so you can have fun while I’m away.
Apps
The Word Counter to increase writing productivity,
Move! to not die from sitting in front of your computer.
Just found this today in a Slack channel. It seems we can actually reference and re-use Xib files by overriding awakeFromCoder!
If we are loading from placeholder view, we create a real view and then we transfer some common properties from it and all it’s subviews, then we just return that instance in place of placeholder, otherwise we just return normal view (This method is implemented on NSObject so we can call super, but this still should be done with method swizzling instead of category smashing).
When the kNibReferencingTag is set, the current instance (self) is treated as a prototype. From that prototype we transfer common properties to the realView which is properly loaded from a Nib. That means it doesn’t go the kNibReferencingTag path but the usual path, deferring to super.
The sample app contains SomeView with its own Xib that should be reused.
In the app’s Xib, we have a scene that uses it as follows:
I know, Xib files aren’t the best to read. Here’s what it boils down to:
Create a scene using a view controller of type ViewController.
In its main view place 3 subviews …
of type SomeView,
all with the tag 616,
and a few standard color properties – apparently all set to white. It doesn’t matter anyway since the SomeView.xib will dictate what it really looks like.
Unlike @IBDesignable components, you won’t have any live preview in Interface Builder. Just empty placeholder boxes.
I read Karl Bowden’s Featherweight Router TL;DR and kind of like how routes are handled. The setup looks complicated, though:
letsomeRouter=Router(aDelegate).route("animal",children:[Router(aDelegate).route("animal/mammal",children:[Router(aDelegate).route("animal/mammal/cow"),Router(aDelegate).route("animal/mammal/pig"),]),Router(aDelegate).route("animal/fish",children:[Router(aDelegate).route("animal/fish/salmon"),Router(aDelegate).route("animal/fish/trout"),]),])// Using regex's for matchingletsomeRouter=Router(aDelegate).route("animal",children:[Router(aDelegate).route("animal/\\w+",children:[Router(aDelegate).route("animal/\\w+/\\w+")])])
Child routers carry the path component of the parent with them. Also, this is very verbose. I imagine a more terse version, like:
// Assuming `aDelegate` is used for all of them and passed along,// let's omit it during setup of sub-routes:letrouter=Router(aDelegate){routerrouter.route("animal"){routerinrouter.route("mammal"){routerinrouter.route("cow")router.route("pig")}}}
Or let’s say some part is variable, like viewing a user profile:
I have added a /now page to this site which shows what I’m currently doing, thinking about, or whatever. I like the idea. Kudos to Matt Gemmell for showing his.
Did you know you can import only parts of a module? Found this in the Swiftz sample codes:
letxs=[1,2,0,3,4]importprotocolSwiftz.SemigroupimportfuncSwiftz.sconcatimportstructSwiftz.Min//: The least element of a list can be had with the Min Semigroup.letsmallestElement=sconcat(Min(2),t:xs.map{Min($0)}).value()// 0
import protocol or even import func were very new to me. Handy!
Maybe my Google-fu is lacking or there’s not much about this on the web: how do you separate handling local notifications when the app is in foreground from when it is in background? After all you’ll probably want to show a specific view when the user taps a notification badge. Here’s one way to do it.
Rethrows saves us a lot of duplicate code. Look at my naive approach to write an iterator in Swift 1 from last year which I later extended for throwing with Swift 2:
The rethrows keyword makes the method a throwing one depending on the closure you pass in. Only if the closure throws each will throw, too. The compiler will know what happens – just like generic functions are write-once, use-many-times.
Of course I later found out that Swift 2 came with forEach already bundled in. So there’s no use in this anymore except for this very illustrative blog post to remember that throws/rethrows is different from throws/throws.
Jordan Morgan of Buffer wrote about MVC on iOS. The idea is simple. Don’t mix view logic into the model; don’t control all view minutiae from the controller; don’t make intelligent views that fetch stuff from servers or similar.
His comparison of good VS bad execution of these principles is worth the read!
I shared that picture the other day and though, well, why not share an updated picture of my workplace here, too? Since 2013, some things have changed. This is my equipment:
How do you test NSURLSession properly? After all, using it in tests directly will hit the servers; that’s not what you want to do 1000s of times per day. Even if you use a localhost based server replacement the tests will be slower and potentially error-prone as the server replacement may not be 100% accurate. Anyway – there’s a popular series of posts about that topic. There, you’ll learn how to mock NSURLSession in your tests. I think the advice is good to move on quickly, but it only shifts the problem slightly out of sight. There are better alternatives.
When DevMate launched, I dabbled with the backend a bit and I really liked it. They use FastSpring for the store and enabling DevMate to integrate into your FastSpring account is very simple.
It seemed to be kind of expensive, though. Since then, they changed the pricing model once or twice and made the platform more attractive to upcoming indies and teams with a lower budget. Now it’s free.
Their SDK seems to provide easy integration. I think I’ll check it out with my next app to tell you more about the details. I just hope they’re doing well – lowering the price could just as well mean that they try to attract more devs because it doesn’t pay off to run the platform at the moment. (I think I’ll just ask them to be sure.)
Rogue Amoeba develop lots of popular software. Now Piezo 1.5 exits the Mac App Store.
While the App Store has many shortcomings, it’s the onerous rules and restrictions Apple has for selling through the Mac App Store which pose the biggest problem. The type of software we make is precluded from being sold through the store, particularly now that sandboxing is a requirement, and Apple has shown no signs of relaxing those restrictions. Fortunately, unlike iOS, the Mac platform is still open. We’re able to distribute and sell direct to our customers, right from our site. We’ve got almost 15 years of experience and success doing just that, and we have no plans to stop.
Their apps that work on the App Store stay there.
Shameless self promotion: Are you worried about the recent trend of abandoning the MAS? I wrote a book about publishing apps outside the Mac App Store. There’s nothing you have to fear. It’s fun.
After reading Sam’s post, I discussed a code snippet with him. Shortsightedly, I told him I didn’t like the following snippet because it controls project instead of doing the object its own job: It made me wonder if we can do better, though, with standard OOP practice. My proposal was a simple toggle method:
Sam Ritchie wrote “Building a Unidirectional Data Flow app with Realm” the other day. I haven’t worked with Realm before, but the state propagation seems super interesting now that I dabble with ReSwift from time to time. His post excited me to try out Realm, soon.
Imagine a complex view with many sub components. This is more common in Mac apps where a window contains multiple panes, lists, graphs, whatever. How do you react to interactions 5 levels deep? Let’s say you avoid massive view controllers which do everything on their own and want to encapsulate event handling outside the view hierarchy – what should you do?
In a recent post, I wasn’t too fond of inline helper functions. Similar things can be accomplished with blocks instead of functions, as both are closures that capture their contexts. Blocks don’t even have to have a name. Inner functions and blocks share the same semantics. Found in Little Bites of Cocoa #180:
“Using a private function means having a hardwired link to an anonymous collaborator. Over time, this will slowly hurt more.” (@jbrains) I was thinking about this the other day when I wrote tests for a presenter. It receives a date, formats it, and makes the view update a label with the result. Simple. (The real thing actually does a bit more, but that doesn’t matter much.)
Sure, now there’s a subclass of NSButton that doesn’t do much and will not be reused in the app. But the intent of delegating DateRangeData to the sub-components is clearer.
Clean and maintainable code will help you see what’s going on when you read the code. title = dateRange.range doesn’t convey everything showDateRange(dateRange) does.
Xcode now offers two kinds of tests natively. You don’t have to rely on 3rd party JavaScript libraries anymore to automate the iOS simulator and assert view conditions. So with the advent of native UI Automation tests, can you rely on them to verify your app works? Here’s the two sides of the 1 criterion you’ll ever need to find out:
Matt Galagher is back writing at Cocoa with Love. His goal is maintainability, which is the greatest of all, I think. It’s easy to copy code samples together to create an app, bur it’s hard to create a product you can keep alive and make better over years. In that vein, his first article, “Partial functions in Swift, Part 1: Avoidance”, includes a lot of details why partial functions will hurt you. This is a great topic. Read his post for the basic set theory involved.