How to parse JSON in a NSCollectionView in swift

I am grabbing data from a url which is a PHP script that is JSON encoding my data from a MySQL database. My data is coming into my app and I know how to parse it but I am unsure how to place my data inside of each item's textField.stringvalue in my Collection View. Most of the information I have found on this subject is all for iOS and I am making an app for OS X.


ViewController.swift


import Cocoa
class ViewController: NSViewController  {
    @IBOutlet weak var collectionView: NSCollectionView!

    var product: [Product]?

    let baseURL = "http:/

    override func viewDidLoad() {
        super.viewDidLoad()
     
        getJSON()
        self.collectionView.reloadData()
     
    }

    func getJSON(){
     
        let url = NSURL(string: baseURL)
        let request = NSURLRequest(url: url! as URL)
        let session = URLSession(configuration: URLSessionConfiguration.default)
        let task = session.dataTask(with: request as URLRequest) { (data,response,error) -> Void in
         
            if error == nil {
             
                let swiftyJSON = JSON(data:data!)
                print(swiftyJSON)
                let product = swiftyJSON[].arrayValue
           
                for name in product{
                 
                    let names = name["product_name"].stringValue
                   print(names)
                }
             
             
            } else{
                print("Error")
            }
        }
        task.resume()
    }

    override var representedObject: Any? {
        didSet {
        /
        }
    }
}
extension ViewController: NSCollectionViewDataSource{

    func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
     
        return (product?.count)!
     
    }

    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
     
     
     
        let item = collectionView.makeItem(withIdentifier: "ImageCollectionViewItem", for: indexPath)
     
        item.textField?.stringValue = "*****"
     
        return item
    }
}


Model.swift


import Foundation
class ProductCategory: NSObject {
   
    var name: String?
    var productss: [Product]?
    var type: String?
}
class Product: NSObject {
   
    var id: NSNumber?
    var product_name: String?
    var product_price: NSNumber?
    var product_description: String?
    var product_image: String?
    var product_download: String?
    var product_video: String?
    var product_featured: Int?
   
}

Replies

So far I have figured out how to assign an item to a property of my Product class:


    func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
       
       
       
        let item = collectionView.makeItem(withIdentifier: "ImageCollectionViewItem", for: indexPath)
       
        let productName = Product().product_name
       
        item.textField?.stringValue = productName!
       
        return item
    }



But I still cannot get anything to appear in my collectionView when I run my app. The window is blank. Any assistance would be greatly appreciated.

My data is coming into my app and I know how to parse it but I am unsure how to place my data inside of each item's textField.stringvalue in my Collection View.

You should rethink the layers within your app. In general I recommend a structure like this:

  • define a set of model objects that represent the data the user works with

  • give your view controller a reference to these model objects and use that to populate the view

  • have your networking code build these model objects from the data it gets off the network

This approach has a bunch of advantages:

  • Your view controller doesn’t do any networking; it is just responsible for displaying a set of model objects. This makes it smaller and much easier to test.

  • Your network code doesn’t have anything to do with view; it just updates the model based on the results from the network. This makes it smaller, and decouples it from your UI (for example, you could move that code to an iOS app and it wouldn’t need to change).

The main gotcha is that your view controller has to be responsive. That is, when the view controller starts up the model will be empty because nothing has been received from the network. The view controller has to show appropriate results in that case (a spinner, a Loading UI, or whatever).

The view controller also has to observe the model so that it can update its views when the model is populated with data from the network. You can do this using a variety of techniques (NSNotifications, KVO, delegates). The best technique really depends on your circumstances but I generally recommend that folks start out with NSNotifications.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you. I understand what you are saying about setting things up properly. The issue I have is that everyone has example for iOS and mobile but almost nothing for MAC OS X desktop apps. Unfortunately they are drastically different and I constantly run into issues.

The issue I have is that everyone has example for iOS and mobile but almost nothing for MAC OS X desktop apps. Unfortunately they are drastically different and I constantly run into issues.

The techniques referenced by my earlier post are the same on both platforms. In fact, they help with the cross-platform issues because they reduce the size of your view controller, and the view controller, with its associated views, is not cross platform. OTOH, your model code, and the networking code to populate that model, should be the same on any Apple platform.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"