aşağıda, verdiğin örnek projede bulunan sunucu verisini nasıl kategorilere göre ayıracağına ilişkin bir düzenleme yaptım. Açıklamalar içinde.
 import UIKit
    typealias Urun = (urun: String, fiyat: String) // urunler için kullanacağımız tuple data tipini burada tanımlayalım
    typealias Kategori = (expanded: Bool, kategori: String, urunler:[Urun]) // kategoriler için kullanacağımız tuple data tipini burada tanımlayalım
    class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, ExpandableHeaderViewDelegate {
        @IBOutlet weak var tblView: UITableView!
        var kategoriler = [Kategori]()
        override func viewDidLoad() {
            super.viewDidLoad()
            parseData()
        }
        func parseData() {
            self.kategoriler.removeAll()
            var request = URLRequest(url: URL(string: "http://kozmogoni.com/public_html/deneme/deneme.php")!)
            request.httpMethod = "GET"
            let configuration = URLSessionConfiguration.default
            let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
            let task = session.dataTask(with: request) { (data, response, error) in
                if (error != nil) {
                    print("Error")
                }
                else {
                    do{
                        let fetchedData = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as! NSArray
                        fetchedData.forEach({ (rawData) in //döngümüz
                            if let castedData = rawData as? [String : Any] { //Ant data tipini String:Any array'ine cast edelim
                                if let receivedKategori = castedData["kategori"] as? String { // ilgili array içerisinde varsa 'kategori' key'inin değerini String data tipine cast edelim
                                    if let receivedUrun = castedData["urun"] as? String { // ilgili array içerisinde varsa 'urun' key'inin değerini String data tipine cast edelim
                                        if let receivedFiyat = castedData["fiyat"] as? String { // ilgili array içerisinde varsa 'fiyat' key'inin değerini String data tipine cast edelim
                                            let urun = Urun(urun: receivedUrun, fiyat: receivedFiyat) // alınan ürün ve fiyat bilgisiyle yeni bir 'Urun' tuple'ı oluşturalım
                                            if let index = self.kategoriler.index(where: { (kategori) -> Bool in // mevcut kategori tuple array'i içerisinde daha önce aynı kategoriden oluşturulmuş mu bir bakalım. varsa array index'ini alalım
                                                return kategori.kategori == receivedKategori // kategori tuple'i nin kategori değeri, alınan kategori adı ile aynıysa, kategoriler array'i içerisinde daha önceden bu kategori eklenmiş demektir.
                                            }) {
                                                var currentKategori = self.kategoriler[index] //alınan index'ile kategoriler array'i içerisinden ilgili kategori tuple'i ni bir değişkene alalım
                                                currentKategori.urunler.append(urun) // kategori tuple'i na ait değişkendeki 'urunler' array'ine yukarıda oluşturduğumumz yeni urun tipini ekliyoruz
                                                self.kategoriler[index] = currentKategori // kategori datasının son halini mevcut kategoriler array'inde yer alanan eski haliyle değiştiriyoruz.
                                            } else { // eğer kategoriler array'i içerisinde daha önce böyle bir kategori eklenmemişse index null geleceğinden aşağıda yeni bir kategori oluşturacağız
                                                let newKategori = Kategori(expanded: false, kategori: receivedKategori, urunler:[urun]) // yeni kategoriyi ilk ürünü ile birlikte oluşturuyoruz.
                                                self.kategoriler.append(newKategori) // yeni kategoriyi, kategoriler array'ine ekliyoruz.
                                            }
                                        }
                                    }
                                }
                            }
                        })
                        self.tblView.reloadData()
                    }
                    catch {
                        print("Error 2")
                    }
                }
            }
            task.resume()
        }
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
        func numberOfSections(in tableView: UITableView) -> Int {
            return kategoriler.count
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return kategoriler[section].urunler.count
        }
        func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 44
        }
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            if (kategoriler[indexPath.section].expanded) {
                return 44
            } else {
                return 0
            }
        }
        func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
            return 2
        }
        func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            let header = ExpandableHeaderView()
            header.customInit(title: kategoriler[section].kategori, section: section, delegate: self)
            return header
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "labelCell")!
            cell.textLabel?.text = kategoriler[indexPath.section].urunler[indexPath.row].urun
            cell.detailTextLabel?.text = kategoriler[indexPath.section].urunler[indexPath.row].fiyat
            return cell
        }
        func toggleSection(header: ExpandableHeaderView, section: Int) {
            kategoriler[section].expanded = !kategoriler[section].expanded
            tblView.beginUpdates()
            for i in 0 ..< kategoriler[section].urunler.count {
                tblView.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
            }
            tblView.endUpdates()
        }
    }