swift3面向协议编程实现Alamofire封装

来源:互联网 发布:如何访问google 知乎 编辑:程序博客网 时间:2024/05/16 09:01

1、原先的实现过程我们一般使用的是Alamofire,对其单例封装

////  NetworkTools.swift////  Created by targetcloud on 2017/3/26.//  Copyright © 2017年 targetcloud. All rights reserved.////原来1import UIKitimport Alamofireenum MethodType {    case get    case post}class NetworkTools {    static let share : NetworkTools = NetworkTools()        private init(){}        //参数的finishedCallback闭包在26行使用了,而使用的环境又是一个闭包,则需要加@escaping    func requestData(_ type : MethodType, URLString : String, parameters : [String : Any]? = nil, finishedCallback :  @escaping (_ result : Any) -> ()) {        let method = type == .get ? HTTPMethod.get : HTTPMethod.post        Alamofire.request(URLString, method: method, parameters: parameters).responseJSON { (response) in            guard let result = response.result.value else {                print(response.result.error ?? " --- 网络请求发生了错误 --- ")                return            }            finishedCallback(result)        }    }}

2、在ViewModel中调用自己的封装的网络工具类

////  TGGiftViewModel.swift////  Created by targetcloud on 2017/3/26.//  Copyright © 2017年 targetcloud. All rights reserved.//import UIKit//原来2class TGGiftViewModel: NSObject {    var results : Array<TGGiftPackage> = []        func requestGiftData(_ complection : @escaping () -> ()) {        NetworkTools.share.requestData(.get, URLString: "http://qf.56.com/pay/v4/giftList.ios", parameters: ["type":0,"page":1,"rows":150]) { (result) in//            print(result)            guard let resultDict = result as? [String:Any] else {return}            guard let typesDictData = resultDict["message"] as? [String:Any] else {return}            for i in 0..<typesDictData.count{                guard let typeDict = typesDictData["type\(i+1)"] as?[String:Any] else {continue}                self.results.append(TGGiftPackage(dict:typeDict))            }            self.results = self.results.filter({ $0.t != 0 }).sorted(by: { $0.t > $1.t })//            print(self.results)            complection()        }    }}

附VM中使用的两个Model,作为例子,读者可以忽略(注意这里使用MVVM设计模式)

////  TGGiftPackage.swift////  Created by targetcloud on 2017/3/26.//  Copyright © 2017年 targetcloud. All rights reserved.//import UIKitclass TGGiftPackage: NSObject {    var t : Int = 0    var title : String = ""    var giftModels : [TGGiftModel] = []        init(dict : [String:Any]) {        super.init()        setValuesForKeys(dict)    }        override func setValue(_ value: Any?, forKey key: String) {        if key == "list"{            if let arr = value as? [[String : Any]]{                for dict in arr{                    giftModels.append(TGGiftModel(dict:dict))                }            }        }else{            super.setValue(value, forKey: key)        }    }        override func setValue(_ value: Any?, forUndefinedKey key: String) {            }}

////  TGGiftModel.swift////  Created by targetcloud on 2017/3/26.//  Copyright © 2017年 targetcloud. All rights reserved.//import UIKitclass TGGiftModel: NSObject {        var coin :Int = 0    var img : String = ""    var img2 : String = ""    var gUrl : String = ""    var subject : String = "" {        didSet{            if subject.contains("有声"){                subject = subject.replacingOccurrences(of: "有声", with: "")            }        }    }        init(dict : [String:Any]) {        super.init()        setValuesForKeys(dict)    }     override func setValue(_ value: Any?, forUndefinedKey key: String) {     }}

3、使用

        fileprivate lazy var giftVM : TGGiftViewModel =  TGGiftViewModel()        //其他代码。。。        giftVM.requestGiftData {            print(self.giftVM.results)            self.pageCollectionView.reloadData()            var titles : [String] = []            for (i,v) in self.giftVM.results.enumerated() {                titles.append( v.title == "" ? "组\(i+1)" : v.title)            }            self.pageCollectionView.setTitles(titles: titles)        }

下面使用面向协议的方式来实现,来对比面向对象的设计方式有何不同

1、制作协议

////  Requestable.swift////  Created by targetcloud on 2017/3/26.//  Copyright © 2017年 targetcloud. All rights reserved.////现在1import Foundationimport Alamofireprotocol Requestable {    var URLString : String {get}    var type : MethodType {get}    var parameters : [String : Any] {get}    associatedtype ResultData    func parseResult(_ result : Any)//MARK:- result由协议完成     var parseData : ResultData {get}}extension Requestable{    //只传闭包 其他不要了 _ type : MethodType, URLString : String, parameters : [String : Any]? = nil, 此三者由协议完成    func requestData(finishedCallback :  @escaping () -> ()) {//MARK:- (_ result : Any) -> () result由协议parseResult完成 1        let method = type == .get ? HTTPMethod.get : HTTPMethod.post        Alamofire.request(URLString, method: method, parameters: parameters).responseJSON { (response) in            guard let result = response.result.value else {                print(response.result.error ?? " --- 网络请求发生了错误 --- ")                return            }            self.parseResult(result)//MARK:- result由协议完成 3            finishedCallback()//MARK:- finishedCallback(result) result由协议完成 2        }    }}

