I'm trying to create a protocol in Swift I can use for object construction. The problem I'm running into is that I need to store the type information so the type can be constructed later and returned in a callback. I can't seem to find a way to store it without either crashing the compiler or creating build errors. Here's the basics (a contrived, but working example):
protocol Model {
init(values: [String])
func printValues()
}
struct Request<T:Model> {
let returnType:T.Type
let callback:T -> ()
}
We have a simple protocol that declares a init
(for construction) and another func printValues()
(for testing). We also define a struct we can use to store the type information and a callback to return the new type when its constructed.
Next we create a constructor:
class Constructor {
var callbacks: [Request<Model>] = []
func construct<T:Model>(type:T.Type, callback: T -> ()) {
callback(type(values: ["value1", "value2"]))
}
func queueRequest<T:Model>(request: Request<T>) {
callbacks.append(request)
}
func next() {
if let request = callbacks.first {
let model = request.returnType(values: ["value1", "value2"])
request.callback(model)
}
}
}
A couple things to note: This causes a compiler crash. It can't figure this out for some reason. The problem appears to be var callbacks: [Request<Model>] = []
. If I comment out everything else, the compiler still crashes. Commenting out the var callbacks and the compiler stops crashing.
Also, the func construct
works fine. But it doesn't store the type information so it's not so useful to me. I put in there for demonstration.
I found I could prevent the compiler from crashing if I remove the protocol requirement from the Request struct: struct Request<T>
. In this case everything works and compiles but I still need to comment out let model = request.returnType(values: ["value1", "value2"])
in func next()
. That is also causing a compiler crash.
Here's a usage example:
func construct() {
let constructor = Constructor()
let request = Request(returnType: TypeA.self) { req in req.printValues() }
//This works fine
constructor.construct(TypeA.self) { a in
a.printValues()
}
//This is what I want
constructor.queueRequest(request)
constructor.next() //The callback in the request object should be called and the values should print
}
Does anyone know how I can store type information restricted to a specific protocol to the type can later be constructed dynamically and returned in a callback?
If you want the exact same behavior of
next
I would suggest to do this:Now you can call
next
with your values. Hopefully this works for you.EDIT: Made some changes to the closure type and the
next
function