下方截图是Alamofire.swift中的一个几个便利方法,都是调用Manager单例中相应的方法,便利方法为了链式调用Request类中的相关方法,所以所有的便利方法都会返回当前Manager单例使用的Request对象。具体如下所示:
download for example:
upload for example:
normal request for example:
上面提到的三种方法最终都会返回Request对象,目的是为了方便调用封装在Request中的方法,比方说查看下载的进度,下面我们举例,其中.progress 和resposne是封装在Request中的方法,然后通过URLSession中的回调方法来调用。
下面以download过程为例,讲解整个过程:
由上面可见,最终调用的Manager里面的download或者是request,或者是upload。其中Manager是一个单例,里面维护了一个session和一个总体外部调用的delegate,其中SessionDelegate是实现了NSURLSessionDelegate,NSURLSessionTaskDelegate,NSURLSessionDataDelegate,NSURLSessionDownloadDelegate四个delegate的方法,而且在里面定义了各个闭包变量,如果开发者需要自己自定义其中闭包回调的实现,则可以重写这些方法。如果开发者不去自定义,则Alamofire库则会调用默认的实现方法。
delegate:SessionDelegate=SessionDelegate()
self.delegate= delegate
self.session=NSURLSession(configuration: configuration, delegate: delegate, delegateQueue:nil)
public class SessionDelegate:NSObject,NSURLSessionDelegate,NSURLSessionTaskDelegate,NSURLSessionDataDelegate,NSURLSessionDownloadDelegate{
}
巧妙的实现机制
在download创建request的时候,将一个闭包回调实现赋值给DownloadTaskDelegate中的一个闭包变量,也就是说让它不给空,所以接下来就回到DownloadTaskDelegate内部,因为在SessionDelegate这个外部层级上我们没有自定义实现闭包的变量,所以会调用默认的的闭包
调用默认的DownloadTaskDelegate的回调函数的闭包,因为在上面一步我们已经赋值了downloadTaskDidFinishDownloadingToURL这个闭包变量,所以下面圈出的地方会执行,在执行let那句的时候,将参数传递进去,闭包函数会去执行上面定义好的闭包体。也就是上面划线部分的return,destination函数是回调函数,这个回调函数会执行download函数体的回调,同时返回值给下面的destination,我们举一个实例:其中的闭包就是上面看到的destination的回调,它有两参数输入对应下面的就是temporaryURL和response,最终把directoryURL.URLByAppendingPathComponent(pathComponent!)这个值赋值给了下面的destination,然后保存了文件。
//default downloading
Alamofire.download(.GET,"https://httpbin.org/stream/100") { temporaryURL, response in
let fileManager =NSFileManager.defaultManager()
let directoryURL = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let pathComponent = response.suggestedFilename
return directoryURL.URLByAppendingPathComponent(pathComponent!)
}
如何重写回调
下面是一个实例,我们可以从Manager中或者SessionDelegate这个代理,这个代理的作用就是获得里面定义的各种闭包变量,在download之后,代码不会进入到temporaryURL参数后面的尾随闭包,只会进入print那边的b闭包,这样就可以实现完全的自定义实现。