I believe this problem isn't too hard.
Usually with Swift segmentation faults are when you try to set the value of a constant (let) quantity, or try to set the value of something that hasn't been properly declared.
I can spot one such instance here:
required init(json: JSON) {
bytesLeft = json["someProperty"].stringValue
}
There's two things wrong with this example. You have a (designated) initialiser which terminates without setting the property someProperty and you haven't declared the variable bytesLeft.
So now the problem (which I really should have spotted before) is that * modelClass* just is not a class (or otherwise initialisable type). To cannot directly access a protocol, you can only access a class conforming to a protocol. The compiler didn't spot this because you did something sneaky with .Type.
When I say access, I mean functions and properties, including initialisers.
Only a class can create an instance of a class, which has itself as the type of the instance, and protocols can't have bonafide instances themselves.
If you think carefully about it, it is impossible to well-define what you are trying to do here. Suppose we had the protocol
protocol JSONModel {
init(json: JSON)
}
but then two classes:
class CurrentDownload: JSONModel {
let someProperty: String
required init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
class FutureDownload: JSONModel {
let differentProperty: String
required init(json: JSON) {
//Different code.
differentProperty = json["differentProperty"].stringValue
}
}
whereas before one might argue that
JSONModel.Type(json: JSON)
(this code is equivalent to your code) should compile and run because we have given an implementation of init, we now can't deny that there is confusion - which implementation should we use here?? It can't choose one, and most would argue that it shouldn't try, and so it doesn't.
What you need to do is initialise with some class.
If you are looking for a minimal class that adheres to JSONModel and no more, you'll need to write such a class e.g.
class BasicJSONModel: JSONModel {
let someProperty: String
required init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
Then do
private let modelClass: BasicJSONModel//.Type not needed with a class
let model = modelClass(json: modelJSON)
of course this is probably silly and one may just write
let model = BasicJSONModel(json: modelJSON)
Or you could just write a common superclass if the protocol's only use is for this:
class SuperJSONModel {
let someProperty: String//This is not needed of course and you could just strip down to the init only.
init(json: JSON) {
//Some other code perhaps.
someProperty = json["someProperty"].stringValue
}
}
and then is you wanted to check that some object is "conforming" to the what was the JSONModel, you simply check that it is a subclass of SuperJSONModel.