Note — This article is now outdated. There’s a new article with updated info here.
When working on a project not too long ago, My teammate and I came across the following situation.
We started developing the project on Swift 2.0 and moved over to 2.1 with the released of Xcode 7.1. We used a class conforming to the
NSCoding protocol to store the basic information about the app’s user. Among the many details stored of the user, one particular detail is an array of Swift structure instances. We used this to store details about the user’s social connections. And, this property was an optional. We wrote the required boilerplate archiving and unarchiving code to the class and it was all set. We forgot about the class and moved on to other things in the project. We realised that the class wasn’t archiving the swift structure instances only after a while. After a bit of digging, we learnt that structure instances aren’t convertible to AnyObject. And, since that property was an optional, it wasn’t leading to any crashes when unarchiving, instead it just gave out a nil value.
The following is an example I wrote for this article, recreating a similar situation.
Here, the structure
Connections contains basic information about a user’s social connections. The class
ProfileDetails has the property
connections which is an array of the said structure. The static method
getProfileDetails() gives an instance of the same class after unarchiving. The method
saveProfileDetails() sets the modified property values and archives class object to file with the modifications preserved.
The problem we encountered was when assigning an array of
Connections instances to the
connections property, it threw no error and everything was merry. Except, when accessing
connections property later on always gave a
This happened because structure instances cannot be represented as
AnyObject, which is quite obvious when you know
AnyObject is only for class instances. And, the swift type
Any (which supports structure instances) is not accepted in the
The workaround we used was to introduce a class similar to the structure and convert the array of structure instances to that class’s objects just before archiving. And doing the opposite when unarchiving. We did this instead of just using the class because we needed a value type for that property in our project.
Thank you Karthik Mitta.