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

时间:2017-05-22 15:58:25

标签: swift generics alamofire

我正在使用 AlamofireObjectMapper 我需要制作一个带有这样的通用参数的函数:

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)
                }
            }

        })


}

但是我得到了错误:

  

使用未声明的类型'myCustomClass'   的修改   因为你们在评论中回答我我修正了错误,但当我试图调用这种方法时我又遇到了另一个错误

我打电话给那个方法

doSomething(myCustomClass: Promotions)

但我又遇到了另一个错误

  

参数类型'Promotions.Type'不符合预期的类型   'BaseMappable'

这是我的促销课程

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"]
        }




}

我该如何解决?

4 个答案:

答案 0 :(得分:5)

只需将Promotions.self作为参数传递。

doSomething(myCustomClass: Promotions.self)

这将克服您在函数调用中遇到的错误。

答案 1 :(得分:2)

您需要将通用类型T的类型作为参数传递。尝试更改

<WebView
    android:layout_marginTop="?attr/actionBarSize"
    android:id="@+id/WebView_Dash"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

通过

android:layout_marginTop="?attr/actionBarSize"

结果如下:

快捷键4:

Toolbar

然后,您应该调用方法:

myCustomClass : T

答案 2 :(得分:1)

myCustomClass只是sudo docker run -dti hypriot/rpi-node:6.10.0 tail -f /dev/null的输入参数的名称。泛型类型的名称为doSomething,因此DataResponse应为T

答案 3 :(得分:0)

以下是使用AlamofireObjectMapperPromiseKit的解决方案,

  • 用户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"]
        }
    }
    
  • 基于类模板的功能

    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))
                    }
            }
        }
    }
    
  • 用法

在实用程序类中定义

    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)
    }

在视图控制器中使用

    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
        }