今天看以前写的网络请求的方法如下:
static func listItemWithRefIndex(refIndex: Int, orientation: String, direction: Int, nitems: Int, response: (items: [Item]) -> Void) { var param = [String: AnyObject]() param["ref_index"] = refIndex param["orientation"] = orientation param["direction"] = direction param["nitems"] = items Alamofire.request(Router.ReadList(param)).responseCollection { (_, _, result: Result<[Item]>) -> Void in if let value = result.value { response(items: value) } } }
越看越不爽,如果下次增加方法,请求类型变成了 Student:
static func listItemWithRefIndex(refIndex: Int, orientation: String, direction: Int, nitems: Int, response: (items: [Student]) -> Void) { var param = [String: AnyObject]() // 参数拼接略 // .... Alamofire.request(Router.ReadList(param)).respon seCollection { (_, _, result: Result<[Student]>) -> Void in if let value = result.value { response(items: value) } } }
后面那段关于 Alamofire 的代码重复写了很多次。然后就想再抽一个方法,这个方法的参数有:
问题在于 response 的 Closures中的参数,怎么声明。
ResponseCollectionSerializable
协议 static func sendRequestWithRouter<T: protocol<AnyObject, ResponseCollectionSerializable>>(router: Router, classType: T.Type, completionHandler: (items: [T]) -> ()) { Alamofire.request(router).responseCollection { (_, _, result: Result<[T]>) -> Void in if let value = result.value { completionHandler(items: value) } } }
classTpye: T.Type 中的 T.Type 表示存储 T 这个类型的本身,而 T.self 表示取出其类型,这样就达到我的目的了,最后变成这样:
static func listItemWithRefIndex(refIndex: Int, orientation: String, direction: Int, nitems: Int, response: (items: [Item]) -> Void) { var param = [String: AnyObject]() param["ref_index"] = refIndex param["orientation"] = orientation param["direction"] = direction param["nitems"] = nitems sendRequestWithRouter(Router.ReadList(param), classType: Item.self, completionHandler: response) }