创建 macOS 桌面应用程序

本指南概述了 Solar2D 中特定于 macOS 桌面应用程序的功能。使用Corona 构建的macOS 桌面应用程序由一个 .app 包组成,其中包含 Corona 运行时引擎以及 Corona 项目的已编译代码和资源。

系统要求

注意

macOS 版 Corona Simulator 支持的所有功能都支持 macOS 桌面版本。

构建优秀的 macOS 应用程序

许多开发者会从 iOS 应用程序开始,打算将其复制到 Mac 平台。首先,要避免一种诱人的假设,即您只需选择文件构建macOS…从 Corona Simulator 菜单中即可从 iOS 应用程序创建 macOS 应用程序。桌面和设备平台差异很大,虽然 Corona 隐藏了许多实际的实现细节,但它无法神奇地将专为触摸屏设备设计的应用程序变成优秀的基于鼠标的桌面体验。

请记住,您的 macOS 应用程序在被Mac App Store接受之前将接受 Apple 的审核流程。这将涵盖与 iOS 应用程序审核相同类型的问题,但由于 macOS 应用程序可能会在此方面被拒绝,因此还有一个额外的门槛需要清除

Your app appears to be a mostly unmodified port of an iOS app.

除其他事项外,您应该考虑您的应用程序如何响应窗口大小变化以及它如何在全屏模式下工作。内容区域的大小在桌面上比在设备上变化更大,您几乎肯定需要更改您的应用程序,使其在桌面环境中良好运行。请记住,您可以调整窗口大小和内容区域,它们不必相同。还要记住,横向方向是用户所期望的,因此在桌面环境中使用纵向应用程序将更难留下良好的印象。

显然,您可以从Mac App Store下载的任何内容都已通过审核流程,因此请务必下载与您的应用程序同类型的其他应用程序,看看它们在桌面上如何工作,并考虑如何修改您的应用程序以使其以类似的方式工作。

窗口设置

对于 macOS 桌面应用程序和 Win32 桌面应用程序,Corona 的 build.settings 文件都支持使用 window 表来自定义应用程序的桌面窗口,包括默认宽度/高度、窗口标题等。

settings =
{
    window =
    {
        -- Settings for the desktop window; applies to both macOS and Win32 desktop apps
    },
}

window 表中,支持以下设置

defaultMode

设置窗口在启动时应如何启动。支持的值包括 "normal"(正常)、"minimized"(最小化)、"maximized"(最大化)或 "fullscreen"(全屏)。默认为 "normal"。这也可以通过 native.setProperty() API 以编程方式设置。

settings =
{
    window =
    {
        defaultMode = "fullscreen",
    },
}
defaultViewWidth

设置窗口的视图/客户端区域的默认启动宽度。这是窗口边框内 Corona 渲染到的区域。理想情况下,这应该与您的 config.lua 内容区域宽度匹配或超过它。

settings =
{
    window =
    {
        defaultViewWidth = 640,
    },
}
defaultViewHeight

设置窗口的视图/客户端区域的默认启动高度。这是窗口边框内 Corona 渲染到的区域。理想情况下,这应该与您的 config.lua 内容区域高度匹配或超过它。

settings =
{
    window =
    {
        defaultViewHeight = 960,
    },
}
resizable

将其设置为 true 以允许最终用户调整窗口大小(默认情况下窗口不可调整大小)。请注意,如果设置为 true,您可能需要处理 Corona 的 resize 事件来重新布局您的内容。

settings =
{
    window =
    {
        resizable = true,
    },
}
minViewWidth

此设置仅在 resizable 设置为 true 时适用。防止用户将窗口宽度调整为小于此值。请注意,这表示窗口边框内区域的宽度。如果 resizable 设置为 true 并且未指定此设置,则窗口可以调整大小到操作系统允许的任何宽度。

settings =
{
    window =
    {
        minViewWidth = 320,
    },
}
minViewHeight

此设置仅在 resizable 设置为 true 时适用。防止用户将窗口高度调整为小于此值。请注意,这表示窗口边框内区域的高度。如果 resizable 设置为 true 并且未指定此设置,则窗口可以调整大小到操作系统允许的任何高度。

settings =
{
    window =
    {
        minViewHeight = 480,
    },
}
enableCloseButton

启用或禁用窗口的“关闭”按钮(默认情况下启用)。如果禁用,您必须通过 native.requestExit() 在 Lua 中关闭窗口。请注意,Corona 目前不会在单击“关闭”按钮时触发事件。

settings =
{
    window =
    {
        enableCloseButton = true,
    },
}
enableMinimizeButton

启用或禁用窗口的“最小化”按钮(默认情况下启用).

settings =
{
    window =
    {
        enableMinimizeButton = true,
    },
}
enableMaximizeButton

启用或禁用窗口的“最大化”按钮(默认情况下禁用)。请注意,最大化/还原窗口时会调整窗口大小,因此如果此设置是 true,您可能需要处理 Corona 的 resize 事件来重新布局您的内容。

settings =
{
    window =
    {
        enableMaximizeButton = true,
    },
}
suspendWhenMinimized

