2015-06-10 1 views
2

Отказ от ответственности: Я пытаюсь выполнить следующее упражнение, потому что я думаю, что это будет поучительно. Меня интересует, как это можно сделать. Поэтому, пожалуйста, не спешите вскакивать с «Это неправильный способ сделать это, вы никогда не должны так делать!»Окно отображения на OSX с использованием Swift без XCode или NIB

Работая с командной строки с помощью моего любимого текстового редактора, я хотел бы создать минимальную программу Swift, которая отображает окно.

Это приветственный мир GUI/Cococa, если хотите.

В том же духе я хочу избежать НИБ.

Итак, нет XCode, нет НИБ.

Я хотел бы:

  • скомпилировать его с быстрым компилятором
  • создать #! быстрый скрипт, который работает с использованием интерпретатора Swift

Если я могу сделать обе эти вещи, я почувствую свои ноги на земле и буду намного более легко обновляться до Xcode.

Я попробовал следующее:

window.swift

import Cocoa 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 
    @IBOutlet weak var window: NSWindow! 
    let newWindow = NSWindow(contentRect : NSScreen.mainScreen()!.frame 
          , styleMask : NSBorderlessWindowMask 
          , backing : NSBackingStoreType.Buffered 
          ,  defer : false) 
    func applicationDidFinishLaunching(aNotification: NSNotification) { 
     // Insert code here to initialize your application 
     newWindow.opaque = false 
     newWindow.movableByWindowBackground = true 
     newWindow.backgroundColor = NSColor.whiteColor() 
     newWindow.makeKeyAndOrderFront(nil) 
    } 
    func applicationWillTerminate(aNotification: NSNotification) { 
     // Insert code here to tear down your application 
    } 
} 

Однако, пытаясь запустить из командной строки не удается:

[email protected] ~ /Users/pi/dev/macdev: 
⤐ swift window.swift 
window.swift:3:1: error: 'NSApplicationMain' attribute cannot be used in a 
         module that contains top-level code 
@NSApplicationMain 
^ 
window.swift:1:1: note: top-level code defined in this source file 
import Cocoa 
^ 
✘ 

Что правильный способ устранения Ошибка?

ответ

7

Сделать файл TestView.swift (как это):

import AppKit 

    class TestView: NSView 
    { 
      override init(frame: NSRect) 
      { 
        super.init(frame: frame) 
      } 

      required init?(coder: NSCoder) 
      { 
        fatalError("init(coder:) has not been implemented") 
      } 

      var colorgreen = NSColor.greenColor() 

      override func drawRect(rect: NSRect) 
      { 
        colorgreen.setFill() 
        NSRectFill(self.bounds) 

        let h = rect.height 
        let w = rect.width 
        let color:NSColor = NSColor.yellowColor() 

        let drect = NSRect(x: (w * 0.25),y: (h * 0.25),width: (w * 0.5),height: (h * 0.5)) 
        let bpath:NSBezierPath = NSBezierPath(rect: drect) 

        color.set() 
        bpath.stroke() 

        NSLog("drawRect has updated the view") 
      } 
    } 

сделать файл TestApplicationController.swift (как это):

import AppKit 

    final class TestApplicationController: NSObject, NSApplicationDelegate 
    { 

      ///  Seems fine to create AppKit UI classes before `NSApplication` object 
      ///  to be created starting OSX 10.10. (it was an error in OSX 10.9) 
      let  window1 =  NSWindow() 
      let  view1 =  TestView(frame: NSRect(x: 0, y: 0, width: 1000, height: 1000)) 

      func applicationDidFinishLaunching(aNotification: NSNotification) 
      { 
        window1.setFrame(CGRect(x: 0, y: 0, width: 1000, height: 1000), display: true) 
        window1.contentView = view1 
        window1.opaque  = false 
        window1.center(); 
        window1.makeKeyAndOrderFront(self) 
      //  window1.backgroundColor = view1.colorgreen 
      //  window1.displayIfNeeded() 
      } 

      func applicationWillTerminate(aNotification: NSNotification) { 
        // Insert code here to tear down your application 
      } 
    } 

