エンドユーザにとって開発言語は遠い存在だが、アプリケーションソフトの類いは必ずなにかの開発言語により作られているわけで、決して無縁ではない。強く意識する必要はないにせよ、Finderで扱う存在である以上はかんたんな約束事程度は知っておいたほうがいい。今回は、「開発者でなくてもSwiftは使える」というテーマで話を進めたい。

Swiftで開発されたアプリの見わけかた

これまでOS XおよびiOSでネイティブアプリケーションの開発言語はObjective-Cとされてきたが、AppleはWWDC 2014の場で突如として「Swift」を発表。モダンさと厳密さを併せ持つ言語仕様にパフォーマンス重視の基礎設計、高効率なLLVMコンパイラ、さらにはインタラクティブなコーディングスタイルの採用と、これからのOS X/iOS/watchOS/tvOS向けソフトウェア開発をけん引するに相応しい仕様を備えている。

とはいえ、すべてのアプリケーションがいきなりSwiftで書き換えられることはない。機能追加の具体的なロードマップがある、複数の開発者が参加しており規模が大きい、などの理由で一気にコードを更新できない開発プロジェクトは多く、結果として現在もObjective-Cは第一線にある。登場から2年が経過したこともあり、Swiftで開発されたアプリケーションを見かける頻度は高まったが、いまだ少数派であることに変わりはない。

そんなSwiftで書かれたアプリケーションを見わけるには、バンドル内部を見ればいい。将来はともかく、現在のところSwiftの標準ライブラリはアプリケーションにバンドルされたものを利用するため(Swiftは静的ライブラリをサポートしない)、バンドル内部にいくつかのSwift用フレームワークが収録されているのだ。つまり、バンドル内部を「Contents」→「Frameworks」の順に開き、「libswift」から始まるフレームワークが複数収録されていれば、そのアプリケーションの開発にはSwiftが使われているということになる。

Swiftで開発されたアプリケーションは、現在のところバンドル内にランタイム用フレームワークが収録されている

コンパイルしてコマンド化できる「Swiftスクリプト」

SwiftはmacOSやiOSのネイティブアプリ開発を主対象としたプログラミング言語だが、そこで終わらないところがおもしろい。2015年12月にオープンソース化(ポータルサイト)され、いまではUbuntu Linux版も存在する。IBMがクラウドサービス「Bluemix」に移植したほか、Swift対応を真剣に検討中とされる企業もいくつか現れるなど、Apple製品にとどまらない勢いがここにはある。

当コラムも無関係ではない。基本的には開発情報は扱わないものの、シェルスクリプトならぬ「Swiftスクリプト」に使えるとなれば話は変わる。Xcodeのインストールが前提とはなるが、Swiftを学習しつつ日々の作業を効率化できるため、アプリ開発者でなくてもメリットがあるのだ。

さらに、個人的にはここがツボなのだが、コンパイルすればかんたんに「コマンド化」できる。使用する機能がごく基本的なもの -- たとえば「import Foundation」で済んでしまうもの -- であれば、Terminalから「swiftc ○○.swift -o △△」を実行するだけで、オリジナルのコマンドを作成できてしまうのだ。

シェルスクリプトとして使うときのポイントは2つ、ファイル(プレインテキストファイル)の1行目に「#!/usr/bin/swift」を記述しておくことと、ファイルに実行権限を与えておくこと(chmod +x ~)。ファイルの拡張子は「.swift」だが、実行時の条件ではないため適当でかまわない。Finderでダブルクリックして実行できるようにしたいのであれば、拡張子は「.command」としたほうがベターだろう。

リスト1は、カレントディレクトリ上のファイルをファイルサイズが大きい順に一覧するスクリプト。シェル(/bin/sh)で「ls -lS」を実行するだけのものだが、取り急ぎSwiftスクリプトの効果を知るにはじゅうぶんだろう。なお、「/bin/sh -c」の引数としてを実行するため、複数のコマンドを組み合わせればいろいろな使い方が可能になる。エラー発生時の処理をくわえれば、意外に実用的なものになるのではなかろうか。

Xcode 7.3には、バージョン2.2のSwiftが収録されている

Swiftスクリプト「lsls」を実行したところ。ファイルサイズの大きい順にカレントディレクトリの内容を表示している

リスト1:カレントディレクトリで「ls -lS」を実行するSwiftスクリプト

#!/usr/bin/swift

import Foundation

let filelist = NSTask()
filelist.launchPath = "/bin/sh"
filelist.arguments = ["-c", "ls -lS ./"]
filelist.launch()
filelist.waitUntilExit()