My model is like this;
import Foundation
struct TimeStamp: Decodable
{
let status : String
let message: String
let zones: [Zone]
}
struct Zone: Decodable
{
let countryCode : String
let countryName : String
let zoneName: String
let gmtOffset : Int
let timestamp : Int
}
TimeStampViewModel
import Foundation
import RxSwift
import RxCocoa
class TimeStampViewModel
{
let timeStamps : PublishSubject<[TimeStamp]> = PublishSubject()
let error : PublishSubject<String> = PublishSubject()
let loading : PublishSubject<Bool> = PublishSubject()
func requestData()
{
self.loading.onNext(true)
let url = URL(string: "http://api.timezonedb.com/v2.1/list-time-zone?key=QQFJMAE732I4&format=json")!
WebService().downloadTimeStamp(url: url)
{
result in
self.loading.onNext(false)
switch result
{
case.success(let timeStamps):
self.timeStamps.onNext(timeStamps)
case.failure(let error):
switch error
{
case.parsingError:
self.error.onNext("Parsing Error")
case.serverError:
self.error.onNext("Server Error")
}
}
}
}
}
WebService
import Foundation
enum TimeStampError : Error
{
case serverError
case parsingError
}
class WebService
{
func downloadTimeStamp(url: URL, completion: @escaping (Result<[TimeStamp], TimeStampError>) -> ())
{
URLSession.shared.dataTask(with: url)
{
data, response, error in
if let _ = error
{
completion(.failure(TimeStampError.serverError))
}
else if let data = data
{
let timeStampList = try? JSONDecoder().decode(TimeStamp.self, from: data)
if let timeStampList = timeStampList
{
completion(.success([timeStampList]))
}
else
{
completion(.failure(.parsingError))
}
}
}.resume()
}
}
CountryHoursVC ViewController
import UIKit
import RxSwift
import RxCocoa
class CountryHoursVC: UIViewController, UITableViewDelegate
{
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var indicatorView: UIActivityIndicatorView!
let timeStampVM = TimeStampViewModel()
let disposeBag = DisposeBag()
var timeStampList = [TimeStamp]()
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .black
tableView.rx.setDelegate(self).disposed(by: disposeBag)
setupBindings()
timeStampVM.requestData()
}
private func setupBindings()
{
timeStampVM.loading.bind(to: self.indicatorView.rx.isAnimating).disposed(by: disposeBag)
timeStampVM.error.observe(on: MainScheduler.asyncInstance).subscribe
{
errorString in
print(errorString)
}.disposed(by: disposeBag)
timeStampVM.timeStamps.observe(on: MainScheduler.asyncInstance).bind(to: tableView.rx.items(cellIdentifier: "CountryHourCell", cellType: CountryHourTableViewCell.self))
{
row, item, cell in
cell.item = item
}.disposed(by: disposeBag)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 70
}
}
CountryHourTableViewCell
import UIKit
var countryList = [String]()
class CountryHourTableViewCell: UITableViewCell
{
@IBOutlet weak var countryNameLabel: UILabel!
@IBOutlet weak var hourLabel: UILabel!
override func awakeFromNib()
{
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
public var item : TimeStamp!
{
didSet
{
countryNameLabel.text = item.zones.first?.countryName
let date = Date(timeIntervalSince1970: TimeInterval(item.zones.first?.timestamp ?? 0))
// Saat dilimini HH:mm formatında ayarla
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm"
hourLabel.text = formatter.string(from: date)
}
}
}
I assigned the data I received with jsondecode into the zones array. I want to print the countryNames and timestamps in the zones array with didSet{} in the tableviewcell, but I can only write the first or last element of the array. Is there a chance to write them all down cell by cell?
The problem is in your WebService. You have it returning an array of TimeStamp objects when the URL you are hitting only returns a single object. Your cells should each display a single Zone object.
I suggest you get rid of the WebService completely and just use:
timeStamps = URLSession.shared.rx.data(request: URLRequest(url: url))
.decode(type: TimeStamp.self, decoder: JSONDecoder())
.map { $0.zones }
.catch { [error] in
error.onNext($0.localizedDescription)
return Observable.just([])
}