Well, this is cutting it close don’t you think? Yeah, I know, not really the best way to approach resolutions. But it is the getting it done that really matters. This time we have the problem Completing a Tree. It, like many other problems I ended up making it harder than I needed to. Of course.
The end draws nigh. The deadline looms. I feel it bearing down on my like a weight. It instills fear and dread. Pretty dramatic, huh? Well, it isn’t that bad by any means. Worse is how my Jayhawks are playing away from Allen Fieldhouse, but it still is pretty intimidating.
Just a recap — I’ve set a goal of completing an app a month. As such I tried to pick a relatively well scoped out app for this month to get me off to a good start. So I picked something that seemed to only have 1 part that is complicated — an MPG tracking app that would store data on Dropbox. Oh, and I decided to write it in Swift and not to take any more dependencies than I needed.
Yeah, so that last part probably cost me a lot of time and complexity. I’m just not that fast in Swift and what I ended up writing for the couple forms in the app just isn’t great. It works, but I’m not happy with it and there isn’t time at this point to fix all that. I know what I wanted to do, but I don’t really know how to make the compiler happy with what I want to do. Not an awesome feeling or awesome result, but I did get something to work.
Tonight I worked on the app icon(s). This app will only launch on iPhone devices because two interfaces would have been harder than one. But, I made iPad sized icons anyway because it didn’t take much time to cut, paste, and scale the assets in Sketch. This icon will definitely not win me any awards, but it could have been much worse. The little bit I do know about using Sketch’s tools paid off in that the shapes are not just straight lines and perfect circles! Yay for small victories!
All of which lead to a likely larger defeat. Being honest here, I don’t think I’m going to make the deadline at the end of this month. I’m going to keep pushing hard and do my best, but there are so many little things (and one BIG thing) left that it seems likely. I’ve already started to plan what will happen if that is the case, but for sure it won’t kill my overall objective. I’ll still shoot for an app a month, but it would just mean I’d need to further adjust the size and scope of what each app may be.
My current gripe with Storyboards — you cannot share prototype cells between view controllers. This makes so little sense and only adds pain. Any time you want a view controller to share a cell with another view controller, you either have to copy/paste that cell from one to the other, or build the cell in code.
Generally I’d say build the cell in code. But if you do that, you don’t get to make use of the
prepareForSegue:sender: method … unless you start naming your segues and then calling
performSegueWithIdentifier:sender: which is a massive pain because it is just more string-typing in the app.
String typing never goes wrong
There is a third option that should only be considered by the truly brave — build your cell in a separate
.xib file and then fight the iOS gods to load that. Not unpossible, and I have for sure done it before, but it is definitely like pulling teeth.
Please Apple, give us a way to create reusable prototype cells that any view controller can use. Then all I’ll have to complain about is Autolayout, IB, Xcode, string typed cell dequeue, …
Oh my gosh where did the month go? It seems to be flying by and I seem to be crawling towards my goal. This could be a bad sign.
I’m not going to take it as that though. It isn’t like I haven’t accomplished anything. I do have an app that compiles and does many of the things I designed it to do. But critically, it doesn’t do all the things, and of those things it does not yet do is probably the most critical — it doesn’t calculate an MPG given a new fuel data entry.
Yeah, that’s a big one. But, I have 13 days left to submit, not necessarily make it into the App Store.
The three big pieces that are still outstanding:
- Calculate MPG
- Provide summary graphs
- Integrate with Dropbox
Of those three, only two are actually critical. The graphs one could be dropped and I don’t think the app would be much worse for it. But it would lose some of the “glance-ability” factor.
Missing functionality is a bug? Nope, that’s a feature.
I still feel confident I can get this out the door and will keep plugging away.
As always, feel free to leave comments here, on twitter, on Facebook or directly to my face (if you see me on a regular basis).
Now that I’ve set a goal for 2 Project Rosalind problems a month, I probably should do one to start this month. The first problem we will tackle is Partial Permutations. This turns out to be a pretty elementary problem that I bet everyone learned the solution to at one point in time.
Writing forms, probably my least favorite part of writing mobile apps. And of course the first app I’m building is heavily reliant on forms. Thankfully these forms are relatively simple. There is no crazy animation, no hiding and showing logic. There are only basic input fields and some options to pick from.
However, that doesn’t really simplify writing forms much. The challenge with forms isn’t so much displaying data that exists. Existing data is easy enough to map from one field on your data object to another field on the form, almost always a 1:1. No, the challenging part is taking input from a form and mapping it back into your data object.
Why is that harder than going the other way? Well because now you are having to put some trust in the user and what she is going to type. Which anyone that has ever made a form, paper or digital, for someone to fill out knows — the user will always put in something that makes no sense and will break your perfectly curated form.
Seriously, end users are the worst customers. It’s almost like they want to use what you made while also wanting to break everything. Bull, meet china shop.
Anyhow, making forms. I did that a bunch in my job back in Chicago. In fact, the last thing I really did before leaving there was to write a form library in Objective-C that took advantage of Key-Value Observing, protocols, enums, and
UIAppearaceContainer to try and simplify the process of creating forms. I created something that had a very shallow inheritance tree, made use of immutability by default with mutability being opt-in, and ended up with a library that was pretty declarative. It did make the assumption that the underlying data was an
NSObject subclass, but that isn’t so egregious in the world of iOS. I’m sure it isn’t as great as I would like to think it is, but looking back the most frustrating part to use may be the fact it uses Autolayout on the cells. Sorry, not sorry.
This time though, I am trying to be much more light weight and a whole lot simpler. I am again having to write some wrappers around the data being presented, and I want to have a declarative style, but I really want it to just work and be done quickly. I’m giving myself only about 2 days to do this because otherwise I’m going to be behind if I’m to submit by the end of this month.
Everyone knows that the iOS simulators are perfect representations of what an app will be like on a real device, right? Everything is hunky dory, peachy keen.
And then there is the real world where these autolayout constraints:
Lead to this output on the iPhone 4, 5, and 6 simulators:
But on the iPhone 6+ simulators it looks like this:
Makes sense, right?
Looking into the actual view hierarchy we can see that there are two cell separator views in each cell (which of course makes sense). This screen shot is from the 4, 5, and 6 simulators:
Notice how the separator views appear to be at the same x position. As in, their left hand sides line up correctly and everyone is happy.
Now, from the 6+ simulators:
Hmm, yeah, those aren’t lining up any more here.
Anyone have any ideas why? I don’t seem to see the issue on device, but I could be just doing something totally wrong at all levels. And no, do not joke about Autolayout, I hate on it enough on my own. 🙂
Just a quick update on the project — it seems to be moving along pretty well. I’ve got basic data structures put together, 90% of the UI wired up and at least transitioning from piece to piece. I have just started on the persistence layer of the app, which is inevitably the ugliest. It is hard to make file I/O look good.
As I’ve been working on this I have made a conscious decision to try to not have any dependencies on other people’s code. I know that I’m going to have to pull in two dependencies before it is done, but that is a price I will pay to use Dropbox’s Swift API. Until I get there though, none.
Some developers will probably scoff at this choice and even ridicule me for not using off the shelf libraries/frameworks that others have written to ease some pains I’ll run into. And those developers are not wrong. Most often it does make sense to reuse components that others have so graciously provided. This time though, I really want to write as much as I can so that I have the experience of solving all these different problems.
I believe that having to develop my own solution will at least force me to get outside my comfort zone in some situations which will lead to one of two outcomes. Either I will come away with much-needed deeper understandings of how others have solved a similar problem, or I’ll end up no better than before but with a crappier implementation. 🙂
Right now, while I write the data serialization/persistence layer, this is going to be the biggest pain point. There are plenty of open source libraries that I could use to make it easier to take my objects from data to JSON and back. And even other libraries that would probably completely abstract away differing interactions with the file system. Yet, I want to have the pain and pleasure of working through these myself and coming up with something I like. I know how I want it to end up working, hopefully I can get there.
I don’t expect that I will take this approach in all future apps, but every now and then it is fun and educational to just roll your own solution to all the things.