Puvanarajan
Puvanarajan

Reputation: 2906

Swift access self.init

I have the classes like this.

protocol BaseProtocol {

    init()
    init(json : SwiftyJSON.JSON)

    func create(parameter : [String : Any], url : ApiEnpoint, success:@escaping(_ responseObject: NSObject)->(),failure:@escaping(_ failedMsg:String)->()) 
}


class BaseModel: NSObject, BaseProtocol {

    required override init() {
    }

    required convenience init(json: JSON) {
        self.init()
    }

 func create(parameter: [String : Any], url: ApiEnpoint, success: @escaping (NSObject) -> (), failure: @escaping (String) -> ()) {

        WebAPI.instance.requestPOSTURL(endPoint: url, parameter: parameter, success: { (response) in

            success(self.init(json: response))
        }) { (faile) in
            failure(faile as! String)
        }
    }
}


class A : BaseModel {

required convenience init(json: JSON) {
        self.init()
// Assign the json values
    }

func createUser() {
create(parameter:pa, url:ApiEnpoint.UserRegistration, success: { (ob) in

        }) { (fa) in

        }
}
}

This is the code structure I am using. I want to access

self.init(json: response)

Inside the webapi block. But its not working. Anyone have any idea?

Upvotes: 1

Views: 128

Answers (1)

Sulthan
Sulthan

Reputation: 130102

You cannot call init on self unless you are in the middle of initialization. You can call init only when creating a new instance, therefore you need to prepend it with a class name. You probably want something like this:

type(of: self).init(json: response)

However, the whole process is a bit strange since you need an instance of A to create a new instance of A in createUser.

You should probably make create to be a class method, or rather, you should properly split your entity classes from your API methods.

For example, a service with a generic method:

class MyService {
    func create<Entity: BaseProtocol>(parameter: [String: Any], url: ApiEnpoint, success: @escaping (Entity) -> (), failure: @escaping (String) -> ()) {

        WebAPI.instance.requestPOSTURL(endPoint: url, parameter: parameter, success: { (response) in
            success(Entity(json: response))
        }) { (faile) in
            failure(faile as! String)
        }
    }
}

(note the success handler will return the correct type now).

You could also make your API URL to be a part of the protocol (e.g. as a static var or static function returning the URL), therefore your could use one create method for all your entities without the need for createUser.

Upvotes: 2

Related Questions