Not getting the Encapsulate Sheet Presentation

I’ve read the postings in this section for this Challenge and it doesn’t seem they follow what the book is asking for. I don’t know if what the book asks for can be done with the current Swift 4.1, but I’d like to try. For those that are following this site, but not reading the book, here is the Challenge:

“In Dice, add a method to ConfigurationWindowController:


The method’s parameter should be the window the configuration sheet should be displayed on, and the completion handler will be a closure of type (DieConfiguration?)->(Void). If the user clicks OK, the DieConfiguration will be passed to the completion handler; otherwise it will be nil to signal that nothing changed.

Here is how your method will look when it is called:
​ ​ ​ ​ ​ ​w​i​n​d​o​w​C​o​n​t​r​o​l​l​e​r​.​p​r​e​s​e​n​t​A​s​S​h​e​e​t​O​n​W​i​n​d​o​w​(​w​i​n​d​o​w​,​ ​c​o​m​p​l​e​t​i​o​n​H​a​n​d​l​e​r​:​ ​{​
​ ​ ​ ​ ​ ​ ​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​i​n​
​ ​ ​ ​ ​ ​ ​ ​ ​ ​i​f​ ​l​e​t​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​=​ ​c​o​n​f​i​g​u​r​a​t​i​o​n​ ​{​
​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​d​i​e​V​i​e​w​.​c​o​l​o​r​ ​=​ ​c​o​n​f​i​g​u​r​a​ton.color
dieView.numberOfTimesToRoll = configuration.rolls
}) ”

I can’t seem to get anything work for this.

Here is my code without these additions (since I couldn’t figure it out yet):

In ConfigurationWindowController.swift:

import Cocoa

struct DieConfiguration {
let color: NSColor
let rolls: Int

init(color: NSColor, rolls: Int) {
	self.color = color
	self.rolls = max(rolls, 1)

class ConfigurationWindowController: NSWindowController {

var configuration: DieConfiguration {
	set {
		color = newValue.color
		rolls = newValue.rolls
	get {
		return DieConfiguration(color: color, rolls: rolls)

@objc private dynamic var color: NSColor = NSColor.white
@objc private dynamic var rolls: Int = 10

override var windowNibName: NSNib.Name? {
	return NSNib.Name(rawValue: "ConfigurationWindowController")

@IBAction func okayButtonClicked(button: NSButton) {
	window?.endEditing(for: nil)
	dismissWithModalResponse(response: NSApplication.ModalResponse.OK)

@IBAction func cancelButtonClicked(button: NSButton) {
	dismissWithModalResponse(response: NSApplication.ModalResponse.cancel)

func dismissWithModalResponse(response: NSApplication.ModalResponse) {
	window!.sheetParent!.endSheet(window!, returnCode: response)

my current MainWindowController.swift:

import Cocoa

class MainWindowController: NSWindowController {

override var windowNibName: NSNib.Name? {
	return NSNib.Name(rawValue: "MainWindowController")

override func windowDidLoad() {

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.

// MARK: - Actions

var configurationWindowController: ConfigurationWindowController?

@IBAction func showDieConfiguration(sender: AnyObject?) {
	if let window = window, let dieView = window.firstResponder as? DieView {
		// Create and configure the window controller to present as a sheet:
		let windowController = ConfigurationWindowController()
		windowController.configuration = DieConfiguration(color: dieView.color,
													rolls: dieView.numberOfTimesToRoll)
						  completionHandler: { response in
							//The sheet has finished.  Did the user click 'OK'?
							if response == NSApplication.ModalResponse.OK {
								let configuration = self.configurationWindowController!.configuration
								dieView.color = configuration.color
								dieView.numberOfTimesToRoll = configuration.rolls
							// All done with the window controller
							self.configurationWindowController = nil
							// closing the color panel
							let sharedColorPanel: NSColorPanel = NSColorPanel.shared
		configurationWindowController = windowController

Apparently to encapsulate, I need to move the IBAction function showDieConfiguration: to ConfigurationWindowController.swift? Or at least the parts of it that create the sheet.

Any hints on how to get this done?


// Edit on 5/17/2018

I’ve been searching online for what felt like weeks to learn how to write the code for this challenge. I did find a page with a solution. I was hoping to find “how to do it” not how it was done, but you can’t unsee what you see. I won’t post the solution here (it took two web sites, one for the solution, and another search on how to get it to work in Swift 4.1). If anyone wants the web sites, or wants the solution just posted here, I can do that.