user3591436
user3591436

Reputation: 161

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.
    }

}

Upvotes: 0

Views: 8258

Answers (2)

Paulw11
Paulw11

Reputation: 114865

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.

Upvotes: 1

Duncan C
Duncan C

Reputation: 131426

That one line:

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

...is Objective-C code in the middle of your Swift program. That's not going to work. You will need to convert that code to Swift.

I also don't recognize the method you're trying to use, setImageWithURL:placehodlerImage:. Are you using some custom subclass of UIImageView? If so, you'll need to tell us about that subclass, and show us the definition of that function.

EDIT:

Based on the Objective-C code you posted, I'm going to take a guess at converting your code to Swift:

//Make sure the call to NSURL(string:) works. If not, bail out.
guard let imageURL= NSURL(string: "coffeemugDirectLink") else {
  print("unable to convert 'coffeemugDirectLink' to a URL")
  return 
}

//Make sure the call to UIImage(named:) works. If not, bail out.
guard let placeholderImage = UIImage(named: "heart.png") else {
  print("unable to load image with name 'heart.png'")
  return 
}

cell.imageView.setImageWithURL(imageURL, placeholderImage: placeholderImage)

By the way, "coffeemugDirectLink" does not look like a valid string to convert to an NSURL.

Upvotes: 1

Related Questions