swift 如何为NSApplication.shared示例使用自定义应用程序类?如果没有NIB/Storyboard文件,则不使用主体类

yc0p9oo0  于 2023-11-16  发布在  Swift
关注(0)|答案(1)|浏览(109)

我想使用NSApplication的自定义子类来创建应用程序示例。这是NSApplication.shared返回的对象的类。我尝试了以下方法:

class Application: NSApplication {
    // My own items
}

字符串
然后,我尝试在Info.plist中将 Principal classNSApplication设置为Application。然后,我尝试通过print(NSApplication.shared as! Application)来确认这是否有效,但这会中止程序,这意味着应用程序示例的类尚未成功设置为我的自定义类。我该怎么做?
我知道我能做到:

extension NSApplication {
    // My own items
}


但是,有没有办法用子类而不是扩展来实现这一点,使我的子类实际上被示例化?

更新:

我尝试在我当前的项目中做answer says,但没有效果。然而,奇怪的是,如果我创建一个新的macOS应用程序模板,并且只做 * 答案中指定的修改,没有问题。
然而,我能够在一个新的项目中重现这个问题,方法是删除.storyboard/.nib,并将AppDelegate.swift替换为main.swift,如下所示:

import Cocoa
class Application: NSApplication, NSApplicationDelegate {
    func applicationShouldTerminateAfterLastWindowClosed(_ _: NSApplication) -> Bool {
        return true
    }
}
NSApplication.shared.delegate = (NSApp as! Application)
NSApp.run()


我还使Info.plist包含以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSMinimumSystemVersion</key>
    <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
    <key>NSPrincipalClass</key>
    <string>$(PRODUCT_MODULE_NAME).Application</string>
    <key>NSSupportsAutomaticTermination</key>
    <true/>
    <key>NSSupportsSuddenTermination</key>
    <true/>
</dict>
</plist>


这就是它的全部内容。项目中唯一的文件是如上所示的main.swiftInfo.plist以及未修改的Assets.xcassets.entitlements文件。同样,我在Xcode中使用了一个新的macOS应用程序模板。
这个问题的另一个证明是,这个Assert失败了:

assert(type(of: NSApplication.shared) == Bundle.main.principalClass!)


Bundle.main.principalClass的值是预期的,但由于某种原因,NSApplication.shared没有示例化这种类型的类。

zmeyuzjn

zmeyuzjn1#

您需要确保Principal class包含正确的模块名称以便加载。
这很好用:

@main
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print("NSApp:", NSApplication.shared as! MyApplication)
    }
}

class MyApplication: NSApplication {
    
}

字符串


的数据
它打印:
NSApp:<CustomClass.MyApplication: 0x12af053b0>

相关问题