5 Replies
      Latest reply: Jul 2, 2015 1:24 PM by bob133 RSS
      p-i- Level 1 Level 1 (0 points)

        I always find it instructive to start from the commandline. When I subsequently migrate to IDE, my feet are on the ground.

         

        I've been trying with a basic "hello world" style Swift snippet: the challenge is to draw a window on the screen without using Xcode.

         

        Now Swift has a compiler and an interpreter. So the challenge bifurcates -- to get it running on each.

         

        Could someone provide a set of instructions for each, together with an explanation of what's going on?

         

        π

        • Re: Swift from the commandline
          QuinceyMorris Level 6 Level 6 (2,580 points)

          There's no interpreter. It's always the compiler.

          • Re: Swift from the commandline
            ahltorp Level 3 Level 3 (410 points)

            You can put a window on the screen by creating an NSWindow object and telling it to show itself.

             

            import Cocoa
            let rect = NSRect(x:100,y:100,width:100,height:100)
            let window = NSWindow(contentRect: rect, styleMask: NSTitledWindowMask, backing: .Buffered, `defer`: false)
            window.makeKeyAndOrderFront(nil)
            

             

            makeKeyAndOrderFront tells the window to show itself and make it the frontmost window. The "frontmost window" in this case is from what I understand relative to the application, but the command line Swift interpreter doesn't have an application, you would have to create that as well. For now, I just set the window level to 1 to make it appear:

             

            window.level = 1
            

             

            This makes it float above all windows at level 0, i.e. the normal window level.

             

            To make something actually appear in the window, you have to make an NSView and make it draw something:

             

            class MyView : NSView {
                override func drawRect(dirtyRect: NSRect) {
                    NSColor.redColor().set()
                    NSRectFill(dirtyRect)
                }
            }
            window.contentView = MyView()
            

             

            The problem here is that you still won't see anything. I'm guessing that the reason is that the runloop is not running. Unfortunately, I don't know how to start it correctly.

              • Re: Swift from the commandline
                ahltorp Level 3 Level 3 (410 points)

                Another way of drawing in the window is to not use an NSView, but draw directly into the window:

                 

                NSGraphicsContext.setCurrentContext(window.graphicsContext)
                NSColor.redColor().set()
                NSRectFill(NSRect(x:0,y:0,width:100,height:100))
                window.flushWindow()
                
                

                 

                The steps here are:

                1. Setting the current graphics context (a global variable for the thread) to the graphics context of the window
                2. Setting the current color of the graphics context to red
                3. Filling a rectangle in the graphics context
                4. Flushing the contents so that the result is visible

                 

                And now you can show a window and draw into it only using the command line.

                 

                Even though this is possible, depending on what you want to do it is probably better to use the playgrounds in Xcode, since they work in a similiar way to a command line, but actually runs in the same kind of environment as "normal" applications.

              • Re: Swift from the commandline
                Jens Level 3 Level 3 (230 points)

                Below is the "Webkit Browser in 30 Lines of Swift" from practicalswift.com, with some small changes to make it run on latest beta with Swift 2.

                (Omitted link because this will get stuck in moderation otherwise ...)

                 

                1. Create a file called browser.swift (or whatever) containing this:

                #!/usr/bin/swift
                import WebKit
                let application = NSApplication.sharedApplication()
                application.setActivationPolicy(NSApplicationActivationPolicy.Regular)
                let window = NSWindow(contentRect: NSMakeRect(0, 0, 960, 720), styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask, backing: .Buffered, `defer`: false)
                window.center()
                window.title = "Minimal Swift WebKit Browser"
                window.makeKeyAndOrderFront(window)
                class WindowDelegate: NSObject, NSWindowDelegate {
                    func windowWillClose(notification: NSNotification) {
                        NSApplication.sharedApplication().terminate(0)
                    }
                }
                let windowDelegate = WindowDelegate()
                window.delegate = windowDelegate
                class ApplicationDelegate: NSObject, NSApplicationDelegate {
                    var _window: NSWindow
                    init(window: NSWindow) {
                        self._window = window
                    }
                    func applicationDidFinishLaunching(notification: NSNotification) {
                        let webView = WebView(frame: self._window.contentView.frame)
                        self._window.contentView.addSubview(webView)
                        webView.mainFrame.loadRequest(NSURLRequest(URL: NSURL(string: "https://forums.developer.apple.com/thread/5137")!))
                    }
                }
                let applicationDelegate = ApplicationDelegate(window: window)
                application.delegate = applicationDelegate
                application.activateIgnoringOtherApps(true)
                application.run()
                
                

                 

                2. Make it executable (chmod +x browser.swift).

                 

                3. Run (./browser.swift)

                • Re: Swift from the commandline
                  bob133 Level 4 Level 4 (955 points)

                  I can help you with the interpreter part.  With Swift, it's called the read-evaluate-play loop (REPL), and it's accessible from both the command line and from the LLDB debugger terminal.

                   

                  To open the REPL in the command line, type this command:

                  xcrun swift
                  

                  The tool isn't downloaded by default, so you'll be prompted to download and install it.

                  Once you get the REPL working, just type a line of code and hit Return—it will be immediately compiled and executed and you'll be able to see the current state of your variables.  I don't know if you'll be able to create a window with it, though, but it's great for learning the language.