Skip to content

Commit

Permalink
viewModel updates observable added
Browse files Browse the repository at this point in the history
  • Loading branch information
sinarionn committed Mar 24, 2017
1 parent 71348d4 commit 9fe79d0
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Change Log

All notable changes to this project will be documented in this file.

## [1.1.0](https://github.com/sinarionn/ReusableView/releases/tag/1.1.0)

ViewModel updates observable added.
2 changes: 1 addition & 1 deletion ReusableView.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Pod::Spec.new do |s|
s.name = "ReusableView"
s.version = "1.0.1"
s.version = "1.1.0"
s.summary = "Reusable and NonReusable viewModel containers"

s.homepage = "https://github.com/sinarionn/ReusableView"
Expand Down
24 changes: 23 additions & 1 deletion Sources/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,34 @@ extension Reactive where Base: ReusableViewProtocol, Base: AnyObject {
get {
return base.reuseBag
}
set {
nonmutating set {
base.reuseBag = newValue
}
}
}

extension ViewModelHolderProtocol {
internal var _viewModelDidUpdate: PublishSubject<(ViewModelProtocol, DisposeBag)> {
get {
objc_sync_enter(self)
defer { objc_sync_exit(self) }
guard let existingObserver : PublishSubject<(ViewModelProtocol, DisposeBag)> = associated(with: self, by: &AssociatedKeys.viewModelUpdateObserver) else {
let newObserver = PublishSubject<(ViewModelProtocol, DisposeBag)>()
associate(self, withValue: newObserver, by: &AssociatedKeys.viewModelUpdateObserver)
return newObserver
}
return existingObserver
}
}
}

extension Reactive where Base: ViewModelHolderProtocol {
public var viewModelDidUpdate: Observable<(Base.ViewModelProtocol, DisposeBag)> {
return base._viewModelDidUpdate.asObservable()
}
}

fileprivate struct AssociatedKeys {
static var disposeBag = "viewModel dispose bag associated key"
static var viewModelUpdateObserver = "viewModel did update observer associated key"
}
1 change: 1 addition & 0 deletions Sources/NonReusableViewProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extension NonReusableViewProtocol where Self: AnyObject, Self.CompatibleType: An
objc_sync_exit(self)

onUpdate(with: newVM, disposeBag: rx.disposeBag)
_viewModelDidUpdate.onNext((newVM, rx.disposeBag))
}

get {
Expand Down
2 changes: 2 additions & 0 deletions Sources/ReusableViewProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extension ReusableViewProtocol {
guard let newVM = newValue else { return }
objc_sync_exit(self)
onUpdate(with: newVM, disposeBag: reuseBag)
_viewModelDidUpdate.onNext((newVM, reuseBag))
}

get {
Expand All @@ -80,6 +81,7 @@ extension ReusableViewProtocol where Self.ViewModelProtocol : Equatable {
guard let newVM = newValue else { return }
objc_sync_exit(self)
onUpdate(with: newVM, disposeBag: reuseBag)
_viewModelDidUpdate.onNext((newVM, reuseBag))
}

get {
Expand Down
11 changes: 11 additions & 0 deletions Tests/NonReusableViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ class NonReusableViewTests: XCTestCase {
XCTAssertTrue(object.errorReceivedViewModel == "321")
}

func testViewModelObserver() {
let object = TestNonReusable()
let expect = expectation(description: "")
_ = object.rx.viewModelDidUpdate.take(1).subscribe(onNext: {
XCTAssert($0.0 == object.receivedViewModel)
XCTAssert($0.0 == "a")
expect.fulfill()
})
object.viewModel = "a"
waitForExpectations(timeout: 1, handler: nil)
}
}

class TestNonReusable: NonReusableViewProtocol {
Expand Down
17 changes: 16 additions & 1 deletion Tests/ReusableViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import XCTest
import RxSwift
import RxCocoa

@testable import ReusableView

Expand Down Expand Up @@ -139,6 +138,22 @@ class ReusableViewTests: XCTestCase {
XCTAssertTrue(object.prepareForReuseCalled == 3)
}

func testViewModelObserver() {
let object : TestReusable = TestDistinctiveReusable()
let expect = expectation(description: "")
_ = object.rx.viewModelDidUpdate.take(1).subscribe(onNext: {
XCTAssert($0.0 == object.receivedViewModel)
XCTAssert($0.0 == "a")
_ = object.rx.viewModelDidUpdate.take(1).subscribe(onNext: {
XCTAssert($0.0 == object.receivedViewModel)
XCTAssert($0.0 == "b")
expect.fulfill()
})
object.viewModel = "b"
})
object.viewModel = "a"
waitForExpectations(timeout: 1, handler: nil)
}
}


Expand Down

0 comments on commit 9fe79d0

Please sign in to comment.