1

So I'm fairly new to the concepts of Reactive Swift/Cocoa & MVVM. I'm wondering If I have the ViewModel initialized in the wrong place.

Model

struct userInfo {
let name: String
let birthday: Date

init(name: String, birthday: Date) {
    self.name = name
    self.birthday = birthday
   }
}

class User {
   let user = MutableProperty([userInfo]())
}

ViewModel

class UserViewModel {
    let user: MutableProperty<userInfo>

    init(_ user: userInfo) {
        self.user = MutableProperty(user)
    }

    var nameTextSignal: SignalProducer<String, NoError> {
        return user.producer.map { $0.name }
    }
}

UserSlide View with outlets

class UserSlide: UIView, UITextViewDelegate {

@IBOutlet weak var userName: UITextField!
@IBOutlet weak var dateField: UITextField!

let picker = UIDatePicker()

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    createDatePicker()

}

View Controller that references the ViewModel and binds it to a UILabel from UserSlide View

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var pageControl: UIPageControl!

var userviewmodel: UserViewModel!

var slides:[Any] = []

override func viewDidLoad() {
    super.viewDidLoad()
    slides = createSlides()
    setupSlideScrollView(slides: slides)

    pageControl.numberOfPages = slides.count
    pageControl.currentPage = 0
    view.bringSubviewToFront(pageControl)
}

func createSlides() -> [Any] {

    let slide1: UserSlide = Bundle.main.loadNibNamed("UserSlide", owner: self, options: nil)?.first as! UserSlide

    //**Error is thrown
    slide1.userName.reactive.text <~ userviewmodel.nameTextSignal
    slide1.userName.keyboardAppearance = .dark
    slide1.userName.delegate = self

    let slide2:ZodiacSlide = Bundle.main.loadNibNamed("ZodiacSlide", owner: self, options: nil)?.first as! ZodiacSlide    

The error I keep getting is "Unexpectedly found nil while implicitly unwrapping an Optional value" on the UserViewModel I reference in the ViewController in the createSlides() function.

I'm basically trying to create a PageController with two views and one of them has a UITextField that I need bound so that whenever the user changes the value and swipes to the second view, the data that is shown on the second view is up to date.

I've tried:

1) Setting the ViewModel to optional(?) but it, unfortunately, must be unwrapped.

2) Initializing the ViewModel in the UserSlide View instead of ViewController. ViewModel is still nil.

3) Initializing a UILabel in the ViewController and binding the ViewModel that way. The same result, ViewModel is nil.

Any Suggestions would be greatly appreciated! :)

AlrightyRob
  • 163
  • 13

1 Answers1

0

What your code is not showing is where you are setting userviewmodel of your ViewController

If you are injecting it from the outside, e.g. a parent or a presenting ViewController, you will have to make sure to set it before viewDidLoad since thats the place where you are accessing it.

Another approach would be to create the bindings in a separate method that is called when the viewModel is set.

Personally, I like ViewModelOwners as described here

MeXx
  • 3,357
  • 24
  • 39