-1

I am trying to convert JSON data into Swift 3.0 format, but I am getting an error.

Here is my JSON data:

"items": [
  {
   "kind": "youtube#searchResult",
   "etag": "\"m2yskBQFythfE4irbTIeOgYYfBU/fJgYDRLJbQIA4cQD71Hu-VtHYuM\"",
   "id": {
    "kind": "youtube#video",
    "videoId": "diVd_vpuons"
   },
   "snippet": {
    "publishedAt": "2015-07-16T13:47:55.000Z",
    "channelId": "UC1iwdTRSV1Z2DMopttg8ocA",
    "title": "Bengali Pala Kirtan | New Bhajan Kirtan | 2015 |  Sabitri Satyaban | Shanta Das | Gold Disc",
    "description": "Watch The New Bengali Pala Kirtan By Shanta Das \"Sabitri Satyaban \". Song : Sabitri Satyaban Album : Sabitri Satyaban Singer : Shanta Das Music By ...",
    "thumbnails": {
     "default": {
      "url": "",
      "width": 120,
      "height": 90
     },
     "medium": {
      "url": "",
      "width": 320,
      "height": 180
     },
     "high": {
      "url": "",
      "width": 480,
      "height": 360
     }
    },
    "channelTitle": "RDC Banglar Geeti",
    "liveBroadcastContent": "none"
   }
},

And this is my Swift code:

func getChannelDetails(_ useChannelIDParam: Bool) {
    var urlString: String!
    if !useChannelIDParam {
        urlString = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PLbhFoUkf_GY6us_3RYg7U_NeNbqlc2AXY&key=AIzaSyAop5T2uSqj4Mw9nAE740za7mAHHiRwO2M"
    }

    let targetURL = URL(string: urlString)

    performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) -> Void in
        if HTTPStatusCode == 200 && error == nil {

            do {
                // Convert the JSON data to a dictionary.
                let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as! Dictionary<String, Any>

                // Get all playlist items ("items" array).
                let items: Array<Dictionary<String, Any>> = resultsDict["items"] as! Array<Dictionary<String, Any>>

                // Use a loop to go through all video items.
                for i in 0 ..< items.count {

                    var desiredValuesDict: Dictionary<String, Any> = Dictionary<String, Any>()

                    let objDicit = (items[i] as Dictionary<String, Any>)["id"] as! Dictionary<String, Any>

                    desiredValuesDict["videoID"] =  (objDicit["videoID"] as! Dictionary<String, Any>) ["videoId"]


                    let snippetDict = (items[i] as Dictionary<String, Any>)["snippet"] as! Dictionary<String, Any>

                    // Get the snippet dictionary that contains the desired data.

                    // Create a new dictionary to store only the values we care about.

                    desiredValuesDict["title"] = snippetDict["title"]

                    desiredValuesDict["thumbnail"] = ((snippetDict["thumbnails"] as! Dictionary<String, Any>)["high"] as! Dictionary<String, Any>)["url"]


                    //desiredValuesDict["videoID"] =  (snippetDict["resourceId"] as! Dictionary<String, Any>) ["videoId"]


                    // Save the channel's uploaded videos playlist ID.

                    // Append the desiredValuesDict dictionary to the following array.
                    self.channelsDataArray.append(desiredValuesDict)

                    // Reload the tableview.
                    self.tblVideos.reloadData()

                    // Load the next channel data (if exist).
                }
            } catch {
                print(error)
            }

        } else {
            print("HTTP Status Code = \(HTTPStatusCode)")
            print("Error while loading channel details: \(String(describing: error))")
        }
        self.viewWait.isHidden = true
    })
}

The title and image are shown, but I am getting the following error:

thread signal sigabrt xcode

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • i would recommend you to use third party Parser Or using `if let` syntax to deep dive, the first one is very nice and makes life and code easy https://stackoverflow.com/a/41037513/3535583 – Mukesh Aug 08 '17 at 07:35

1 Answers1

0

This will help clear the source code

let urlString = "The URL"
    let targetURL = URL(string: urlString)
    performGetRequest(targetURL, completion: { (data, HTTPStatusCode, error) ->  in
        if let error = error {
            //do something with the error
        }
        else {
            do {
                if let resultsDict = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:Any] {
                    if let items = resultDict["items"] as? [[String:Any]] {

                        //var parsedItems = [[String:Any]]()

                        for item in items {

                            var desiredValues = [String:Any]()

                            //get the videoId
                            if let id = item["id"] as? [String:Any], let videoId = id["videoId"] as? String {
                                desiredValues["videoId"] = videoId
                            }

                            //get title and thumbnail from snippet
                            if let snippet = item["snippet"] as? [String:Any] {
                                if let title = snippet["title"] {
                                    desiredValues["title"] = title
                                }

                                if let thumbanail = snippet["thumbnails"] as? [String:Any], let highValues = thumbanail["high"] as? [String:Any], let url = highValues["url"] as? String {
                                    desiredValues["url"] = url
                                }
                            }

                            self.channelsDataArray.append(desiredValues)

                        }

                        DispatchQueue.main.async {
                            self.tblVideos.reloadData()
                        }
                    }
                }
            }
            catch (let error){
                print("Error while parsing data: \(error.localizedDescription)")
            }
        }
    }

And if you are putting all the values in channelsDataArray then access it like

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let playerViewController = segue.destination as? PlayerViewController {
        playerViewController.videoID = channelsDataArray[selectedVideoIndex]["videoID"] as! String
    }
}

try downloading image in different function like below

func getImage(from urlString:String) -> UIImage? {
    if let url = URL(string: urlString) {
        do {
             let imageContent = try Data(contentsOf: url)

            //we have image dat
            let image = UIImage(data: imageContent)

            return image
        }
        catch {
            print("Unable to get image data")
        }
    }
    return nil
}

you may want to try using SDWebImage or other image library to make smooth scrolling possible on tableView. Or do something like below

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    var cell = tableView.dequeueReusableCell(withIdentifier: "idCellChannel", for: indexPath)

    let channelTitleLabel = cell.viewWithTag(10) as! UILabel
    let thumbnailImageView = cell.viewWithTag(12) as! UIImageView
    let channelDetails = channelsDataArray[indexPath.row]

    channelTitleLabel.text = channelDetails["title"] as? String

    DispatchQueue.global(qos: .background).async {
        if let imageURL = channelDetails["url"] as? String {
            if let image = getImage(from: imageURL) {
                thumbnailImageView.image = image
            }
        }
    }
    return cell
}
kathayatnk
  • 975
  • 1
  • 7
  • 9