0

I have an issue with my code, I have parsed out my JSON to the level where I get a URL for an image. I'm trying to populate an image view in a collection view cell with the image that the URL is giving me. Here is my code.

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    var media = NSDictionary()

    @IBAction func SearchBTN(_ sender: AnyObject) {
        getPictures()

    }
    @IBOutlet weak var CollectionView: UICollectionView!
    @IBOutlet weak var searchBoxTF: UITextField!



    func getPictures(){
        let url = URL(string: "http://www.flickr.com/services/feeds/photos_public.gne?tags=baseball&format=json&nojsoncallback=1")
        let session = URLSession(configuration: URLSessionConfiguration.default)
        let task = URLSession.shared.dataTask(with: url!){(data, response, error) in
            if error != nil
            {
                print("Error")
            }
            else
            {
                if let content = data
                {
                    do
                    {
                        let myJSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as? AnyObject
                    //print(myJSON)
                        if let images = myJSON?["items"] as? [[String: AnyObject]]
                        {
                            var media = UIImage()
                            for media in images
                            {
                               // let media = self.media
                                print(media["media"])

                            }


                        }
                    }

                    catch
                    {

                    }
                }
            }
        }
        task.resume()
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        CollectionView.delegate = self
        CollectionView.dataSource = self
        // Do any additional setup after loading the view, typically from a nib.
    }

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


    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return media.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as! ImageCollectionViewCell
        cell.imageView.image = media[indexPath.item]as? UIImage
        return cell
    }

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Ingelbert
  • 3
  • 4
  • Json is not an image. cell.imageView.image = media[indexPath.item]as? UIImage , you are trying to set a JSON value to an UIImage ? –  Feb 14 '17 at 00:25
  • The JSON results contains a URL for a jpeg image that I am trying to get, my code will parse the JSON to get down to the URL. I am unable to extract the URL, so that I am able to use it to populate a collectionViewcell that contains a UIimageView so that I can view the image. Do you have any advice? – Ingelbert Feb 14 '17 at 00:36
  • check my answer I have updated with all you need to know. –  Feb 14 '17 at 00:42
  • @user7454867 if You are still looking for the solution check below to answer or you will find the project in this link https://github.com/huilgolAni19/ParsingJSON – Anirudh R.Huilgol. Jul 06 '17 at 09:58

2 Answers2

1

Your JSON response is not an image.

cell.imageView.image = media[indexPath.item]as? UIImage , you are trying to set a JSON value to an UIImage.

http://www.flickr.com/services/feeds/photos_public.gne?tags=baseball&format=json&nojsoncallback=1

This URL Returns response of JSON with URL's to the actual image.

You then need to download the UIImage from those actual image URLs.

EDIT: (based on your question in comment)

1: You get the NSDictionary JSON Respone.

2: Inside the NSDictionary You get an NSArray with "items", (objectForKey:"items")

3: Inside that NSArray you have one object for each image object, which is an NSDictionary .

4: And finally, In each image object NSDictionary there is an url named "media" (objectForKey:"media"), which is your final URL to the image. Then you need to download the UIImage based on that URL

I don't code in Swift so I don't want to give you wrong code example, There are many threads how to get the URL or any value from JSON response.

Community
  • 1
  • 1
  • What part of the other thread do you mean specifically? How would you collect the URLs so that you could down load them. I was reading some of what you attached in the link, I don't understand the process the link was explaining. – Ingelbert Feb 14 '17 at 00:46
  • You should read what I wrote about the response. FIRST You get the `NSDictionary` JSON Respone. Inside the `NSDictionary` You get an `NSArray` of "items". Inside that `NSArray` you have one object for each image, which is an `NSDictionary` . And finally, In each image object `NSDictionary` there is a "url" `objectForKey` "media" , which is your final `URL` to the image. Then you need to download the `UIImage` based on that URL. –  Feb 14 '17 at 00:54
1

Try this code you will get your expected output

import UIKit

private let reuseIdentifier = "Cell"

class MCollectionViewController: UICollectionViewController {

    var arraImage: [String] = [String]()


    override func viewDidLoad() {
        super.viewDidLoad()

        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        self.collectionView!.backgroundColor = UIColor.whiteColor()
        RestAPIManager.sharedInstance.getServerData { (Json) -> Void in
            //print("Response = \(Json)")
            let array = Json["items"].arrayValue
            for item in array {
                print("\(item["media"]["m"])")
                self.arraImage.append(item["media"]["m"].stringValue)
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.collectionView!.reloadData()
                })
            }
        }
    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */

    // MARK: UICollectionViewDataSource

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }


    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of items
        return arraImage.count
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

        let padding =  10
        let collectionViewSize = collectionView.frame.size.width - CGFloat(padding)

        return CGSizeMake(collectionViewSize/2, collectionViewSize/2)

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

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CollectionViewCell

        if let url: NSURL = NSURL(string: arraImage[indexPath.row]) {
            cell.imageView.sd_setImageWithURL(url)
        }
        return cell
    }

    // MARK: UICollectionViewDelegate

    /*
    // Uncomment this method to specify if the specified item should be highlighted during tracking
    override func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    */

    /*
    // Uncomment this method to specify if the specified item should be selected
    override func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }
    */

    /*
    // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item
    override func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
        return false
    }

    override func collectionView(collectionView: UICollectionView, canPerformAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) -> Bool {
        return false
    }

    override func collectionView(collectionView: UICollectionView, performAction action: Selector, forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) {

    }
    */

}

I have also attached the link where you will find the project here

Anirudh R.Huilgol.
  • 839
  • 1
  • 15
  • 16