16 Feb 2015
Next stage of the app is to store the settings we previously added to both the local
user settings and to iCloud for syncing across multiple devices.
Luckily I had some Objective-C code I could repurpose for most of the logic, but porting it was a useful exercise in getting used to the slightly obtuse casting syntax necessary in Swift when interacting with the frameworks.
Setting up iCloud preferences
To enable storing key-value pairs for the app in iCloud, it’s as simple as going to the Capabilities section of your project
- Turn on the iCloud capabilities
- Make sure the “Key-value storage” checkbox is selected
Code to get and set preferences
The code - available on GitHub for viewing - is reasonably straightforward port of some common code I’ve used before.
I’ve refactored the main settings code into a BLUserSettings.swift class I should be able to reuse in other projects. The existing DaysLeftModel class now inherits from this base class, and the getters and setters have been changed to call the appropriate read/write methods in the base class.
The getters will read from the local user settings, so they’ll be available even if the device is offline. The setters will write to both the local store, and the cloud store, and the base class also handles notifications if the settings have been changed on a remote device, and writes them locally as appropriate.
Having a bunch of unit tests as always helped to test my refactoring of the model class worked fine.
I think we’re now ready to start on the UI.
Previous posts in the series
The code for the project is also available on GitHub
11 Feb 2015
As per my previous posts, I’m developing an iOS app “in the open” using Swift as a learning experiment. It’s going to be an app that counts down the days to a future date.
Data Model design
I thought a good way of getting started would be to work on the data model code. There would be more pure Swift code to write to get up to speed on the syntax, plus I’d get the chance to write some unit tests too.
The data model design is pretty straightforward; I want to have the following properties to hold the settings data:
- start: NSDate
- end: NSDate
- title: String
- weekdaysOnly: Bool
Then there are three different access properties/methods to calculate various day lengths:
- DaysLength: Int - the number of inclusive days between the start and the end
- DaysGone(currentDate: NSDate) -> Int - the number of days from the start to the current date
- DaysLeft(currentDate: NSDate) -> Int - the number of days to the end to the current date
Writing a simple class to implement this logic was pretty simple even in a new language, although a few things were a little strange at first in Swift.
Semi-colons at the end of the line are optional in Swift, and a few references I found seemed to say best practice is not to add them, although muscle memory from Objective-C and C# made this hard to do.
Also integrating into the IOS Foundation classes was a little strange in places especially the use of optional values. For example, note the ! at the end of this line
model.start = NSCalendar.autoupdatingCurrentCalendar().dateFromComponents(startComponents)!
model.start is of type
NSDate i.e. can’t be null, whereas
dateFromComponents() can return a null value,
! forces this to actually return a value (I think!). Not the most intuitive, but thankfully the Xcode editor prompted me to add the exclamation point.
The other problem I had initially was being able to reference the DaysLeftModel class from my unit test code. I couldn’t figure out anyway of importing the model code, before this very helpful blog post by Andrew Bancroft pointed out the way of configuring the build settings to automatically create a module.
For the date logic of calculating the difference between two dates ignoring weekends was a little tricky, but as usual the Internet was my friend and with the help of TDD and the algorithm outlined in this article by Alec Pojidaev I managed to get it working correctly.
So I’m happy to be up and running in Swift, and the code is up at GitHub if you’re interested.
I think I’ll next tackle storing these settings in a local datastore, as well as synching them with the cloud to share across devices.
Previous posts in the series
The code for the project is also available on GitHub
04 Feb 2015
I’m currently in-between contracts, so as promised last week I’m going to try developing a new app in Swift "in the open" and see how we get on.
My idea is to write a simple app that basically counts down how many days left until a certain date. This was inspired by the fact that in my last contract I used a spreadsheet to count down how much I had left to go (it wasn’t that bad really!)
I wanted something simple enough that could be completed in a few days - even though I know very little Swift before starting - and could be extended into an Apple Watch app.
Now there are hundreds of similar apps out there in the app store already, so this isn’t going to be groundbreaking in any way, but hopefully when it’s done it’ll find a small audience.
Before starting coding, obviously I want to do a little planning.
I’m very much a believer in doing just enough planning to get started along the right path, and if I had a test team enough information for them to understand what the app should do (but no more).
I’ve finally broken into my Evernote Moleskin notebook to sketch out a mini-design for the main app, and used the Evernote Scannable app to snap a picture:
Beautiful or what?
More usefully, I’m tracking the actual tasks in a Trello board which you should be able to see if you’re interested.
The initial tasks on the backlog - in probable order of development - are:
- Code to handle settings in iCloud
- Settings view to handle input etc.
- Simple main page to show days left
- Unit tests for calculations
- Daily notifications
- Today screen widget
- Watch extension
- Main page animations
18 Jan 2015
It’s clearly been a while since I updated my blog here, so I thought I’d give a quick update, and then share
my plan for getting me to share a bit more regularly what I’m up to.
Since my last post (6 months ago!) I’ve shipped my second iOS app - and Instagram client focusing on location called
Pixagogo. I learnt a hell of a lot making it,
and we have regular users from all around the world enjoying a different way of enjoying Instagram pictures.
We’ve also shipped several updates to our Daily Optimiser app, and now it’s
a paid app we have a small band of regular and hopefully happy users.
Unfortunately my fledgling business isn’t bringing in enough money to pay the bills yet, so for the last few
months I’ve been contracting at Sage in Newcastle working on a confidential project
doing financial website stuff (which is as much as I can and want to say).
While we ponder our next major app, I want to keep learning by building things. So my plan is
to build an app in the open where I can do the following things:
- Build something in Swift
- Something simple that I can ship in a few hours work
- Use the WatchKit SDK for something that might work on the Apple Watch when it ships
- Share the code on Github
- Blog about what I’m learning along the way
I have an idea what I’m going to do, and hopefully will start working on this during the next week.
If that’s true, there should be a new post here a bit sooner than the last interval :(
03 Jul 2014
So I’ve left Microsoft/Bing once again (lost count how many times I’ve come and gone).
My contract had expired at the end of June, and I think it’s time to do something away from search for a while.
I’m currently looking for contract work where I can be more flexible in my location - which I guess
means working at home for most of the time.
Over the last few months I’ve been working hard on the all-new iPad version of Daily Optimiser app.
I’ve learnt a hell of a lot about iOS development in the process, and am really proud of what we’ve built.
Checkout the website for full details of what the app does.
It should be in the App Store within days (assuming it passes the review process), but if you want to be a beta tester
for this or future versions, drop me an email and I’ll set you up.
Now I have a bit more time I’m hoping to blog a lot more about what I’m learning along the way. We will see as I’ve said that before :)