Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OSX application without storyboard or xib files using Swift

Tags:

macos

swift

cocoa

Unfortunately, I haven't found anything useful on the Internet - I wanted to know, what code I actually have to type for initializing an application without using storyboard or XIB files in Swift. I know I have to have a .swift file called main. But I don't know what to write in there (like do I need autoreleasepool or something like that?). For example, what would I do for initializing an NSMenu and how would I add a NSViewController to the active window (iOS's similar .rootViewController doesn't help). Thanks for any help ;)

Edit: I actually don't want to use @NSApplicationMain in front of the AppDelegate. I'd rather know what exactly happens there and then do it myself.

like image 654
borchero Avatar asked Mar 01 '15 10:03

borchero


People also ask

Should I use storyboard or XIB?

When you want to see some flow without building the app, a storyboard is the best option. Also if you create static table views or more then one cell template, you can use a storyboard.

How do you make an app for OSX?

Start by adding a macOS target to the project. Xcode adds a new group and set of starter files for the macOS app, along with the scheme needed to build and run the app. You'll then add some existing files to the new target. To be able to preview and run the app, be sure your Mac is running macOS Monterey or later.

What is XIB Swift?

Swift version: 5.6. NIBs and XIBs are files that describe user interfaces, and are built using Interface Builder. In fact, the acronym "NIB" comes from "NeXTSTEP Interface Builder", and "XIB" from "Xcode Interface Builder".


3 Answers

if you don't want to have the @NSApplicationMain attribute, do:

  1. have a file main.swift

  2. add following top-level code:

     import Cocoa   let delegate = AppDelegate() //alloc main app's delegate class  NSApplication.shared.delegate = delegate //set as app's delegate  NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) //start of run loop          // Old versions:  //  NSApplicationMain(C_ARGC, C_ARGV)  //  NSApplicationMain(Process.argc, Process.unsafeArgv);   

the rest should be inside your app delegate. e.g.:

import Cocoa  class AppDelegate: NSObject, NSApplicationDelegate {     var newWindow: NSWindow?     var controller: ViewController?          func applicationDidFinishLaunching(aNotification: NSNotification) {         newWindow = NSWindow(contentRect: NSMakeRect(10, 10, 300, 300), styleMask: .resizable, backing: .buffered, defer: false)                  controller = ViewController()         let content = newWindow!.contentView! as NSView         let view = controller!.view         content.addSubview(view)                  newWindow!.makeKeyAndOrderFront(nil)     } } 

then you have a viewController

import Cocoa  class ViewController : NSViewController {     override func loadView() {         let view = NSView(frame: NSMakeRect(0,0,100,100))         view.wantsLayer = true         view.layer?.borderWidth = 2         view.layer?.borderColor = NSColor.red.cgColor         self.view = view     } } 
like image 66
Daij-Djan Avatar answered Sep 19 '22 08:09

Daij-Djan


The top level code sample above no longer works in recent versions of Xcode. Instead use this:

import Cocoa  let delegate = AppDelegate() //alloc main app's delegate class NSApplication.shared().delegate = delegate //set as app's delegate  let ret = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) 
like image 32
Ted Lemon Avatar answered Sep 20 '22 08:09

Ted Lemon


In Swift 4 it has changed slightly yet again,

The main file must have

import Cocoa

let delegate = AppDelegate()
NSApplication.shared.delegate = delegate

NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

The AppDelegate must be

import Cocoa


class AppDelegate: NSObject, NSApplicationDelegate {
    var newWindow: NSWindow?
    var controller: ViewController?

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        newWindow = NSWindow(contentRect: NSMakeRect(10, 10, 300, 300), styleMask: .resizable, backing: .buffered, defer: false)

        controller = ViewController()
        let content = newWindow!.contentView! as NSView
        let view = controller!.view
        content.addSubview(view)

        newWindow!.makeKeyAndOrderFront(nil)
    }
}

The view controller is the same

like image 44
Noskcaj Avatar answered Sep 18 '22 08:09

Noskcaj