0
votes

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?

2

2 Answers

2
votes

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.

0
votes

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()


}