1

I am currently creating my first Swift / Mac application and I have the problem of sharing a model (in the MVC sense) between several controllers.

In C# for example one would first create a model, then a number of view models, and then plug that model into them like this:

var gameEngine = new MyGameEngine()
var vm1 = new ViewModelCockpit(gameEngine);
var vm2 = new ViewModelOptionsDialog(gameEngine);

However, in XCode it seems that my controllers I am supposed to place into the .xib, which are, in turn, automatically instantiated.

What is given Swift's language features and XCode / Objective-C existing standards the best and most professional way have a number of heavyweight models that can be shared and accessed from several controllers? (Heavyweight in the sense that they take some time, memory or complex logic / dependencies) to load and might not easily be put into the .xib themselves.

Potential answers could be: global variables, some magic / static properties, ... Ideally the solution should feel solid in a software engineering sense and take Swift's language features into account.

left4bread
  • 1,514
  • 2
  • 15
  • 25
  • 3
    Where did you get "new" from? Also, download the WWDC app and take look at the videos. This is how we are all learning at the moment. – Fogmeister Jun 05 '14 at 08:07
  • The new X() above is how you would do it in C#. I am looking for an equivalent solution to the general problem in XCode / IB / Swift. – left4bread Jun 05 '14 at 08:10

2 Answers2

0

Depending on how complex your data model is, here are some things to consider:

  1. For complex data models, consider using Core Data
  2. Create a singleton DataController class that gives you access to your models from any controller in your app. In Swift it could be done like this: Using a dispatch_once singleton model in Swift

You only use XIBs/Storyboards for the UI, never for your models.

Community
  • 1
  • 1
Johannes Fahrenkrug
  • 42,912
  • 19
  • 126
  • 165
-1

I like to create the model(s) first, then pass them into each view's initialiser code, very similar to what you describe in C#. It's also similar to how you would do this in JavaScript (for example, in Backbone JS).

let gameEngine = MyGameEngine()


let vm1 = ViewModelCockpit(nibName: "ViewModelCockpit", bundle: NSBundle.mainBundle(), gameEngine: gameEngine)
let vm2 = ViewModelOptionsDialog(nibName: "ViewModelOptionsDialog", bundle: NSBundle.mainBundle(), gameEngine: gameEngine)

class ViewModelCockpit: NSViewController {
  var myGameEngineModel: GameEngineModel

  init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!, myGameEngineModel: GameEngineModel) {
    self.myGameEngineModel = myGameEngineModel

    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  }
}

Note — you have to call the super.init() of the parent class, and if you forget, Xcode very nicely reminds you! I use Xcode's autocompletion to provide me with the usual init function and its exact args.

jeff-h
  • 2,184
  • 1
  • 22
  • 33