Search code examples
iosjsonswiftuiimagesdwebimage

IOS load images from URL using SDWebImage


I'm trying to load images from a json URL with the following but I get an error on [cell.imageView setImageWithURL:[NSURL URLWithString:@"coffeemugDirectLink"] placeholderImage:[UIImage imageNamed:@"heart.png"]]; the errors are Expected ',' separator and Expected expression in container literal What am I doing wrong? How can I load the URLs from json into my cell in UICollectionView?

import UIKit
import SDWebImage


class TopratedVC: BaseViewController {

        @IBOutlet var collectionview: UICollectionView!
        @IBOutlet var Image: UIImageView!

    //Our web service url
    let URL_GET_coffeemugs:String = "http://coffeemugs.com/ios/feed.php"


    override func viewDidLoad() {
        super.viewDidLoad()
        addSlideMenuButton()
        // Do any additional setup after loading the view.

        //SDWebimage stuff
        let imageView = UIImageView()


        //created NSURL
        let requestURL = NSURL(string: URL_GET_coffeemugs)


        //creating NSMutableURLRequest
        let request = NSMutableURLRequest(URL: requestURL!)

        //setting the method to post
        request.HTTPMethod = "GET"

        //creating a task to send the post request
        let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
            data, response, error in

            //exiting if there is some error
            if error != nil{
                print("error is \(error)")
                return;
            }

            //parsing the response
            do {
                guard let coffeemugs = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray else {
                    //Doesn't exist, or isn't an NSArray
                    return
                }

                for coffeemug in coffeemugs {
                    //getting the data at each index
                    let coffeemugName = coffeemug["name"] as! String
                    let coffeemugDirectLink = coffeemug["direct_link"] as! String
                    let coffeemugImage = coffeemug["image"] as! String

                    //displaying the data
                    print("name -> ", coffeemugName)
                    print("direct_link -> ", coffeemugDirectLink)
                    print("image -> ", coffeemugImage)
                    print("===================")
                    print()

                }


            } catch {
                print(error)
            }
        }

        // Make cell
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)


            [cell.imageView setImageWithURL:[NSURL URLWithString:@"coffeemugDirectLink"] placeholderImage:[UIImage imageNamed:@"heart.png"]];            

            return cell
        }


        //executing the task
        task.resume()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

Solution

  • You have a couple of problems with your code. The one you are asking about is caused by dumping some Objective-C syntax into the middle of a Swift program, but your bigger problem is that you aren't storing the data you retrieved from the API anywhere that your cellForItemAtIndexPath can get it.

    Additionally, cellForItemAtIndexPath needs to be an instance method on your view controller class, where it can be called by the UICollectionView as required. You can't put it as an inline function and hope that it will work.

    You need to create an array to store your mugs and a struct to put in the array.

    struct Mug {
        var name: String
        var directLink: String
        var image: String
    }
    
    import UIKit
    import SDWebImage
    
    class TopratedVC: BaseViewController, UICollectionViewDataSource {
    
        @IBOutlet var collectionview: UICollectionView!
        @IBOutlet var Image: UIImageView!
    
        var mugs = [Mug]()
        var placeholderImage = UIImage(named:"heart.jpg")!
    
        //Our web service url
        let URL_GET_coffeemugs = "http://coffeemugs.com/ios/feed.php"
    
        override func viewDidLoad() {
            super.viewDidLoad()
            //     addSlideMenuButton()
            // Do any additional setup after loading the view.
    
            //created NSURL
            if let requestURL = NSURL(string: URL_GET_coffeemugs) {
                //creating NSMutableURLRequest
                let request = NSMutableURLRequest(URL: requestURL)
                //setting the method to post
                request.HTTPMethod = "GET"
                //creating a task to send the post request
                let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
                    data, response, error in
                    //exiting if there is some error
                    if error != nil{
                        print("error is \(error)")
                        return;
                    }
    
                    //parsing the response
                    do {
                        guard let coffeemugs = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSArray else {
                            //Doesn't exist, or isn't an NSArray
                            return
                        }
    
                        var newMugs=[Mug]()
    
                        for coffeemug in coffeemugs {
                            //getting the data at each index
                            let coffeemugName = coffeemug["name"] as! String
                            let coffeemugDirectLink = coffeemug["direct_link"] as! String
                            let coffeemugImage = coffeemug["image"] as! String
    
                            let newMug = Mug(name:coffeemugName,
                                             directLink: coffeemugDirectLink,
                                             image:coffeemugImage)
                            newMugs.append(newMug)
                            //displaying the data
                            print("name -> ", coffeemugName)
                            print("direct_link -> ", coffeemugDirectLink)
                            print("image -> ", coffeemugImage)
                            print("===================")
                            print()
    
                        }
                        dispatch_async(dispatch_get_main_queue(),{
                            self.mugs = newMugs
                            self.collectionview.reloadData()
                        })
    
                    } catch {
                        print(error)
                    }
                }
                //executing the task
                task.resume()
            }
        }
    
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
        {
            return self.mugs.count
        }
    
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
            let mug = self.mugs[indexPath.item]
            if let imageURL = NSURL(string:mug.image) {
                cell.imageView.setImageWithURL(imageURL,placeholderImage:self.placeholderImage)
            } else {
                cell.imageView.image = self.placeholderImage
            }
            return cell
        }
    }
    

    Some purists may complain about my force unwrapping of the placeholder image, but honestly if that fails you have something messed up in your application assets and a crash will tell you this at development time.