与其尝试检测您是否在使用 Terminal.app(例如,如果您使用不同的终端程序或在 Linux 上运行,这可能容易出错),您应该查询终端以了解它是否支持特定功能。这可以通过ncurses 库轻松完成。
1。将CCurses 目标添加到您的 Swift 包中
我们需要创建一个系统库目标,以便 Swift 包管理器知道如何查找和链接 ncurses 库将目标添加到您的Package.swift:
let package = Package(
// ...
targets: [
// ...
.systemLibrary(name: "CCurses"),
],
// ...
)
并在Sources/CCurses 创建一个新目录,其中包含以下文件:
curses.h
#include <curses.h>
#include <term.h>
module.modulemap
module CCurses [system] {
header "curses.h"
link "curses"
export *
}
2。检查终端是否支持颜色输出
在设置时,查询 terminfo 数据库以检查颜色支持:
import CCurses
// ...
var erret: Int32 = 0
if setupterm(nil, 1, &erret) != ERR {
useColor = has_colors()
} else {
useColor = false
}
基于https://stackoverflow.com/a/7426284。
如果您需要检查其他功能是否存在,几乎可以肯定有一个 ncurses 功能 - 只需检查 the man page、在线搜索或在此处询问。
ncurses dylib 在所有平台上都可用,但由于某种原因,标头仅存在于 macOS 上。无论如何,您在 iOS、watchOS 或 tvOS 上都不需要它,因为这些平台没有 终端。有两种方法可以排除在 iOS 上构建 ncurses 等:1)您可以在标头中使用#ifdef,或者 2)在 Swift 5.3 中,您可以声明一个 conditional target dependency,这会稍微简单和干净。
方法一:#ifdef 标头
改用以下Sources/CCurses/curses.h 文件:
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
#if !(defined TARGET_OS_IPHONE || defined TARGET_OS_WATCH || defined TARGET_OS_TV)
#include <curses.h>
#include <term.h>
#endif
然后,每当你在 Swift 代码中使用来自 curses 的函数时,用构建条件包围它:
#if os(iOS) || os(watchOS) || os(tvOS)
useColor = false
#else
var erret: Int32 = 0
if setupterm(nil, 1, &erret) != ERR {
useColor = has_colors()
} else {
useColor = false
}
#endif
方法 2:条件目标依赖(需要 Swift 5.3)
CCurses 目标无需更改;你只需要在你的Package.swift 中修改你对CCurses 的依赖:
.target(
name: "MyLib",
dependencies: [
.target(name: "CCurses", condition: .when(platforms: [.macOS, .linux]))
]),
并在您 import CCurses 或使用 curses 函数时使用构建条件:
#if canImport(CCurses)
import CCurses
#endif
// ...
#if canImport(CCurses)
var erret: Int32 = 0
if setupterm(nil, 1, &erret) != ERR {
useColor = has_colors()
} else {
useColor = false
}
#else
useColor = false
#endif