指示运行时在窗口最小化时挂起(默认情况下禁用).

settings =
{
    window =
    {
        suspendWhenMinimized = true,
    },
}
showWindowTitle

使窗口的标题栏显示(默认)或隐藏,使应用程序的内容填充整个窗口。在窗口顶部拖动将像常规窗口一样移动它,并且此区域中的单击不会转到应用程序。此设置仅在 macOS 上受支持。

settings =
{
    window =
    {
        showWindowTitle = false,
    },
}
titleText

将窗口的标题栏文本设置为指定的 字符串(默认情况下没有标题栏文本)。 支持两位 ISO 639‐1 语言代码和可选的两位 ISO 3166‐1 国家/地区代码(两者都不区分大小写)。 还可以通过 native.setProperty() API 以编程方式设置 default 标题文本。

settings =
{
    window =
    {
        titleText = {
            -- The "default" text will be used if the system is using a language and/or
            -- country code not defined below. This serves as a fallback mechanism.
            default = "Window Title Test",
            -- This text is used on English language systems in the United States.
            -- Note that the country code must be separated by a dash (-).
            ["en‐us"] = "Window Title Test (English‐USA)",
            -- This text is used on English language systems in the United Kingdom.
            -- Note that the country code must be separated by a dash (-).
            ["en‐gb"] = "Window Title Test (English‐UK)",
            -- This text is used for all other English language systems.
            ["en"] = "Window Title Test (English)",
            -- This text is used for all French language systems.
            ["fr"] = "Window Title Test (French)",
            -- This text is used for all Spanish language systems.
            ["es"] = "Window Title Test (Spanish)",
        },
    },
}

排除文件

您可以通过 build.settings 文件的 excludeFiles 模式匹配功能排除 macOS 桌面应用程序不需要的文件。有关模式匹配的更多详细信息,请参阅项目构建设置指南的**排除文件**部分。

包含资源

有时需要在应用程序中包含某些文件以支持特定的 macOS 功能。一个例子是**本地化**,它是在操作系统级别(例如 Finder 的应用程序标签)使用应用程序 Resource 目录中的 .lproj 目录实现的(背景)页面。请注意,这种在应用程序中包含任意资源的机制仅用于使您能够完成某些任务,而不是用于自动执行任何操作。

要在应用程序的 Resource 目录中包含任意文件,请将 bundleResourcesDirectory 条目添加到您的项目的 macOS 版本的 build.settings 中。例如

settings =
{
    macos =
    {
        bundleResourcesDirectory = "osx-resources",
    },
}

然后,在项目中,osx-resources 目录的内容可能如下所示

fr.lproj/

osx-resources/fr.lproj:
InfoPlist.strings

这将导致 fr.lproj 目录最终位于 MyApp.app/Content/Resources/fr.lproj 中。

您可能希望将用作 bundleResourcesDirectory 的目录添加到您的排除文件中。

自定义 URL 方案

要在 macOS 应用程序中启用自定义 URL 方案,您需要在应用程序的 Info.plist 中进行设置,方法是在 build.settings 中包含如下所示的部分

settings =
{
    macos =
    {
        plist =
        {
            CFBundleURLTypes =
            {
                {
                    CFBundleURLName = "My URL Scheme",
                    CFBundleURLSchemes = {
                        "myscheme",
                    },
                },
            },
        },
    },
}

这将允许应用程序从(或由其启动)**终端**命令(例如)接收消息

open myscheme://these/are/the/parameters

要在 Corona 应用程序中处理消息,请实现如下所示的处理程序

local function onSystemEvent( event )
    if ( event.type == "applicationOpen" and event.url ) then
        local launchURL = event.url
        print( "Event: applicationOpen - launchURL: ", launchURL )
    end
end

Runtime:addEventListener( "system", onSystemEvent )

自定义文档类型

与自定义 URL 方案的工作方式类似,您可以设置应用程序识别的文档类型,可以通过将它们拖到**访达**或**程序坞**中的应用程序图标来打开它们。

要在 macOS 应用程序中启用自定义文档类型,您需要在应用程序的 Info.plist 中进行设置,方法是在 build.settings 中包含如下所示的部分

settings =
{
    macos =
    {
        plist =
        {
            CFBundleDocumentTypes =
            {
                {
                    CFBundleTypeExtensions =
                    {
                        "png",
                    },
                    CFBundleTypeIconFile = "app.icns",
                    CFBundleTypeName = "public.png",
                    LSHandlerRank = "Alternate",
                    LSItemContentTypes =
                    {
                        "public.png",
                    },
                },
            },
        },
    },
}

在您的 Corona 应用程序中,实现如下所示的处理程序

local function onSystemEvent( event )
    if ( event.type == "applicationOpen" and event.url ) then
        local filename = event.url
        print( "Event: applicationOpen - filename: ", filename )
    end
end

Runtime:addEventListener( "system", onSystemEvent )

当具有已配置类型的文件被拖放到**访达**或**程序坞**中的应用程序图标上时,将调用此代码。更多信息可在 Apple 的开发者核心基础键文档中找到。

