1

I a struct model named User.. with the following code

struct User {
    let userId: Double
}

extension User {
    init(json: JSON) {
        self.userId = json["userId"].double!
    }
}

And have normal class with generic like the following

class LoginTask<User>: Operation {

    var userName: String
    var password: String

    init(username: String, password: String) {
        self.userName = username
        self.password = password
    }

    var request: Request {
        return UserRequests.login(username: self.userName, password: self.password)
    }

    func exeute(in dispatcher: Dispatcher, completed: (User) -> Void) {
        do {
            do {
                try dispatcher.execute(request: self.request, completion: { (response, error) in
                    if error == nil {
                        let user = User(json: response)

                    }
                })
            } catch {

            }
        }
    }

}

Operation is a protocol is having associatedtype named Output

now on line

let user = User(json: response)

it gives error

Non-nominal type 'User' does not support explicit initialization

I tried to make User.Type .. but may be I don't fully understand the concept or the error.

Mohamed Emad Hegab
  • 2,665
  • 6
  • 39
  • 64

1 Answers1

4

The User in your class is not the same as the User type you created. It's just a placeholder for any type. You could replace the word User in your class definition with anything e.g. T or Apple and it would still be the same definition.

The compiler knows nothing about whatinit methods User in your class has, hence the error. To make it work properly, you must constrain the type parameter. This is usually done by making it conform to a protocol e.g.

protocol JSONInitable
{
    init(json: JSON)
}

struct User: JSONInitable { ... }
struct Group: JSONInitable { ... }

class LoginTask<PrincipalType: JSONInitable> 
{ 
    ....

    func foo() 
    {
       let user = PrincipalType(json: response)
    }
}

In the above, the LoginTask can be used with both User and Group but not any arbitrary type that doesn't conform to the protocol.

Alternatively, if the class will always use the User type, it doesn't need to be generic.

JeremyP
  • 84,577
  • 15
  • 123
  • 161