Using Codable with Array

I was converting one of my projects to Swift 4 and ran into an issue where I didn’t understand how to use the new Codable protocol to encode and decode an array of my model object. Here’s a little post explaining what I found out:

Repo: https://github.com/garricn/ggn-blog/tree/master/posts

Raw: https://raw.githubusercontent.com/garricn/ggn-blog/master/posts/060517-codable.swift

There’s also a playground in the repo.

Private Property Mix-Match in Swift Extension

Imagine you have a type (enum, struct, class, it doesn’t matter) like so:

struct SomeType {}

Then you add an extension to it with an internal var foo and a private var bar where foo just returns bar and bar returns the string “foo”:

 

Now, when we call SomeType().foo, we get “foo”, right? Right.

SomeType().foo prints “foo”

Then you add another extension to it with another internal var baz and another private var bar where similarly baz returns bar and bar returns the string “baz”:

 

Now, when we call SomeType().baz, we should get “baz”, right? Wrong.

SomeType().baz prints “foo”.

Weird right? What’s going on here?

Let’s try something else. Let’s remove bar from Extension II and see what happens:

 

Interestingly, we get the following error:

'bar' is inaccessible due to 'private' protection level

This is really weird because on the one hand, Extension II’s bar prints “foo”, but when it doesnt have a bar, the compiler throws an error. Weird, right? Why is that? What’s going on here?. This same behavior is present with instance and static properties and methods on enums (static only), structs, and classes.

This also works where the initial bar is in the original type definition and not in an extension:

Thing().foo and Thing.baz both print “foo”

Is this a bug? If not, why is this the correct behavior? Please let me know @garricn

Interestingly too, if you try this in the IBM Swift Sandbox, it crashes!

UPDATE (about 10 minutes later 🙂 Its a known bug!

Line of the Day #001

Line number 5 was super fun to get to.

It does the following:

  1. Gets newValue from set and uses the nil coalescing operator to either:
    1. Return the unwrapped value if newValue is not nil, or
    2. Return an empty string: ""
  2. Then – using the ternary operator – it checks whether the returned value isEmpty (i.e., is an empty string) :
    1. If it is empty, it sets constant to 0.0
    2. Otherwise, it sets constant to 4.0

To get to that line we started with what you can see in the commented out code starting on line 9. Pretty fun stuff 🙂

 

 

Making a Simple Swift Observable

I’ve been practicing reactive programming recently mostly with SwiftBond and I’ve been enjoying it. I’ve mostly just worked with simple observing and binding. So, I thought how – if at all – could I do simple observing in Swift without using a reactive library, key-value observing, or NSNoticationCenter.

I was able to do it using closures, except that I’m running into an issue where I’m forced to make some properties immutable when I would rather not. Take a look at the project and let me know if you can help me with it. Ideally, I would like to be able to make my viewModel property of my ViewController as well as the alertOutput property of my viewModel constants. The issue is that the observe(onNext:) method of my viewModel is mutating. So, how could I do self.onNext = onNext in some other way? How could I make that method non-mutating? What could I do so that I could keep those two properties immutable?

Check out the project on GitHub. Take a look at the code and let me know if you can help.