简体   繁体   中英

Parsing JSON and extracting URLS for images

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
    }

}

Your JSON response is not an image.

cell.imageView.image = media[indexPath.item]as? UIImage 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM