0

I have an app, that shows current weather. Data is downloaded via Alamofire from forecast.io. Result forms a table with forecast. I used simple tableviewdelegate and tableviewDatasource, everything works. But now I wanted to learn some reactive, using rxswift and rxcocoa. After some googling, and tutorial from raywanderlich: I changed my code to:

var week = Variable<[DailyWeather]>([])

override func viewDidLoad() {
    super.viewDidLoad()

    week.asObservable().subscribe { (e) in
        self.generateTable()
    }.addDisposableTo(disposeBag)

//        tableView.delegate = self
//        tableView.dataSource = self
        tableView.backgroundColor = UIColor(red:0.81, green:0.81, blue:0.81, alpha:1)
        refreshControl.tintColor = UIColor(red:1, green:1, blue:1, alpha:1)
        self.tableView.addSubview(self.refreshControl)
        manager.delegate = self
        manager.requestWhenInUseAuthorization()
        updateLocation()


}

func downloadData(_ completion: @escaping DownloadComplete) {

    var weatherURL: String {
        if pre == "ru" {
            return("\(BASE_URL)\(API_KEY)/\(latitudeNew),\(longitudeNew)?units=si&lang=ru")
        } else {
            return("\(BASE_URL)\(API_KEY)/\(latitudeNew),\(longitudeNew)?units=si")
        }
    }

    print(weatherURL)

    if let url = URL(string: weatherURL) {
        let request = Alamofire.request(url)

        request.validate().responseJSON { response in
            switch response.result {
            case .success:

                self.week.value = []

                self.weekly = []
                if let data = response.result.value as! [String: AnyObject]! {

                    self.weatherDict = data["currently"] as! [String: AnyObject]!
                    self.currentDict = CurrentWeather(weatherDictionary: self.weatherDict)

                    self.dailyArray = data["daily"]?["data"] as! [[String: AnyObject]]!
                    for dailyWeather in self.dailyArray {
                        let daily = DailyWeather(dailyWeatherDict: dailyWeather)
                        self.weekly.append(daily)
                    }
                    for x in 0...7 {
                        if x == 0 {
                        } else {

                            self.week.value.append(self.weekly[x])

                        }
                    }
                    completion()
                }

            case .failure(let error):
                self.showAlert("You are offline", message: "Enable network connection and try again")
                print("Alamofire error: \(error)")
            }

        }

    }
}


func generateTable() {

    week.asObservable().bindTo(tableView.rx.items(cellIdentifier: "WeatherViewCell", cellType: WeatherViewCell.self)) { (index, weather, cell) in
        cell.configureCell(daily: weather, index: index)
        }.addDisposableTo(disposeBag)

}

But I receive this fatal error:

fatal error: Failure converting from Optional(<UIView: 0x7facad60f620; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x60800002e520>>) to UITableViewDataSource: file /Users/ruslansabirov/Desktop/swift/Havo4/Pods/RxCocoa/RxCocoa/RxCocoa.swift, line 146
(lldb) 

Pls, help, what I'm doing wrong?

Ruslan Sabirov
  • 440
  • 1
  • 4
  • 19

2 Answers2

2

Check table view delegate and datasource methods. if tableview delegate is set in your code then you must implement the delegate method of tableview while using RXSwift otherwise application got crash.

Deepak Saki
  • 945
  • 1
  • 8
  • 16
0

you only need to call func generateTable() once. The tableview will update automatically. As it is a data bindingoverride

 func viewDidLoad() {
    super.viewDidLoad()

        self.generateTable()

        tableView.backgroundColor = UIColor(red:0.81, green:0.81, blue:0.81, alpha:1)
        refreshControl.tintColor = UIColor(red:1, green:1, blue:1, alpha:1)
        self.tableView.addSubview(self.refreshControl)
        manager.delegate = self
        manager.requestWhenInUseAuthorization()
        updateLocation()


}
Daniel Poulsen
  • 1,446
  • 13
  • 21
  • No, I want table to update everytime when location is changed. I found the error, somehow delegate was already defined in storyboard (my first old project) and i set delegate to nil in generate table function: func generateTable() { tableView.dataSource = nil week.asObservable().bindTo(tableView.rx.items(cellIdentifier: "WeatherViewCell", cellType: WeatherViewCell.self)) { (index, weather, cell) in cell.configureCell(daily: weather, index: index) }.addDisposableTo(disposeBag) } – Ruslan Sabirov Feb 13 '17 at 12:25
  • You still dont need to need to bind the week to the tableview again and again. it will still update – Daniel Poulsen Feb 13 '17 at 12:27