我的模型是这样的;
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
}
时间戳视图模型
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")
}
}
}
}
}
网络服务
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视图控制器
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)
}
}
}
我将通过 jsondecode 收到的数据分配到区域数组中。我想在 tableviewcell 中使用 didSet{} 打印区域数组中的国家名称和时间戳,但我只能写入数组的第一个或最后一个元素。有机会逐格写下来吗?
问题出在您的 WebService 中。当您访问的 URL 仅返回单个对象时,您可以让它返回一个 TimeStamp 对象数组。您的单元格应每个显示一个区域对象。
我建议你完全摆脱WebService并只使用:
let timeStamp = 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([])
}