сделать файл main.swift (как это):

// 
    // main.swift 
    // CollectionView 
    // 
    // Created by Hoon H. on 2015/01/18. 
    // Copyright (c) 2015 Eonil. All rights reserved. 
    // 

    import AppKit 

    let  app1   =  NSApplication.sharedApplication() 
    let  con1   =  TestApplicationController() 

    app1.delegate =  con1 
    app1.run() 

Последний файл не должен быть переименован, main.swift, по-видимому, является специальным именем для swift (иначе пример не будет компилироваться).

Теперь введите это (скомпилировать пример):

swiftc -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/TestView.swift TestApplicationController.swift main.swift 

Выполнить код, введя:

./main 

Это показывает главное окно (в центре) с красивым зеленым Коллором и а желтый прямоугольник внутри него). Вы можете убить приложение, введя Control-C.

Обратите внимание, что это быстрая компиляция, а не интерпретатор, поэтому у вас есть родное приложение.

Обратите внимание: необходим -sdk и путь к MacOSX10.11.sdk (иначе код не будет компилироваться).

Обратите внимание, что эта компиляция зависит от последнего распространения Xcode, поэтому обновите MacOSX10.11.sdk до MacOSX10.10.sdk или что-то еще в каталоге SDK.

потребовалось некоторое время, чтобы найти это ...

+0

Подробнее: в конце пути к SDK отсутствует директива компиляции «/MacOSX10.11.sdk». С этим он работает! – telliott99

0

Передайте -parse-as-library флаг swiftc:

swiftc -parse-as-library window.swift 

Это говорит, вы будете просто в конечном итоге работает во вторую ошибку, когда вы делаете это:

2015-06-10 14: 17: 47.093 window [11700: 10854517] Нет файла Info.plist в комплекте приложений или нет файла NSPrincipalClass в файле Info.plist, выходящего

+0

Если вы видите в рамках своего кода 'class AppDelegate: NSObject, NSApplicationDelegate', ему не нужно передавать это как библиотеку вообще: -/если что-то нужно для синтаксического анализа как' -primary-file', если это единственный файл, который маловероятен. –

+0

@AdrianSluyters Флаг имеет странное имя, но это флаг, который использует Xcode при компиляции приложения Swift, и в моих быстрых тестах он выполнял именно то, что было задано, и это испускало исполняемый файл, который позволяет '@ NSApplicationMain' работать. –

+0

Я предполагаю, что вам понадобится файл RADAR, а затем яблоко a, которое действительно странно –

1

Портирование this код из Objective-C Свифта, вы получите

import Cocoa 

let nsapp = NSApplication.shared() 
NSApp.setActivationPolicy(NSApplicationActivationPolicy.regular) 
let menubar = NSMenu() 
let appMenuItem = NSMenuItem() 
menubar.addItem(appMenuItem) 
NSApp.mainMenu = menubar 
let appMenu = NSMenu() 
let appName = ProcessInfo.processInfo.processName 
let quitTitle = "Quit " + appName 
let quitMenuItem = NSMenuItem.init(title:quitTitle, 
    action:#selector(NSApplication.terminate),keyEquivalent:"q") 
appMenu.addItem(quitMenuItem); 
appMenuItem.submenu = appMenu; 
let window = NSWindow.init(contentRect:NSMakeRect(0, 0, 200, 200), 
    styleMask:NSTitledWindowMask,backing:NSBackingStoreType.buffered,defer:false) 
window.cascadeTopLeft(from:NSMakePoint(20,20)) 
window.title = appName; 
window.makeKeyAndOrderFront(nil) 
NSApp.activate(ignoringOtherApps:true) 
NSApp.run() 

Сохранить это как minimal.swift, компилировать

swiftc minimal.swift -o minimal 

и запустить

./minimal 

Вы получите пустое окно и панель меню с меню, названным как приложение, и кнопкой quit.

Почему это работает точно, я не знаю. Я новичок в программировании Swift и Cocoa, но связанный веб-сайт немного объясняет.

Смежные вопросы