I've got a syntax issue that has hung me up for a couple of days now, trying to work out a safe/correct/elegant way to handle derived linked objects. Let me layout what works before I present the specific problem:
This works great for me currently:
open class DAOAccount: DAOBaseObject {
// MARK: - Class Factory methods -
open class var userType: DAOUser.Type { DAOUser.self }
open class func createUser() -> DAOUser { userType.init() }public var linkedUser: DAOUser?
func linkUser(userId: String) {
var newUser = Self.createUser()
newUser.id = userId
linkedUser = newUser
}
}
This is in a lower-level generic library. In the primary application code, we have an APPAccount (and an APPUser object) which are derived from their DAO ancestors:
public class APPAccount: DAOAccount {
// MARK: - Class Factory methods -
override open class var userType: DAOUser.Type { APPUser.self }
}
There's obviously much more than just this simple example, but it also makes use of objects being Codable, using the decodable creations when pulling in objects from an API (for example), As in this code:
try container.decodeIfPresent(Self.userType, forKey: key)
By doing this, the proper object type is instantiated, even without the library know the specific object type. I think this should give a general idea of what I'm doing, and how I'm approaching it.
Currently, this part is working great. The lower-library creates the User object as an APPUser, even though it doesn't exist in-scope to the library.
So, now my new problem is a case where the Account object now needs to be able to load an array of users from the API. Hence, I tried this inside the DAOAccount class:
open class var userArrayType: [DAOUser].Type { [DAOUser].self }
And to load the array:
try container.decodeIfPresent(Self.userArrayType, forKey: key)
This APPEARED to work fine in my testing....it compiled and ran without a hitch.....UNTIL I added this line in the APPAccount object:
override open class var userArrayType: [DAOUser].Type { [APPUser].self }
....and....BOOM! The compile failed with "Type of expression is ambiguous without more context".
My simple assumption at this point is that [APPUser] is not considered derived from [DAOUser] and therefore, even though APPUser "isa" DAOUser....[APPUser] is NOT a [DAOUser].
So, if I can't change the type of the objects inside the array to APPUser, then the array decoder will create an array of the base DAOUser objects....but I need it to create an array of APPUser objects.
I've racked my brain on this one and can't figure out something that will work correctly....specifically with the Codable methods.