iOS development: new pandemic skills

Here’s yet another suggestion in the sea of unsolicited advice during this pandemic 2020 – learn to code iOS apps. Trust us, we’re speaking from experience. We’re not full-time “coders”. We’re full-time friends, husbands, wives, and entrepreneurs. While some of us our fortunate enough to work from home during this weird time, others aren’t. Whatever the circumstances, we’ve always more time on our hands than we believe. Whether you have 15 minutes every other day or 1 hour every night, dedicate some of that time to iOS development – you’ll thank yourself later.

In fact, research suggests that chunking is a more effective means to learning. That is, the opposite of cramming – spending small, consistent chunks of time yields more results than large, uninterrupted sessions.

In any case, we’d thought we’d share two courses from Udemy that are absolutely invaluable when it comes to picking up iOS development quickly. In fact, these two resources allowed members of our team to make remarkable improvements to their diverse skill set (again, we’re not all full-time coders). The courses aren’t expensive when discounted (we paid $10 per course per person). Promotions are run fairly frequently, so keep checking the website.

Finally, there’s no need for a disclaimer here. We get no referrals or kick-backs of any sort for recommending these videos. We only get the satisfaction of reviewing quality work, recognizing quality work, and hopefully, converting some of you to coders. If we can do it, anyone can do it – seriously.

So, if there was ever a time to pick up iOS development (as a hobby, a side-gig, or career pivot), now is the time.

iOS 13 & Swift 5 – The Complete iOS App Development Bootcamp

Angry Birds, Crossy Road & more: Game Development in Swift 4

swift 5: using plists to store data

Using plists to store data in Swift doesn’t get much attention on the web. Although not the most elegant (or recommended) solution to store data, reading from and writing to property lists is a convenient way to store small bits of data. For example, simple plists can be used to store level data for games.

In the image above, we’ve generated a level set using an external program (think something like python or even Excel). The plist can be dragged-in to any Xcode project and referenced via a few simple lines of code.

Note: you cannot modify a plist included in the main bundle (i.e. dropped into the project as a resource). You’ll need to copy the file over into the users’ documents directory.

Modifying the plist is pretty straightforward. First, check to see if the plist exists in the documents directory. If not, copy it over, otherwise, reference the file.

func reloadData() -> Bool{
        if (try? levelDataURL().checkResourceIsReachable()) == nil {
            guard let originalFile = Bundle.main.url(forResource: Constants.kLevelDataFileName, withExtension: ".plist") else {
                fatalError("Could not locate level data")
            do {
                let originalContents = try Data(contentsOf: originalFile)
                try originalContents.write(to: levelDataURL(), options: .atomic)
                print("Made a writable copy of the level data at \(levelDataURL())")
                return reloadData()
            } catch {
                print("Couldn't copy level data to documents directory")
                return false
        } else {
            if let data = try? Data(contentsOf: levelDataURL()) {
                let decoder = PropertyListDecoder()
                do {
                    levels = try decoder.decode([Level].self, from: data)
                } catch {
                    print("Error loading level data")
                    return false
        return true

You’ll notice a [Level].self reference inside the decoder.code function. In order to decode the property list, you’ll need to define a class that represents the object in the list. Level is the Codable class that can be mapped to the plist.

class Level: Codable {
    var number: Int = 0
    var completed: Bool = false
    var available: Bool = false
    var score: Int = 0
    var speed: Float = 0.0
    var radius: Float = 0.0
    var feedspeed: Int = 0
    var path: [Int] = []
    var time: Int = 0
    var music: String = ""
    var musicStartTime: Int = 0
    var specials: [String] = []
    var orbital_types: [String] = []

Now that we’ve successfully copied over the plist and created an object that describes the each element in the plist array, we can also modify this copy.

       let encoder = PropertyListEncoder()
        do {
            guard let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
                fatalError("Documents directory not found in application bundle.")
            let url = documentsDirectory.appendingPathComponent("\(Constants.kLevelDataFileName).plist")
            let data = try encoder.encode(newLevels)
            try data.write(to: url)
        } catch {
            print("Error saving results: \(error)")

You’ll notice a newLevels reference in the encoder.encode function. This is an array of Level objects that conform to the plist format. You’ll be required to save the whole plist any time you make changes (even to a single element). It should be pretty apparent why this is pretty clunky and not recommended, however, it’s a convenient way to store small chunks of data that don’t need to be modified often.

Happy coding!