저는 서버에서 도시 개체 목록을 가져 와서 JSON으로 반환하는 RAC4로 앱을 개발하고 있습니다. 저는 각 도시와 그 적절한 속성을 City 객체로 저장하여 응답을 처리합니다. 그런 다음 각 City를 CityViewModel 유형으로 매핑하고 [CityViewModel] 유형의 배열을 MutableProperty로 저장합니다. 여기에서 각 도시는 tableViewCell에 저장되고 셀 안에 progressBar라는 이름으로 표시됩니다. 탭을 누르면 셀에서 city nid (city ID)를 매개 변수로 사용하여 이미지가 포함 된 큰 .zip 파일을 다운로드하는 또 다른 서버 요청이 트리거됩니다.RAC MutableProperty 제작자가 이벤트를 구독자에게 보내지 않습니다.
진행 목표는 진행 상황에 실시간 업데이트로 애니메이션을 적용하는 것입니다. 탭에서 셀은 downloadCityData(nid: Int)
함수를 호출하여 모든 것을 시작합니다.
도시의 속성이 업데이트되는 동안 도시 MutableProperty<[CityViewModel]>
은 DataViewModel
개체 외부의 변경 내용을 수신 대기하지 않는다는 문제가 있습니다.
class DetailViewController: UIViewController {
@IBOutlet weak var cityTableView: UITableView!
private var bindingHelper: TableViewBindingHelper<CityViewModel>!
var viewModel: DetailViewModel?
override func viewDidLoad() {
super.viewDidLoad()
self.viewModel = DetailViewModel()
self.viewModel!.cities.producer
.startOn(UIScheduler())
.startWithNext{ x in
/// this doesn't hear any changes as progress updates
}
bindingHelper = TableViewBindingHelper(tableView: cityTableView, sourceSignal: self.viewModel!.cities.producer, nibName: "CityCell")
}
}
뷰 모델 :
의 ViewController (이 경우는 어느 DetailViewController
이다)
class DetailViewModel: NSObject {
var dataManager: DataManager
let cities = MutableProperty<[CityViewModel]>([CityViewModel]())
override init() {
self.dataManager = DataManager()
super.init()
self.dataManager.progressMarker.producer
.observeOn(UIScheduler())
.startWithNext{ [weak self] (nid, progress) in
self!.cities.value = (self!.cities.value.map{ city in
if city.nid.value == nid {
print(nid, progress)
city.downloading.value = true
city.progress.value = progress
}
return city
})
}
}
func downloadCityData(nid: Int) -> SignalProducer<(JSON?, Float), NSError> {
return dataManager.getCityData(nid)
.on(next: { (json, progress) in
/// download complete
print("download complete")
self.cities.value = (self.cities.value.map{ city in
if city.nid.value == nid {
city.downloading.value = false
city.downloadedBool.value = true
city.upToDate.value = true
}
return city
})
})
}
}
DataManager는 :
class DataManager: NSObject {
private let restClient = RestClient()
let progressMarker = MutableProperty<(Int, Float)>(0, 0)
override init() {
super.init()
}
func getCityData(nid: Int) -> SignalProducer<(JSON?, Float), NSError> {
return restClient.fetchCityData(nid)
.filter{ (fileName, progress) in
self.progressMarker.value = (nid, progress)
return fileName.characters.count > 0
}
.flatMap(FlattenStrategy.Latest, transform: unzipCityData)
.flatMap(FlattenStrategy.Latest, transform: unpackCityData)
}
}
CityViewModel :
도시 : 난 당신이 Colin Eberhardt's TableViewBindingHelper을 사용하고 참조
struct City {
var name: String
var nid: Int
var timestamp: Int
var progress: Float
var downloading: Bool
var downloaded: Bool
var upToDate: Bool
init() {
name = ""
nid = 0
timestamp = 0
progress = 0
downloading = false
downloaded = false
upToDate = false
}
}
내가 가정 한 부분적인 대답. 'TableViewBindingHelper' 클래스 내에서 문제를 일으키는 것을 정확하게 지적하는 것이 좋을 것입니다. –