Alamofire 在 UICollectionView 的实际应用,很简单,大概记录下:
首先用 Alamofire 在 ViewDidload 中获取到 PhotoInfo 对象的数组,PhotoInfo 是我们创建的 Model 对象,该对象包含一些照片的基本信息,如 imageUrl,并不包含实际的 image 图片
func populatePhotos() { // 用 populatingPhotos 表示是否正在下载 ing,是,直接退出 if populatingPhotos { return } populatingPhotos = true Alamofire.request(Five100px.Router.PopularPhotos(self.currentPage)).responseJSON() { (_, _, JSON, error) in if error == nil { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { let photoInfos = ((JSON as! NSDictionary).valueForKey("photos") as! [NSDictionary]) .filter{ ($0["nsfw"] as! Bool) == false } .map{ PhotoInfo(id: $0["id"] as! Int, url: $0["image_url"] as! String) } // 用 lastItem 记录 currentPage 页面的照片数量,然后下次就可以从这个位置接着取图片,第一次为 0 let lastItem = self.photos.count self.photos.addObjectsFromArray(photoInfos) let indexPaths = (lastItem..<self.photos.count).map { NSIndexPath(forItem: $0, inSection: 0) } // 在主线程中更新新获取到数据 dispatch_async(dispatch_get_main_queue()) { self.collectionView?.insertItemsAtIndexPaths(indexPaths) } // 每次只刷新 1 页 self.currentPage++ } } // 重置下载指示器 self.populatingPhotos = false } }
具体的图片下载要放到 Cell 里去做,这里给每一个 Cell 都加了一个 request 属性
var request: Alamofire.Request?
每一个 Cell 都保持着一个 Request,该 request 从发起请求,到得到数据,除了将 image 赋值需要你完成,其他整个过程 Alamofire 都替你封装好了
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier(PhotoBrowserCellIdentifier, forIndexPath: indexPath) as! PhotoBrowserCollectionViewCell let imageURL = (photos.objectAtIndex(indexPath.row) as! PhotoInfo).url cell.request?.cancel() // 这里用到了 cache,如果缓存已经存在了,就用缓存中的数据,不用发起网络请求了 if let image = self.imageCache.objectForKey(imageURL) as? UIImage { cell.imageView.image = image } else { cell.imageView.image = nil // 当前 cell 对应一个请求,设置请求的时候,同时执行了『从发起请求到得到结果,再到给 // image赋值的整个过程』网络通讯过程是异步的,Alamofire 替你封装好了,但一旦下载到数据 // 就会回到主线程,执行 callback block 里设置 cell image 的代码 cell.request = Alamofire.request(.GET, imageURL).validate(contentType: ["image/*"]).responseImage { request, _, image, error in if error == nil && image != nil { self.imageCache.setObject(image!, forKey: request.URLString) cell.imageView.image = image } else { } } } return cell }