2016-06-01 2 views
1

저는 서버에서 도시 개체 목록을 가져 와서 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 
    } 
} 

답변

1

. ViewController가 ViewModel의 신호를 듣고 관찰하는 기능을 없애는 것으로 보입니다. 이전에도이 도우미 클래스를 사용하여 문제가 발생했습니다.

+0

내가 가정 한 부분적인 대답. 'TableViewBindingHelper' 클래스 내에서 문제를 일으키는 것을 정확하게 지적하는 것이 좋을 것입니다. –

관련 문제