2、VM的改变

////  TGGiftViewModel.swift////  Created by targetcloud on 2017/3/26.//  Copyright © 2017年 targetcloud. All rights reserved.//import UIKit//原来2/*class TGGiftViewModel: NSObject {    //lazy var giftModels : [TGGiftModel] = [TGGiftModel]()    var results : Array<TGGiftPackage> = []        func requestGiftData(_ complection : @escaping () -> ()) {        NetworkTools.share.requestData(.get, URLString: "http://qf.56.com/pay/v4/giftList.ios", parameters: ["type":0,"page":1,"rows":150]) { (result) in//            print(result)            guard let resultDict = result as? [String:Any] else {return}            guard let typesDictData = resultDict["message"] as? [String:Any] else {return}            for i in 0..<typesDictData.count{                guard let typeDict = typesDictData["type\(i+1)"] as?[String:Any] else {continue}                self.results.append(TGGiftPackage(dict:typeDict))            }            self.results = self.results.filter({ $0.t != 0 }).sorted(by: { $0.t > $1.t })//            print(self.results)            complection()        }    }}*///现在2class TGGiftViewModel: NSObject,Requestable {    var URLString: String = "http://qf.56.com/pay/v4/giftList.ios"    var type : MethodType = .get    var parameters : [String:Any] = ["type":0,"page":1,"rows":150]    typealias ResultData = [TGGiftPackage]    var parseData : Array<TGGiftPackage> = []}extension TGGiftViewModel {    func parseResult(_ result : Any) {        guard let resultDict = result as? [String:Any] else {return}        guard let typesDictData = resultDict["message"] as? [String:Any] else {return}        for i in 0..<typesDictData.count{            guard let typeDict = typesDictData["type\(i+1)"] as?[String:Any] else {continue}            self.parseData.append(TGGiftPackage(dict:typeDict))        }        self.parseData = self.parseData.filter({ $0.t != 0 }).sorted(by: { $0.t > $1.t })    }}

3、使用

        //原来3        /*        giftVM.requestGiftData {            print(self.giftVM.results)            self.pageCollectionView.reloadData()            var titles : [String] = []            for (i,v) in self.giftVM.results.enumerated() {                titles.append( v.title == "" ? "组\(i+1)" : v.title)            }            self.pageCollectionView.setTitles(titles: titles)        }        */                //现在3        giftVM.requestData {            //print(self.giftVM.parseData)            self.pageCollectionView.reloadData()            var titles : [String] = []            for (i,v) in self.giftVM.parseData.enumerated() {                titles.append( v.title == "" ? "组\(i+1)" : v.title)            }            self.pageCollectionView.setTitles(titles: titles)//根据网络数据,动态改变标题栏        }

使用面向协议的方式,我们就只需要对协议的属性进行实现,而不用再关心原来的参数调用顺序,

同时对原来的请求逻辑做了业务逻辑层抽取,我们只需实现数据的具体解析逻辑,从而把关注点更焦聚在业务逻辑上,更加符合业务设计需求


关键代码解析

protocol Requestable {

    var URLString : String {get}//1

    var type : MethodType {get}//2

    var parameters :[String : Any] {get}//3

    associatedtype ResultData//4

    var parseData : ResultData {get}//5

    func parseResult(_ result : Any)//6

}


协议中的6个数据属性分别在VM中进行了实现


class TGGiftViewModel: NSObject,Requestable {

    var URLString: String = "http://qf.56.com/pay/v4/giftList.ios"//1

    var type : MethodType = .get//2

    var parameters :[String:Any] =["type":0,"page":1,"rows":150]//3

    typealias ResultData = [TGGiftPackage]//4

    var parseData : Array<TGGiftPackage> = []//5

}


extension TGGiftViewModel {

    func parseResult(_ result : Any) {//6

        guard let resultDict = result as?[String:Any] else {return}

        guard let typesDictData = resultDict["message"] as?[String:Any] else {return}

        for i in 0..<typesDictData.count{

            guard let typeDict = typesDictData["type\(i+1)"] as?[String:Any] else {continue}

            self.parseData.append(TGGiftPackage(dict:typeDict))

        }

        self.parseData = self.parseData.filter({ $0.t != 0 }).sorted(by: { $0.t > $1.t })

    }

}


//4与5 是关联类型,在VM指定


0 0
原创粉丝点击