首先,我认为没有必要像你这样堆叠层,例如将验证功能作为一个层添加,会增加耦合性,使该层依赖于下面的层(解析、网络等),相反,为什么不将验证分离出来,使其仅依赖于数据?
class ViewController: UIViewController {
var validator = InputValidator()
override func viewDidLoad() {
super.viewDidLoad()
do {
try validator.validateInput("INPUT")
try Fetcher.requestDataWithParams("INPUT")
}
catch {
handleError(error)
}
}
}
现在验证功能不依赖于其他层,通信流程如下:
视图控制器 <---> 解析层 <---> 网络层
我已经重命名了这些层,但它们不一定要像这样,您可以添加或删除层。
如果我尝试解释我的方法,可能会有点复杂,所以我将使用之前的层举个例子,首先是底层:
class NetworkingLayer {
class func requestData(params: AnyObject, completion: (getResult: () throw -> AnyObject) -> Void) -> Void {
session.dataTaskWithURL(url) { (data, urlResponse, var error) in
if let error = error {
completion(getResult: { throw error })
} else {
completion(getResult: { return data })
}
}
}
}
我省略了一些代码部分,但是核心思想是要执行任何必要的步骤使图层正常工作(例如创建会话等),并始终通过完成闭包进行通信;上面的图层看起来像这样:
class ParsingLayer {
class func requestObject(params: AnyObject, completion: (getObject: () throw -> CustomObject) -> Void) -> Void {
NetworkingLayer.requestData(params, completion: { (getResult) -> Void in
do {
let data = try getResult()
let object = try self.parseData(data)
completion(getObject: { return object })
}
catch {
completion(getObject: { throw error })
}
})
}
}
请注意,完成闭包不同,因为每个层都添加了功能,返回的对象可能会改变。另外请注意,
do
语句内部的代码可能会出现两种故障:第一种是网络调用失败,第二种是无法解析来自网络层的数据; 向上层的通信总是通过完成闭包进行的。
最后,ViewController可以使用在此情况下Parsing层期望的闭包来调用下一层,并能够处理任何层中产生的错误。
override func viewDidLoad() {
super.viewDidLoad()
do {
try validator.validateInput("INPUT")
try ParsingLayer.requestObject("INPUT", completion: { (getObject) in
do {
let object = try getObject()
try self.validator.validateOutput(object)
print(object)
}
catch {
self.handleError(error)
}
})
catch {
handleError(error)
}
}
请注意,完成闭包中有一个
do catch
,这是必要的,因为调用是异步进行的,现在响应已经通过所有层,并实际上已更改为更专业的类型,您甚至可以验证结果而不必需要为验证功能创建一个层。
希望能对您有所帮助。