<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Adam Preble</title>
    <description>Cocoa, Trains, and Pinball</description>
    <link>http://adampreble.net</link>
    <atom:link href="http://adampreble.net/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Design Patterns: Locks and Keys</title>
        <description>&lt;p&gt;John Sundell’s &lt;a href=&quot;https://www.swiftbysundell.com/posts/managing-objects-using-locks-and-keys-in-swift&quot;&gt;Locks and Keys design pattern&lt;/a&gt; (also covered in &lt;a href=&quot;https://youtu.be/ujOc3a7Hav0?t=1222&quot;&gt;this talk&lt;/a&gt;) is worth a look. In short, rather than having a manager class with, say, &lt;code class=&quot;highlighter-rouge&quot;&gt;var currentUser: User?&lt;/code&gt;, you create a specialized factory class that represents the state of having a user (&lt;code class=&quot;highlighter-rouge&quot;&gt;var currentUser: User&lt;/code&gt;), which is in turn used to create the appropriate view controllers with the user populated/injected.&lt;/p&gt;

&lt;p&gt;For the past few years I’ve considered the Coordinator pattern (popularized on iOS by &lt;a href=&quot;http://khanlou.com/2015/10/coordinators-redux/&quot;&gt;Soroush Khanlou&lt;/a&gt;) to be my go-to high level app architectural pattern. For me, Locks and Keys closely resemble how the Coordinator pattern has worked out in practice, particularly after several years of Swift. As an example, a root &lt;code class=&quot;highlighter-rouge&quot;&gt;AppCoordinator&lt;/code&gt; might create and defer to &lt;code class=&quot;highlighter-rouge&quot;&gt;LoggedInCoordinator&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;LoggedOutCoordinator&lt;/code&gt;, depending on the state of the app. These coordinators then have private methods to create populated view controllers.&lt;/p&gt;

&lt;p&gt;Recently I spent some time experimenting with &lt;a href=&quot;https://flutter.io&quot;&gt;Flutter&lt;/a&gt;, writing an app that shows a “Connect to Server” screen prompting for address and port when not connected, and the rest of the user interface when it is connected. Flutter seems to encourage a similar pattern to the above: if the app is not connected to the server, &lt;code class=&quot;highlighter-rouge&quot;&gt;build()&lt;/code&gt; returns a widget for the “Connect to Server” screen. If it is connected, a different widget is built, with the reference to the connection passed to its constructor.&lt;/p&gt;

&lt;p&gt;A few observations of differences and similarities between Swift/UIKit and Dart/Flutter here:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Swift’s optionals must be dealt with. Without the above pattern, as Sundell points out, you end up with a lot of &lt;em&gt;guard-assertionFailure&lt;/em&gt; clutter – error handling code you never expect to be executed.&lt;/li&gt;
  &lt;li&gt;In Dart, any reference can be null, but there’s also no need to unwrap them. As a result I imagine most code only rarely checks for null, resulting in the occasional “Oh, I forgot to pass that in…” crash.&lt;/li&gt;
  &lt;li&gt;If you use UIKit storyboards to load your view controllers, you &lt;em&gt;can’t&lt;/em&gt; override the initializer and must instead rely on a convention of populating the injected dependencies, models, etc. One could argue that this is roughly equivalent to pitfalls of Dart’s “everything is optional”. (This issue with UIKit view controller instantiation is well understood by the community.)&lt;/li&gt;
  &lt;li&gt;Flutter’s design encourages passing dependencies down – stark comparison to UIKit storyboards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check out John Sundell and Soroush Khanlou’s posts if you haven’t already.&lt;/p&gt;

</description>
        <pubDate>Sat, 26 Jan 2019 11:04:41 -0500</pubDate>
        <link>http://adampreble.net/blog/2019/01/locks-and-keys/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2019/01/locks-and-keys/</guid>
      </item>
    
      <item>
        <title>Thanksgiving Moon</title>
        <description>&lt;p&gt;&lt;a href=&quot;/images/2018/11/IMG_3349.jpg&quot; class=&quot;fancybox&quot; title=&quot;Thanksgiving Moon&quot;&gt;&lt;img class=&quot;center&quot; src=&quot;/thumbs/IMG_3349_720x720.jpg&quot; alt=&quot;Thanksgiving Moon&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 26 Nov 2018 20:55:03 -0500</pubDate>
        <link>http://adampreble.net/blog/2018/11/thanksgiving-moon/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2018/11/thanksgiving-moon/</guid>
      </item>
    
      <item>
        <title>Railroad: Relocated</title>
        <description>&lt;p&gt;I’ve moved all of my railroad-related posts to their own blog, &lt;a href=&quot;http://railroad.adampreble.net/&quot;&gt;railroad.adampreble.net&lt;/a&gt;, where they can fully stretch out in all of their nerdy splendor.&lt;/p&gt;
</description>
        <pubDate>Mon, 26 Nov 2018 20:31:38 -0500</pubDate>
        <link>http://adampreble.net/blog/2018/11/railroad-relocated/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2018/11/railroad-relocated/</guid>
      </item>
    
      <item>
        <title>The Next Chapter</title>
        <description>&lt;p&gt;I’ve just begun work at &lt;a href=&quot;http://www.ritualdevelopment.com/&quot;&gt;Ritual Development Group, Inc.&lt;/a&gt;. Ritual is a product-oriented software company. I’m serving as the CTO and will share more about what we’re building as time goes on. For now, suffice it to say that this is a huge step for me; It is the realization of a dream I’ve had for quite some time.&lt;/p&gt;

&lt;p&gt;As wonderful as this is, it has meant making the very difficult decision to leave Big Nerd Ranch, where I have proudly worked for the past five years. I joined BNR in 2010, just as the original iPad was being released. Since that time, BNR has experienced tremendous growth.&lt;/p&gt;

&lt;p&gt;At BNR I worked as an independent engineer, a team lead, an author, a teacher, and as the VP of Engineering. I was able to work with startup companies, government contractors, and billion-dollar multinational conglomerates. I feel fortunate to have learned a tremendous amount in that time, and quickly.&lt;/p&gt;

&lt;p&gt;Teaching was one of the best parts of my time at BNR. As much as I love writing software, it’s really hard to beat a week spent teaching a group of nerds about platforms you love, especially when every student is excited to be there. The days for an instructor are long, but it’s a truly rewarding experience, even (or especially) when you’re sitting in the lab at 10:00 PM sketching out an app architecture with a student. BNR’s bootcamps are an exceptional experience. If you are serious about advancing as a software developer, I wholeheartedly recommend &lt;a href=&quot;https://training.bignerdranch.com/classes&quot;&gt;taking a class&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Co-authoring the fourth and fifth editions of &lt;a href=&quot;http://www.amazon.com/Cocoa-Programming-OS-Ranch-Guides/dp/0134076958/&quot;&gt;Cocoa Programming for OS X&lt;/a&gt; was a remarkable experience. I couldn’t be more thankful to Aaron for the trust he placed in me. I am especially proud of the fifth edition, which my friend and colleague Nate co-authored with me. While the fourth edition was an important update, but the fifth edition was truly an &lt;em&gt;overhaul&lt;/em&gt;, a major version release with substantial refactoring. We focused on demonstrating modern app architecture and style while also transitioning from Objective-C to Swift.&lt;/p&gt;

&lt;p&gt;All of my prior work has stretched me, but the opportunity to work as the VP of Engineering stretched me in a whole new dimension (or two). Looking back on it, I believe we accomplished a lot. But it’s also challenging to fully take stock of it. I owe many thanks to my team of engineering directors: Brandy, Brian, the Chrises, and Steven. Working with them and all of the Nerds was a truly rewarding experience. It’s hard to part ways with such a fine group of people.&lt;/p&gt;

&lt;p&gt;Looking back over my time at BNR, it’s almost unreal how much I grew there, even in some of the simplest ways. I’m a &lt;em&gt;fairly&lt;/em&gt; quiet person and the fact that I can happily deliver a talk on a chapter from the Cocoa book feels very incongruous. I also drink coffee now. I owe a great deal to all of the people at BNR who gave me so many chances to grow over the years.&lt;/p&gt;

&lt;p&gt;So here we are. This chapter has come to a close. I’m grateful for all that’s past, and I look with great anticipation to what’s next.&lt;/p&gt;

</description>
        <pubDate>Wed, 02 Sep 2015 12:00:00 -0400</pubDate>
        <link>http://adampreble.net/blog/2015/09/the-next-chapter/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2015/09/the-next-chapter/</guid>
      </item>
    
      <item>
        <title>Handling Keyboard Input in a View Controller – Alongside SpriteKit</title>
        <description>&lt;p&gt;I’m using SpriteKit in the &lt;a href=&quot;/blog/2015/02/train-game-prototypical-vs-playable/&quot;&gt;train game&lt;/a&gt; I’ve been tinkering with on and off, and recently went to add keyboard event handling to my view controller:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;override func keyDown(event: NSEvent) {
    interpretKeyEvents([event])
}

override func deleteBackward(sender: AnyObject?) {
    println(&quot;deleteBackward&quot;)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To my surprise, though, whatever was first responder wasn’t passing &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt; up the responder chain. (This is 10.10 so view controllers are in the responder chain automatically.)&lt;/p&gt;

&lt;p&gt;First, determining what was first responder was easy enough. After &lt;code class=&quot;highlighter-rouge&quot;&gt;showWindow:&lt;/code&gt; had been called:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(lldb) ex windowController.window!.firstResponder
(SKView) $R2 = 0x0000000100e1b100 {
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;SKView&lt;/code&gt; is the first responder. I had forgotten that &lt;code class=&quot;highlighter-rouge&quot;&gt;SKNode&lt;/code&gt; is a subclass of &lt;code class=&quot;highlighter-rouge&quot;&gt;NSResponder&lt;/code&gt; and that nodes can participate in the responder chain.&lt;/p&gt;

&lt;p&gt;So why wasn’t the &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt; propagating up to the view controller? I checked the &lt;code class=&quot;highlighter-rouge&quot;&gt;nextResponder&lt;/code&gt; of the &lt;code class=&quot;highlighter-rouge&quot;&gt;SKView&lt;/code&gt;: it was the same as its superview, which is to be expected. The question remains: why wasn’t &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt; propagating?&lt;/p&gt;

&lt;p&gt;For the answer to that I turned to &lt;a href=&quot;http://www.hopperapp.com&quot;&gt;Hopper Disassembler&lt;/a&gt;, which revealed that &lt;code class=&quot;highlighter-rouge&quot;&gt;-[SKView keyDown:]&lt;/code&gt; essentially sends &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt; to its scene:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;void -[SKView keyDown:](void * self, void * _cmd, void * arg2) {
    rbx = self;
    r14 = [arg2 retain];
    if (rbx-&amp;gt;_disableInput == 0x0) {
        rdi = rbx-&amp;gt;_scene;
        if (rdi != 0x0) {
            [rdi keyDown:r14];
        }
    }
    rdi = r14;
    rax = [rdi release];
    return;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So how can I deal with this? I could subclass &lt;code class=&quot;highlighter-rouge&quot;&gt;SKView&lt;/code&gt; and override &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt; to give it a more traditional implementation (pass it on to &lt;code class=&quot;highlighter-rouge&quot;&gt;nextResponder&lt;/code&gt;, for example). However, while I was in Hopper I noticed that &lt;code class=&quot;highlighter-rouge&quot;&gt;SKScene&lt;/code&gt; doesn’t implement &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt;, which means that it is relying on the default implementation of &lt;code class=&quot;highlighter-rouge&quot;&gt;keyDown:&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;NSResponder&lt;/code&gt;. Which means that the simplest solution is to set the scene’s next responder to my view controller:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;let gameScene = GameScene(size: ...)
skView.presentScene(gameScene)

assert(gameScene.nextResponder == nil)
gameScene.nextResponder = self
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now my view controller receives keyboard events: problem solved! My guess is that SpriteKit’s designers intended for the keyboard event handling to be done in an &lt;code class=&quot;highlighter-rouge&quot;&gt;SKScene&lt;/code&gt; subclass – that’s how it’s done in the Adventure sample code. Unfortunately that doesn’t make sense for my app architecture, where there’s more to the UI than an &lt;code class=&quot;highlighter-rouge&quot;&gt;SKView&lt;/code&gt;.&lt;/p&gt;

</description>
        <pubDate>Wed, 15 Apr 2015 21:55:17 -0400</pubDate>
        <link>http://adampreble.net/blog/2015/04/handling-keyboard-input-in-a-view-controller-alongside-spritekit/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2015/04/handling-keyboard-input-in-a-view-controller-alongside-spritekit/</guid>
      </item>
    
      <item>
        <title>A Quick Fix for Fuzzy SKShapeNode Lines</title>
        <description>&lt;p&gt;I’ve been using Apple’s SpriteKit for &lt;a href=&quot;/blog/2015/02/train-game-prototypical-vs-playable/&quot;&gt;the train game&lt;/a&gt;. It’s gone fairly well, except there have been a few unpleasant surprises with &lt;code class=&quot;highlighter-rouge&quot;&gt;SKShapeNode&lt;/code&gt;, which strokes/fills a bezier path. The internet is filled with folks complaining about buggy behavior from it and I’ve definitely had more than a few moments where I daydreamed about dusting off my OpenGL chops.&lt;/p&gt;

&lt;p&gt;This is an A/B screenshot of an issue I was running into. At left is before, right is after:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015/02/SKShapeNodeAntialiasedAB.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These are &lt;code class=&quot;highlighter-rouge&quot;&gt;SKShapeNode&lt;/code&gt;s with paths for the track segments, which are 2pt wide, stroked, and, most importantly &lt;em&gt;scaled up several times&lt;/em&gt; (zoomed in on the map). The issue of course is the blurry/fuzzy line rendering.&lt;/p&gt;

&lt;p&gt;The ‘fix’ was startlingly simple: setting &lt;code class=&quot;highlighter-rouge&quot;&gt;antialiased = false&lt;/code&gt; makes your blurry lines crystal clear when scaled up. This isn’t at all what I was expecting (antialiasing off == stair-stepping, pixelated lines in my mind).&lt;/p&gt;

&lt;p&gt;My guess is that this is an optimization. For &lt;code class=&quot;highlighter-rouge&quot;&gt;SKShapeNode&lt;/code&gt;, antialiased means it will be drawn on a texture at unscaled resolution and that texture is then scaled as needed. With antialiased off, the curve drawing occurs at the current resolution. This is only reasoning off of the visual results. I don’t notice any significant difference in CPU overhead when antialiased is off.&lt;/p&gt;

&lt;p&gt;It’s also curious because SpriteKit seems to perpetually re-render &lt;code class=&quot;highlighter-rouge&quot;&gt;SKShapeNode&lt;/code&gt;s whether they have changed or not. At some point I will likely end up writing code to render them to textures, or just moving over to OpenGL and rendering the tracks myself.&lt;/p&gt;

&lt;p&gt;At this point in development the visuals are secondary, however. I ran an experiment with &lt;code class=&quot;highlighter-rouge&quot;&gt;SKShapeNode&lt;/code&gt;’s &lt;code class=&quot;highlighter-rouge&quot;&gt;strokeTexture&lt;/code&gt; and aside from some strange rendering artifacts (texture scaled unevenly), the result was much too busy. For now I rather like this abstract appearance for the tracks.&lt;/p&gt;

</description>
        <pubDate>Mon, 16 Feb 2015 23:57:51 -0500</pubDate>
        <link>http://adampreble.net/blog/2015/02/a-quick-fix-for-fuzzy-skshapenode-lines/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2015/02/a-quick-fix-for-fuzzy-skshapenode-lines/</guid>
      </item>
    
      <item>
        <title>A Train Game: Prototypical vs Playable</title>
        <description>&lt;p&gt;Late last year I was playing &lt;a href=&quot;http://www.artemis.eochu.com&quot;&gt;Artemis Spaceship Bridge Simulator&lt;/a&gt; and, being the sort that likes trains, I thought, wouldn’t it be cool if there were a collaborative game that simulated running a railroad? So late in December I started writing some Swift code, building the game as a Cocoa app. Here’s what it looks like today:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015/02/DispatchGame-2015-02-15-Overview.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s some video of it from around the first of this year:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/ffer5s0Fcj0?list=PLfEeoaJWHalbimilWmVugyNw36e1xgOMY&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The vision is for several players to operate a railroad together. One or two dispatchers, a few engineers cycling between trains. Switching cars in yards, moving trains up and down the mainline, fulfilling orders from industries. A game could run an hour or two, or perhaps a number of sessions over the course of a few weeks.&lt;/p&gt;

&lt;p&gt;It’s come a long way over the past two months. There’s a server that clients can connect to and operate the trains, couple and decouple cars. A basic map editor. It’s a lot, or it feels like a lot to me, but at the same time it still feels very primitive. It’s a prototype, or possibly a toy, but not yet a game.&lt;/p&gt;

&lt;p&gt;Motivation can be a curious beast, especially with competing priorities. With the basics in place, feature work becomes less satisfying. It’s time to start playing with making it a game.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;At its core this game is a simulation of the operating sessions that some model railroaders conduct in their basement, but without the limitation of space. This makes it possible for maps to be very realistic, modeled on real places.&lt;/p&gt;

&lt;p&gt;That realism presents some interesting challenges in terms of presenting the information. This is a fairly simple classification yard and already it’s pretty challenging to take in:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015/02/DispatchGame-2015-02-15-Yard.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Picture those tracks full of cars and weep. I weep for joy &lt;em&gt;and&lt;/em&gt; terror: there’s something very pleasing about vast arrays of parallel tracks, as well as extremely daunting if you are expecting me to make sense of it! At the moment my favored approach to this is to add a toggle-able HUD that color codes cars by their destination.&lt;/p&gt;

&lt;p&gt;Here’s another area that needs work. Perfectly clear, right?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2015/02/DispatchGame-2015-02-15-Switches.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;From here there will of course be more feature work – such as on those switch track signals – but more importantly I plan to work on the model for the industries and yards so that there is something to accomplish in the game, aside from randomly coupling and decoupling cars.&lt;/p&gt;

</description>
        <pubDate>Sun, 15 Feb 2015 12:18:50 -0500</pubDate>
        <link>http://adampreble.net/blog/2015/02/train-game-prototypical-vs-playable/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2015/02/train-game-prototypical-vs-playable/</guid>
      </item>
    
      <item>
        <title>Lennart Green</title>
        <description>&lt;p&gt;This video of Swedish close-up/card magician &lt;a href=&quot;http://www.ted.com/talks/lennart_green_does_close_up_card_magic?language=en&quot;&gt;Lennart Green from TED 2005&lt;/a&gt; (&lt;a href=&quot;https://www.youtube.com/watch?v=1_oa8m5Oq00&quot;&gt;YouTube&lt;/a&gt;) is simply wonderful. It is a pleasure to watch him expertly fumbling his way through one delightful surprise after another.&lt;/p&gt;

&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/1_oa8m5Oq00&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

</description>
        <pubDate>Tue, 07 Oct 2014 23:55:22 -0400</pubDate>
        <link>http://adampreble.net/blog/2014/10/lennart-green/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2014/10/lennart-green/</guid>
      </item>
    
      <item>
        <title>Iterating Over a Range of Dates in Swift</title>
        <description>&lt;p&gt;&lt;em&gt;Updated 2016/8/25: Made a few style tweaks and fixes for Swift 2.2; fixed start date issue (thanks, gist commenters!).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One thing I’ve been wanting to do with Swift is iterate over a range of &lt;code class=&quot;highlighter-rouge&quot;&gt;NSDate&lt;/code&gt; objects in a for loop. Something like this:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endDate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While I think it might be possible to do this by making &lt;code class=&quot;highlighter-rouge&quot;&gt;NSDate&lt;/code&gt; conform to &lt;code class=&quot;highlighter-rouge&quot;&gt;ForwardIndexType&lt;/code&gt;, it would be fairly inflexible. As I understand date arithmetic, to do it right you need a reference to the &lt;code class=&quot;highlighter-rouge&quot;&gt;NSCalendar&lt;/code&gt; being used, and of course you need to know how much to ‘step’ the date each time. You could just make it step by days but what if you later want to step by hours?&lt;/p&gt;

&lt;p&gt;So I decided on a different approach: create a struct, &lt;code class=&quot;highlighter-rouge&quot;&gt;DateRange&lt;/code&gt;, that conforms to &lt;code class=&quot;highlighter-rouge&quot;&gt;SequenceType&lt;/code&gt;. It’s not nearly as succinct, but it is much more flexible. Create an instance of the struct using an extension on &lt;code class=&quot;highlighter-rouge&quot;&gt;NSCalendar&lt;/code&gt;, as this seems to be in keeping with calendar-dependent date APIs. It looks like this:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;calendar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;currentCalendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dateRange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calendar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dateRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                     &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                   &lt;span class=&quot;nv&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                   &lt;span class=&quot;nv&quot;&gt;stepValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;date&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;It's &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The complete code is below (also &lt;a href=&quot;https://gist.github.com/preble/b08b6d9ee161534e6c1f&quot;&gt;in a gist&lt;/a&gt;), but first a bit of a disclaimer: this code works, but I half expect to look back on it in a year, cringe, and contemplate deleting this post. My crystal ball of Swift faux pas is cloudy.&lt;/p&gt;

&lt;p&gt;Note also that at the time this was written, &lt;code class=&quot;highlighter-rouge&quot;&gt;NSDate&lt;/code&gt; did not have any Swift comparison operators built in, so I implemented &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;. Presumably that will change.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Foundation&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;OrderedDescending&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;extension&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendar&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dateRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendarUnit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DateRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dateRange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DateRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;calendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                  &lt;span class=&quot;nv&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stepValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;multiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateRange&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DateRange&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;SequenceType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;calendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendar&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendarUnit&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;stepValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;multiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Generator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Generator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Generator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GeneratorType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;DateRange&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;mutating&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;nextDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;calendar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dateByAddingUnit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                          &lt;span class=&quot;nv&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stepValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multiplier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                         &lt;span class=&quot;nv&quot;&gt;toDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                        &lt;span class=&quot;nv&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endDate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;nil&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multiplier&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextDate&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Usage:&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;testDateRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;calendar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;calendarIdentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSCalendarIdentifierGregorian&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;timeIntervalSinceNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NSDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;timeIntervalSinceNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;24*60*60*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dateRange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calendar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dateRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                         &lt;span class=&quot;nv&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                       &lt;span class=&quot;nv&quot;&gt;stepUnits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                       &lt;span class=&quot;nv&quot;&gt;stepValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;datesInRange&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dateRange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;XCTAssertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datesInRange&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Expected 7 days&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;XCTAssertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datesInRange&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;First date should have been the start date.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sun, 07 Sep 2014 22:29:04 -0400</pubDate>
        <link>http://adampreble.net/blog/2014/09/iterating-over-range-of-dates-swift/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2014/09/iterating-over-range-of-dates-swift/</guid>
      </item>
    
      <item>
        <title>Southern 4501 at TVRM</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://norfolksouthern.tumblr.com/&quot;&gt;Norfolk Southern’s Tumblr&lt;/a&gt; and &lt;a href=&quot;https://www.flickr.com/photos/norfolksouthern/&quot;&gt;Flickr&lt;/a&gt; tend to have some pretty great train photography on them. Recently they’ve had some shots of Southern 4501, which has been restored by the &lt;a href=&quot;http://www.tvrail.com/&quot;&gt;Tennessee Valley Railroad Museum&lt;/a&gt; up in Chattanooga.&lt;/p&gt;

&lt;p&gt;In particular, this shot of 4501 and 630 at TVRM is pretty sharp: &lt;a href=&quot;http://norfolksouthern.tumblr.com/post/96778062992/southern-2-8-0-630-and-2-8-2-4501-simmer-side-by&quot;&gt;Southern 2-8-0 630 and 2-8-2 4501 Simmer Side By Side&lt;/a&gt;. I’d embed them but they aren’t on Flickr.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 9/6/2014&lt;/strong&gt;: They shot some video, too: &lt;a href=&quot;http://norfolksouthern.tumblr.com/post/96837158477/heres-a-video-of-the-southern-630-and-4501&quot;&gt;Southern 4501 and 630 Working Together&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 9/7/2014&lt;/strong&gt;: &lt;a href=&quot;http://norfolksouthern.tumblr.com/post/96884488207/after-a-day-of-excursions-during-tennessee-valley&quot;&gt;This overhead shot&lt;/a&gt; is pretty outstanding.&lt;/p&gt;

&lt;p&gt;We went up to TVRM a couple months ago and had a great visit. The Missionary Ridge Local that they run uses 630 as its power. It’s a 45-minute out-and-back excursion with a 15 minute break in the middle where you watch them turn the locomotive on a turntable and run it back to the (new) front of the train to take it back to the station.&lt;/p&gt;

&lt;p&gt;Below is a photo I took during that visit of 630 arriving as NS 9686 kindly passes in the background.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.flickr.com/photos/preble/14970390817&quot; title=&quot;NS 9686 &amp;amp; Southern 630 at Grand Junction by Adam Preble, on Flickr&quot;&gt;&lt;img src=&quot;https://farm4.staticflickr.com/3854/14970390817_91246fd7dc_z.jpg&quot; width=&quot;640&quot; height=&quot;427&quot; alt=&quot;NS 9686 &amp;amp; Southern 630 at Grand Junction&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

</description>
        <pubDate>Sat, 06 Sep 2014 10:21:32 -0400</pubDate>
        <link>http://adampreble.net/blog/2014/09/southern-4501-at-tvrm/</link>
        <guid isPermaLink="true">http://adampreble.net/blog/2014/09/southern-4501-at-tvrm/</guid>
      </item>
    
  </channel>
</rss>