Reputation: 13
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?
What I expect to happen is in this style of implementation
Upvotes: 1
Views: 42
Reputation: 33979
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([])
}
Upvotes: 0