How to access OSX NSApplication from StoryBoard created default ViewController? - macos

I’ve used Xcode 6.3 to create a very simple Swift Mac application. It is not a document-based app. My app has one NSViewController, and it loads, opens and runs as expected. However, now I need to use the Application menu, and I don’t see the proper way for my NSViewController to communicate with the NSApplicationDelegate or the NSApplication itself.
I am looking for some chain of properties or methods I can call from my NSViewController, after it has loaded, but before it is displayed.

Try
override func viewDidLoad() {
super.viewDidLoad()
let myApplication = NSApp as! NSApplication
let myAppDelegate = myApplication.delegate as! AppDelegate
}
Works as expected within NSViewController instance.

Related

WKWebView in iOS and Mac OS Problems Not working in Mac OS; Why?

I open a default cocoa app; one for Mac OS and one for iOS using Storyboards. I drag a Web View (WKWebView) into the default view supplied by Storyboard. I modify the default ViewController.swift file so that for ios it reads
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
let url=URL(string: "https://www.example.com")
webView.load(URLRequest(url: url!))
// Do any additional setup after loading the view.
}
}
And for Mac OS it reads as follows
import Cocoa
import WebKit
class ViewController: NSViewController, WKNavigationDelegate {
#IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
let url=URL(string: "https://www.example.com")
webView.load(URLRequest(url: url!))
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
I connect the webView variable to the Web View object the same in both projects. The iOS project does what I expect. The Mac OS project fails to display the example page although it appears to run; I just have a blank window. The question is
What am I doing wrong in Mac OS?
Also in Mac OS I get a message
"Unable to load Info.plist exceptions (eGPUOverrides)".
I get that message for all my projects in the newer Xcode and have been unable to find any clues as to what it means. Just downloaded an updated Xcode today but I still get that message and still have this problem. Not sure if that relates or not to my question.
Try enable App Sandbox in Capabilities settings. (I use Xcode 11.2, Swift 5 and it works fine)

storyboard viewcontroller to coded viewcontroller

Is it possible to connect Storyboard ViewControllers with manual code-written ViewControllers? What I'm trying to do is make an app that, when internet connection is established, I see the viewcontroller made in the storyboard with tools given in the xcode (like the stepper, progress view, and etc) and when there's no internet connection, I want to access my coded viewcontroller that doesn't use the provided storyboard. How do I make the transition from the viewcontroller in the storyboard to the one not in the storyboard? Thanks!
UPDATE:Image depiction of what I seek to find:
depiction
I believe what you wanna do is show a storyboard programmatically?
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewController")
window?.rootViewController = vc
Don't forget to add the "ViewController" identifier to the ViewController in your Interface builder.

Why is applicationDidFinishLaunching NOT being called in my macOS document based app with a storyboard?

I'm working on a Swift document based app for macOS and I discovered that the appDelegate method applicationDidFinishLaunching is never called. The app delegate is being set correctly and I can see in the debugger that the NSApplication object has the delegate set. Why isn't this method being called when the application launches?
Note: my storyboard has an entry point set to a 'welcome window' controller (in case that has anything to do with this problem).
Resolved: my method signature was wrong. It was:
applicationDidFinishLaunching(aNotification: NSNotification)
When it should have been:
applicationDidFinishLaunching(_ aNotification: Notification)
This probably happened wile converting to the current Swift syntax.

Reference main NSWindow in AppDelegate using Storyboard?

I am attempting to set an outlet for the main window of my app in my App Delegate, then connect it within Interface Builder. I create the outlet within my App Delegate easily:
#IBOutlet weak var mainWindow: NSWindow!
However there's no way, within interface builder, for me to connect a referencing outlet to the App Delegate. Instead, I can only connect it to the Window Controller, which I hope this picture shows:
The first object is the Window Controller and the second object is the First Responder, however the App Delegate object is missing. The menubar has the App Delegate object:
And I can connect anything from the menubar to any outlets in the App Delegate.
I figure I can access the window object by using:
NSApp.windows[0]
But that seems prone to error, especially if I have more than one window.
I dont know if this is correct way of doing, but this will solve your problem.
Decalre a NSWindow property in AppDelegate
weak var window: NSWindow!
and set the property in something like windowWillLoad of the NSWindowController
(NSApplication.sharedApplication().delegate as! AppDelegate).window = self.window
You will have to subclass NSWindowController to define windowWillLoad

How does window management work in Mac development for MenuBar apps?

I'll preface this by saying this is my first Mac application, though I've been building iOs apps for some time.
I've got a menu bar app (system tray app) by which I mean I've got this.
I now want to show an NSWindow I've created in Interface Builder so I've created a class that's derived from NSWindow. Made my class the Window's delegate and from the App Delegate I do this:
MyClass *myClass = [[MyClass alloc] init];
[myClass display];
[myClass center];
[NSApp activateIgnoringOtherApps:YES];
[viewer makeKeyAndOrderFront:nil];
This seems to show a window without the standard window buttons (minimise, maximise, close) rather than the window I've defined.
Is this the right way to be showing windows? and how should the Window be defined so it shows my designed interface?
In Windows Forms programming this would be:
Form myForm = new Form();
myForm.Show();
You rarely need to subclass NSWindow unless you want to override a window's behavior. A more typical usage scenario would be to use an instance of NSWindowController or a subclass of NSWindowController to manage the window, by making that class the File's Owner in Interface Builder. Once this is done, to grab an instance of the window use:
NSWindowController *wc = [[NSWindowController alloc] initWithWindowNibName:#"NIBNAMEHERE"];
[wc showWindow:nil];
Another alternative in your app would be to add an NSWindow IBOutlet to your app delegate, and load the window in your app delegate with:
[NSBundle loadNibNamed:#"NIBFILENAME" owner:self];
[_window makeKeyAndOrderFront];

Resources