System
は、一般的にOSレベルで定義されるシステムコールや通貨型に関して、慣用的で型安全なインターフェースを提供する目的で、AppleがWWDCカンファレンスで紹介した低レベルのライブラリである。Swiftをクロスプラットフォームな開発エコシステムとしてプッシュするというAppleの目標に従って、プログラマがプラットフォームを越えた開発を容易にコントリビュートできるようにする上で、System
はその根源としての役割を果たすものだ。
SwiftNIOやSwiftPMといった、OS層に近いライブラリの開発を簡略化する手段としてSystem
は誕生した。
私たちの目標は、Swiftがサポートするすべてのプラットフォームにおいて、Systemが最終的に、低レベルインターフェースの単一のホームとして機能するようになることです。
前述のようにSystem
は、Swiftの型システムを活用することで、(OSレベルの機能を)慣用的で安全、かつ表現力のあるものにしようとしている。これはつまり、例えばC APIで多用されている整数値に代えてstruct
やenum
を使用したり、char*
の代わりにFilePath
などの強い型を積極的に使用する、ということである。さらには、Swiftのエラー処理機構であるdo/try/catch
構文によって、エラーを無視することが難しくなる。もうひとつ言及すべき点として、シグナルによって割り込まれる可能性のあるシステムコールすべてでretryOnInterrupt
動作がデフォルトになっているため、自動的にリトライが実施される。
以下の例は、System
でファイルをオープンする方法を示すものだ。
let message: String = "Hello, world!" + "\n"
let path: FilePath = "/tmp/log"
let fd = try FileDescriptor.open(
path, .writeOnly, options: [.append, .create], permissions: .ownerReadWrite)
try fd.closeAfter {
_ = try fd.writeAll(message.utf8)
}
System
それ自体はクロスプラットフォームを目指したものでない、すなわち、すべてのサポート対象プラットフォームに共通するAPIを公開するものではない、という点には注意が必要である。System
の目的はそうではなく、基盤にあるOS APIの形式にAPIを適応させることなのだ。これにより、System
を複数プラットフォームに移植する作業が容易になることは確実だが、同時にSystem
では#if os()
によるガードを使用する必要がある。
現在実装されているSystem
モジュールには、ごく少数のシステムコールと通貨型の他には、LinuxやmacOSといったUNIX系OSで利用可能な、Cの低レベルAPIに結びついたユーティリティ機能が含まれているに過ぎない。ただしAppleは、ロードマップ上の次の目標としてSystem
をWindows上で使用可能にすることを挙げており、先日発表されたSwift for Windowsのより強力なケースとなっている。
SwiftプロジェクトへのSystem
の追加は、Swift Package Managerを使って行うことができる。それにより、以下の例のように、"SystemPackage"として参照することが可能になる。
let package = Package(
// name, platforms, products, etc.
dependencies: [
.package(url: "https://github.com/apple/swift-system", from: "0.0.1"),
// other dependencies
],
targets: [
.target(name: "MyTarget", dependencies: [
.product(name: "SystemPackage", package: "swift-system"),
]),
// other targets
]
)
注意すべき点として、System
は開発の早期段階にあるため、大幅な変更が行われる可能性がある。そのため、互換性が期待できるのは、0.0.1と0.0.3というように、マイナーバージョン間に限定される。