Alamofire 学习笔记(三)

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
}

-EOF-

如果感觉此文对你有帮助,请随意打赏支持作者 😘

chengway

认清生活真相之后依然热爱它!

Subscribe to Talk is cheap, Show me the world!

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!