权限

如果您需要在 macOS 应用程序中自定义权限,请在 build.settings 中指定它们。例如,如果您使用 Corona 的 location 功能,则可能需要指定 com.apple.security.personal-information.location 权限。

settings =
{
    macos =
    {
        entitlements = {
            ["com.apple.security.personal-information.location"] = true,
        },
    },
}

应用程序图标

您应该将 Icon-osx.icns 文件添加到 Corona 项目的根目录,以便为 macOS 上的应用程序提供图标。 这应该是一个 .icns 文件,其中包含不同分辨率的多个版本的图标(详细信息)。这个Icon-osx.icns文件将用于设置以下图标

  1. 您的 .app 包使用的图标,如在 Finder 中查看的那样。
  2. 您的应用程序在程序坞中使用的图标。

您可以在 Mac App Store 中找到可帮助创建 .icns 文件的应用程序。

构建 / 运行

要构建和运行 macOS 桌面应用程序,请按照以下步骤操作

  1. 打开 Corona Simulator。

  2. 打开并运行一个 Corona 项目。

  3. 选择文件构建macOS…菜单项以显示 macOS 构建对话框。

  4. **应用程序名称**、**版本**和**保存到文件夹**字段都是必需的。以下是有关这些构建对话框字段的注释

    • **应用程序名称** — 您输入的应用程序名称可以在运行时通过 Corona 的 system.getInfo( "appName" ) 调用获取(参考)。

    • **版本** — 您输入的版本字符串可以在运行时通过 Corona 的 system.getInfo( "appVersionString" ) 调用获取(参考)。

    • **配置文件** — 应用程序的配置文件;请参阅下面的应用程序签名

    • **保存到文件夹** — 用于保存构建项目的目录。

    • **构建后** - 选择应用程序成功构建后应执行的操作。

  5. 单击**构建**按钮将您的应用程序构建到给定的**保存到文件夹**位置。如果您选择发送到 Mac App Store…,将打开一个面板,允许您选择首选选项的选项卡,并按照提示完成构建。

调试

Corona Simulator 目前不支持直接模拟以 macOS 桌面模式运行的应用程序,尽管运行“自定义设备”皮肤的 Simulator 几乎相同。

请注意,当运行构建的 macOS Corona 应用程序或 Corona Shell 时,所有 print() 输出和 Lua 错误/警告都将流式传输到 stdout。有多种方法可以管理此输出。一种方法是在终端窗口中运行嵌入在应用程序包中的可执行文件,这将使调试输出可见。例如

./Bridge\ for\ OS\ X/Contents/MacOS/Bridge\ for\ OS\ X

在此示例中,反斜杠 (\) 保护文件名中的空格(或者,您可以使用引号)。

您还可以使用**应用程序** → **实用工具**文件夹中的**控制台**应用程序来查看应用程序输出。

如果您在 Corona 模拟器构建对话框中选择构建后打开应用程序选项来运行应用程序,则应用程序的输出将显示在 Corona 模拟器控制台窗口中。

应用程序签名

您需要从 Apple Developer 门户获取“Mac Apps”配置文件才能对您的 macOS 应用程序进行签名。这与 iOS 应用程序签名过程非常相似,但您可以选择在执行构建时在配置文件下拉列表中选择来创建未签名的应用程序。未签名的应用程序可以在您自己的机器上运行,并且通过对“安全性与隐私”(位于“系统偏好设置”中)进行一些调整,也可以在其他 Mac 上运行。但是,未签名的应用程序不能提交到 Mac App Store,因此您最终需要整理您的 Mac 配置文件。

配置文件应安装在~/Library/MobileDevice/Provisioning Profiles中。可能需要手动执行此操作。

为了进行测试,建议您使用您的 Mac 应用程序签名标识对应用程序进行签名,方法是在 Corona 模拟器macOS 构建对话框中选择它,然后告诉您的测试人员在“安全性与隐私”“系统偏好设置”面板上选择Mac App Store 和已识别开发者选项。

分发

您可以通过 Mac App Store、.dmg 或任何其他分发 .app 捆绑包的方式分发您的应用程序。

如果不使用 Mac App Store,我们建议您使用您的 Mac 应用程序签名标识对应用程序进行签名,方法是在 Corona 模拟器构建对话框菜单中选择它,然后告诉您的测试人员在“系统偏好设置”面板上选择Mac App Store 和已识别开发者选项。“安全性与隐私”“系统偏好设置”面板上选择Mac App Store 和已识别开发者选项。

如果使用 .zip 存档来分发您的应用程序,请注意构建的 .app 捆绑包中存在符号链接,因此如果您在命令行上运行 zip 来创建存档,则必须指定 -y 选项(在 Finder 中使用压缩选项会自动执行正确的操作)。否则,当在其他计算机上运行时,macOS 会提示应用程序已损坏。另请注意,某些文件共享服务可能会损坏 macOS 应用程序,因此我们建议您在上传之前将它们放入 .zip 存档中。