user3591436 user3591436 - 3 months ago 69
Swift Question

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

}

Answer

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.