简体   繁体   English

试图在Swift中传递Generic类型作为参数

[英]Trying to pass Generic type as parameter in Swift

I am Using AlamofireObjectMapper i need to make a func that take a Generic parameter like that : 我正在使用AlamofireObjectMapper我需要创建一个带有这样的Generic参数的函数:

func doSomething < T : BaseMappable > (myCustomClass : T) 
{
    Alamofire.request("url", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: APIKeys().AuthorizedHeader).responseObject(completionHandler: { ( response :DataResponse<T>) in

             let data = response.result.value

            if let array = data?.objects
            {
                for ar in array
                {
                   self.allPromotions.append(ar)
                }
            }

        })


}

but iam getting error : 但我得到错误:

Use of undeclared type 'myCustomClass' edit as you guys answer me in the comments i put fixed the error but i got another error when iam trying to call this method 使用未声明的类型'myCustomClass' 编辑,因为你们在评论中回答我我修复了错误但是当我试图调用这个方法时我得到了另一个错误

i called the method like that 我这样称呼方法

doSomething(myCustomClass: Promotions)

but i got another error 但我有另一个错误

Argument type 'Promotions.Type' does not conform to expected type 'BaseMappable' 参数类型'Promotions.Type'不符合预期类型'BaseMappable'

and here's my Promotions class 这是我的促销课程

import ObjectMapper


class Promotions : Mappable  {





        var id:Int?
        var workshop_id:Int?
        var title:String?
        var desc:String?
        var start_date:String?
        var expire_date:String?
        var type:String?

        var objects  = [Promotions]()




        required init?(map: Map){

        }

        func mapping(map: Map) {
            id <- map["id"]
            workshop_id <- map["workshop_id"]
            title <- map["title"]
            desc <- map["desc"]
            start_date <- map["start_date"]
            expire_date <- map["expire_date"]
            type <- map["type"]
            objects <- map["promotions"]
        }




}

How can i fix that 我该如何解决这个问题

Just pass the Promotions.self as the parameter. 只需将Promotions.self作为参数传递即可。

doSomething(myCustomClass: Promotions.self)

This'll overcome the error that you are getting in the function call. 这将克服您在函数调用中遇到的错误。

You need to pass as argument the type of Generic Type T. Try changing 您需要将Generic Type T的类型作为参数传递。尝试更改

myCustomClass : T

by 通过

myCustomClass : T.Type

The result would look like: 结果如下:

Swift 4: 斯威夫特4:

    func doSomething<T>(myCustomClass : T.Type) where T : BaseMappable
    {
        Alamofire.request("url", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: APIKeys().AuthorizedHeader).responseObject(completionHandler: { ( response :DataResponse<T>) in

                 let data = response.result.value

                if let array = data?.objects
                {
                    for ar in array
                    {
                       self.allPromotions.append(ar)
                    }
                }

            })
    }

Then, you should call the method: 然后,您应该调用该方法:

doSomething(myCustomClass: Promotions.self)

myCustomClass is just the name of the input parameter to doSomething . myCustomClass只是doSomething的输入参数的名称。 The name of the generic type is T , so DataResponse should be DataResponse<T> . 泛型类型的名称是T ,因此DataResponse应该是DataResponse<T>

Here is the solution using Alamofire , ObjectMapper and PromiseKit , 这是使用AlamofireObjectMapperPromiseKit的解决方案,

  • User Mappable object. 用户可Mappable对象。

     class User: Mappable { var id: Int! var userName: String! var firstName: String? var lastName: String? required init?(map: Map) { } // Mappable func mapping(map: Map) { id <- map["id"] userName <- map["userName"]\\ firstName <- map["firstName"] lastName <- map["lastName"] } } 
  • Class template based function 基于类模板的功能

     func sendRequest<T: Mappable>(_ url: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders? = nil, responseObject: T.Type) -> Promise<T> { return Promise { resolve, reject in Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers) .responseJSON() { response in switch response.result { case .success(let data): let json = JSON(data as Any) let dataObj = json["data"].object let resObj = Mapper<T>().map(JSONObject: dataObj) resolve(resObj!) case .failure(_): reject(self.generateError(message: nil)) } } } } 
  • Usage 用法

Define in utility class 在实用程序类中定义

    func loginWith(userName: String, and password: String) -> Promise<User> {

        let apiPath = "localhost:3000"

        let parameters: Parameters = [
            "email": userName,
            "password": password
        ]

        return sendRequest(apiPath, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil, responseObject: User.self)
    }

Use in view controllers 在视图控制器中使用

    loginWith(userName: name, and: password)
        .then { response -> Void in
            // response is `User` type object!!!
        }
        .catch { error in
            // show error message
        }
        .always {
            // do something like hide activity indicator
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM