0

So I currently have the following code that works

  func createArray() -> [News] {

           return [News(title: "Hello") , News(title: "how") , News(title: "You")]

    }

However what I want is to replace that with remote JSON data, So far I got it working to the point of no errors.

However it seems that the tableViewCell does not want to work - I believe it something to do with the append function.

tempNews.append(News(title: $0.title))

Now I have check to see if $0.title prints out the title and it does So the issue has to be something other than that.

newsdata.news.forEach(){
                                print($0.title)

                               // tempNews.append(News(title: $0.title))
                             tempNews.append(News(title: "1123"))

                            }

returns

Please stay safe on the roads.
Lost Beliefs
Dami Im - Crying Underwater
Dear Extinction Rebellion Protesters
Billie Eilish All Good Girls Go To Hell (Music Video Review)
Inferno Engulfs Conception
Council Kills Australian Icon
Third Time Lucky - pilot lands
Anchors Away For Ross Lyon
Sydney Under Attack
With Friends Like This...
Papa You Did Wrong
6Year Old French Tourist Injured
Bendigo Woman First Victorian to use new Assisted Dying Act
America Shocked By Back To Back Shootings
Channel Ten’s The Project Infighting Backstage.

but when I try tempNews.append(News(title: "1123"))

it does not append it to tempNews So I now know that the appending is not working.

the following does append

 func createArray() -> [News] {
        //var tempNews = [News] = []
        var tempNews : [News] = []


        let news1 = News(title: "Hello")
        let news2 = News(title: "how")
        let news3 = News(title: "You")

        tempNews.append(news1)
        tempNews.append(news2)
        tempNews.append(news3)

        return tempNews
    }

code

 func newsfetch() -> [News]{
        var artical = Array<Any>()
        var tempNews: [News] = []
                    let jsonURLString = "https://api.drn1.com.au/api-access/news"
                    guard let feedurl = URL(string: jsonURLString) else {  return tempNews }

                      URLSession.shared.dataTask(with: feedurl) { (data,response,err)
                          in

                          guard let news = data else { return }

                          do{
                            let newsdata = try JSONDecoder().decode(NewsData.self, from: news)

                            newsdata.news.forEach(){
                                print($0.title)

                               // tempNews.append(News(title: $0.title))
                                artical = News(title: "1123")

                            }


                            }catch let jsonErr{

                                print("error json ", jsonErr)
                            }


                      }.resume()


        return tempNews(artical)


          }

Full code with Kamran code

//
//  NewsViewController.swift
//  DRN1
//
//  Created by Russell Harrower on 26/11/19.
//  Copyright © 2019 Russell Harrower. All rights reserved.
//

import UIKit


struct NewsData: Decodable{
    let news: [articalData]
}

struct articalData: Decodable{
    let title: String
}

class NewsViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    var news: [News] = []

    override func viewDidLoad() {
      super.viewDidLoad()
        self.newsfetch { news in
            guard let news = news else { return }
        }

        //news = createArray()
      // Do any additional setup after loading the view.
        tableView.delegate = self
        tableView.dataSource = self
    }

    func createArray() -> [News] {

           return [News(title: "Hello") , News(title: "how") , News(title: "You")]

    }

    func newsfetch(_ completionHandler:  @escaping ([News]?)->Void){
        let jsonURLString = "https://api.drn1.com.au/api-access/news"
        guard let feedurl = URL(string: jsonURLString) else {  return }

        URLSession.shared.dataTask(with: feedurl){ (data,response,err)
            in
            guard let news = data else { return }
            do {
                let newsdata = try JSONDecoder().decode(NewsData.self, from: news)
                var tempNews: [News] = []
                newsdata.news.forEach(){
                    tempNews.append(News(title: $0.title))
                }
                completionHandler(tempNews)
            } catch let jsonErr {
                print("error json ", jsonErr)
                completionHandler(nil)
            }
        }.resume()

    }


    /*func newsfetch() -> [News]{

        var tempNews: [News] = []
                    let jsonURLString = "https://api.drn1.com.au/api-access/news"
                    guard let feedurl = URL(string: jsonURLString) else {  return tempNews }

                      URLSession.shared.dataTask(with: feedurl) { (data,response,err)
                          in

                          guard let news = data else { return }

                          do{
                            let newsdata = try JSONDecoder().decode(NewsData.self, from: news)

                            newsdata.news.forEach(){

                                DispatchQueue.main.async {
                                    print($0.title)

                                    tempNews.append(News(title: $0.title))
                                    print(tempNews.count)
                                }
                            }
                            }catch let jsonErr{

                                print("error json ", jsonErr)
                            }


                      }.resume()



        return tempNews

        }*/


  override func viewDidAppear(_ animated: Bool) {
    self.tabBarController?.navigationItem.title = "News"

          //     let controller = AVPlayerViewController()
            //    controller.player = player

                // Modally present the player and call the player's play() method when complete.
          //      present(controller, animated: false) {
           //       player.play()
           //     }


  }

}


extension NewsViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return news.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let newsa = news[indexPath.row]

        let cell = tableView.dequeueReusableCell(withIdentifier: "NewsCell") as! NewsCell
        cell.setNews(news: newsa)
        return cell
    }
}

Issue is on screen the table is still blank.

RussellHarrower
  • 6,470
  • 21
  • 102
  • 204
  • How can you sure `tempNews.append(News(title: "1123"))` is not working? what is `newsdata` ? – Faysal Ahmed Nov 28 '19 at 05:03
  • @FaysalAhmed the above are all the titles it should show – RussellHarrower Nov 28 '19 at 05:04
  • what is `newsdata`? – Faysal Ahmed Nov 28 '19 at 05:04
  • To confirm you can print the `tempNews` array count before and after the `foreach` loop. If the count print different number then the append is working well. Please try this. – Faysal Ahmed Nov 28 '19 at 05:07
  • @FaysalAhmed I did and the result was 0 – RussellHarrower Nov 28 '19 at 05:08
  • How you initialize the `tempNews` variable? – Faysal Ahmed Nov 28 '19 at 05:10
  • @FaysalAhmed the following works func createArray() -> [News] { //var tempNews = [News] = [] var tempNews = [News] = [] let news1 = News(title: "Hello") let news2 = News(title: "how") let news3 = News(title: "You") tempNews.append(news1) tempNews.append(news2) tempNews.append(news3) return tempNews } – RussellHarrower Nov 28 '19 at 05:11
  • Please try this `var tempNews:[News] = []` instead of `var tempNews = [News] = []` – Faysal Ahmed Nov 28 '19 at 05:13
  • @FaysalAhmed that was a typo but not the issue see original code – RussellHarrower Nov 28 '19 at 05:14
  • 1
    @RussellHarrower Read about closure in swift. The task you're performing is an asynchronous task and will give you the data later not immediately. So you're returning the `tempNews` before the data get appended to it. You need a completion block instead. – TheTiger Nov 28 '19 at 05:19
  • @TheTiger sorry but I don't understand why that matters, as it still printing the data? So my question how... as I really don't get how your comment helps – RussellHarrower Nov 28 '19 at 05:26
  • @RussellHarrower It prints the data inside callback. Just print the date in `do` block and just before the `return` line and you will see the time difference. The date of `do` block will be greater. – TheTiger Nov 28 '19 at 05:31
  • Does this answer your question? [Returning data from async call in Swift function](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function) – TheTiger Nov 28 '19 at 06:48

0 Answers0