Search code examples
iosswiftparse-platformuicollectionviewsdwebimage

SDWebImage implementation in parse using Swift


I am using parse to retrieve my images and labels and display it on a collection view. The problem was that the collection view loads all the images and labels at once making the load time long and memory usage was high. I was thinking that I would load 10 cells each time however I was recommended to use SDWebImage to make the app lighter. However I don't know how to implement it with parse using swift. I am suspecting that I would put some code in this piece of code below

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("newview", forIndexPath: indexPath) as! NewCollectionViewCell
    let item = self.votes[indexPath.row]


    let gesture = UITapGestureRecognizer(target: self, action: Selector("onDoubleTap:"))
    gesture.numberOfTapsRequired = 2
    cell.addGestureRecognizer(gesture)


    // Display "initial" flag image
    var initialThumbnail = UIImage(named: "question")
    cell.postsImageView.image = initialThumbnail

    // Display the country name
    if let user = item["uploader"] as? PFUser{
        item.fetchIfNeeded()
        cell.userName!.text = user.username


        var profileImgFile = user["profilePicture"] as! PFFile
        cell.profileImageView.file = profileImgFile
        cell.profileImageView.loadInBackground { image, error in
            if error == nil {
                cell.profileImageView.image = image
            }
        }

        var sexInt = user["sex"] as! Int
        var sex: NSString!
        if sexInt == 0 {
            sex = "M"
        }else if sexInt == 1{
            sex = "F"
        }

        var height = user["height"] as! Int
        cell.heightSexLabel.text = "\(sex) \(height)cm"



    }

    if let votesValue = item["votes"] as? Int
    {
        cell.votesLabel?.text = "\(votesValue)"
    }

    // Fetch final flag image - if it exists
    if let value = item["imageFile"] as? PFFile {
        println("Value \(value)") 
        cell.postsImageView.file = value
        cell.postsImageView.loadInBackground({ (image: UIImage?, error: NSError?) -> Void in
            if error != nil {
                cell.postsImageView.image = image
            }
        })
    }

    return cell
}

I have implemented SDWebImage using Pods and have imported through the Bridging Header. Is there anyone who knows how to implement SDWebImage with parse using Swift?


Solution

  • You should rethink your approach -

    I believe you are using collectionViewDelegate method - collectionView(_:cellForItemAtIndexPath:)

    this fires every time the collection view needs a view to handle.

    In there you can access the cell imageView and set its image (For Example)-

    cell.imageView.sd_setImageWithURL(url, placeholderImage:placeHolderImage, completed: { (image, error, cacheType, url) -> Void in  })
    

    And if you wish to fade in the image nicely, you could -

    cell.imageView.sd_setImageWithURL(url, placeholderImage:placeHolderImage, completed: { (image, error, cacheType, url) -> Void in
                if (cacheType == SDImageCacheType.None && image != nil) {
                    imageView.alpha = 0;
                    UIView.animateWithDuration(0.0, animations: { () -> Void in
                        imageView.alpha = 1
                    })
                } else {
                    imageView.alpha = 1;
                }
            })
    

    EDIT

    I see the you use Parse, so you don't need SDWebImage, you need to use Parse - PFImageView, It will handle your background fetch for the image when it loads. You will need to save reference to your PFObject, but I believe you already do that.

    For example (inside your cellForItemAtIndexPath)-

    imageView.image = [UIImage imageNamed:@"..."]; // placeholder image
    imageView.file = (PFFile *)someObject[@"picture"]; // remote image
    
    [imageView loadInBackground];