この記事は、フラー株式会社のカレンダー | Advent Calendar 2023 - Qiita の 22 日目の記事です。
21 日目は @devKyousuke さんで TShockを用いてAWSでTerrariaのサーバーをたてよう でした。
はじめに
学習指導要領の改訂に伴い、プログラミング教育は2020年度から小学校で必修化され、翌年には中学校でも必修化されました。
そして、AppleからSwift Playground Bookを使った中学校向けの教材もリリースされています。
プログラミング教育にフォーカスが当たり始めた今、我々も若きエンジニアを育てるために何かできることはないでしょうか?
Swift Playground Bookなら、若い世代にプログラミングの楽しさを知ってもらうための教材作りがSwiftでできるのです。
本セッションではXcodeでPlayground Bookを作る方法からデバッグ方法、リリースの方法までを実際にコードを見ながら説明していきます。
アプリ開発とは全く異なるXcodeプロジェクトの構造から始まり、特殊な文章表現・単語説明機能などPlayground Bookならではの内容について解説します。
…と、これが私がiOSDC Japan2023に投稿し、見事不通過となったプロポーザルです。
本日はこの投稿で語ろうとしていた、Swift Playground Bookの作り方(の一部)についてお話しようと思います。
なお、Playgournd Bookの作り方についてはAppleの公式ドキュメントがあるので、ぜひそちらもご覧ください。
Swift Playground Bookとは
Playgroundsの種類
Swift Playgroundsには2種類の形式が存在します。
1つめがアプリ開発中に使う方も多いであろう(?)、Playgroundファイルです。
Swiftコードをインタラクティブに実行でき、主に簡単なコードの動作確認などに使われるものです。

そして2つめが今回ご紹介する、Playground Bookファイル(以下PBファイル)です。
主に教材として使われることを想定した、教科書のような構造のファイルです。
独自の説明文表示やヒントの表示など、Playgroundファイルには無い、より教育的な側面をもった様々な機能を有しています。
どうやって作るの?
さて、そもそもどうやってPBファイルを作り始めれば良いのでしょうか?
答えは簡単、AppleのダウンロードページからXcodeテンプレートファイルをダウンロードし、それを編集していくのです。
Xcodeから新規プロジェクト作成、みたいなことはできないんですね。
ちなみに2023/12/21現在、最新のテンプレートはXcode14.1用となっています。が、このテンプレートはXcode15.1でも使用できるのでご安心ください。
ダウンロードして展開すると、以下のようなディレクトリ構成になっています。

この中のPlaygroundBook.xcodeprojを開き、Xcode上で編集していきましょう。
以下、このプロジェクトを便宜上「PBプロジェクト」と呼びます。
PBプロジェクトの構造(概要編)
さて、ここからはPBプロジェクトがどのような構造になっているか、大枠をご紹介します。
ダウンロードしてきたテンプレートファイルを開くと、下図のようなプロジェクト構造になっています。
まずはManifestファイルです。こちらがPBプロジェクトの要であり、ブックの名前や章立てなどの情報をここに記述します。

次にModulesとUserModulesディレクトリです。
- Modules
- ブック全体で使用するファイル郡を配備します。この中に配備したコードはビルドして実際に使用する際にユーザには見えません。裏で少し凝ったことをしたいけど、教材自体はできるだけシンプルに留めて学習範囲を絞りたい、といったときに使えそうですね。
- UserModules
次はChapterとPageです。
PBファイルの構造(詳細編)
BookのManifestファイル
まずは全体の構成を司る、Book全体のManifestファイルを見てみましょう。
中身は以下のようになっています。

Chaptersキーの配列に.playgroundchapterの名前をそれぞれ入力する必要があります。
$(PLAYGROUND_BOOK_DISPLAY_NAME)などの変数は、Config Filesディレクトリ内のBuildSettingsファイルで設定できます。
Chapter
次にChapterの構造を見ていきましょう。
1つのChapterはplaygroundchapterディレクトリから成り、その中にはManifestファイル、Pagesディレクトリが存在します(Pagesの構成は後述)。
- Manifestファイル
- チャプター名と、そのチャプターが持つpageの一覧を保持しています。
- Pagesディレクトリ
- 後述のPageディレクトリの一覧を保持しています。
Manifestファイルは、例えばPageが3つ存在するChapterの場合、以下のような構造になります。

Page
次にPageです。
1つのPageはplaygroundpageディレクトリで構成され、その中にはLiveView.swiftとmain.swiftの2つのSwiftファイルが存在します。やっとSwiftファイルが出てきましたね!
LiveView.swifとmain.swiftはそれぞれ、教材1ページの右側と左側のビューを表現しています。

こちらはプロジェクトをビルドして、PBファイルとして開いたときのビューを見ながらの方が理解しやすいのでその画像をお見せします。
上記のように、main.swiftに記載した内容は主に教材として、説明文と実際にユーザにコードを記述してもらう箇所になります。
LiveView.swiftは、main.swiftに記述したコードの実行する前の状態を表現する画面です。
デフォルトのLiveViewは中央にLive Viewと書かれているだけのシンプルな画面ですが、ここを任意のViewControllerに差し替えることにより、Appleが出しているPBファイル(上記画像)のように、プログラム実行前の画面を良い感じに変更することができます。
↓テンプレートのままビルドして実行するとこんな感じになります。味気ない…

なお、LiveViewの領域は画面下部の「コードを実行」ボタンを押下するとその実行結果が表示されます。
例えばmain.swiftを以下のように記述してPBファイル上で実行すると…
import MapKit
import PlaygroundSupport
let mapView = MKMapView()
mapView.preferredConfiguration = MKStandardMapConfiguration()
let location = CLLocationCoordinate2D(
latitude: 35.8948967197249,
longitude: 139.9518645086708
)
let annotation = MKPointAnnotation()
annotation.coordinate = location
mapView.addAnnotation(annotation)
let span = MKCoordinateSpan(latitudeDelta: 0.45, longitudeDelta: 0.45)
let region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
PlaygroundPage.current.liveView = mapView
Modules, UserModules
ModulesとUserModulesの構成は非常にシンプルで、それぞれ内部にSourcesディレクトリを作成し、その中にソースファイルを配備するだけです。
以下のように作成したModulesとUserModulesをPBファイルで開くと…

下図のように表示されます。
Modulesの中身はユーザに見えていないことがわかりますね。

どうやってデバッグするの?
PBファイルのプロジェクトは.xcodeproj形式になっているので、そのファイルを開いてXcode上で編集を行います。
デバッグを行う場合、Xcode上でRunを実行するとPBファイルが開く…というわけではありません。
ビルドディレクトリを開き、Build > Products > Debug-iphonesimulator(ここは実行時に選択したシミュレータによって異なります)内に、{Book名}.playgroundbookというファイルが生成されています。
これをダブルクリックすることで、PCにインストールしたSwift Playgroundアプリ上でPBファイルが開けます。
iPadで実機確認したいときはどうすればいいかって?
先程の.playgroundbookをAirDropでiPadに送るだけです!とっても簡単ですね!(もうちょっとやり方なかったの?)
ちなみにAirDropの不具合なのか、ファイル名を日本語にするとAirDropで送信できません。
デバッグ時はファイル名をアルファベット表記にしておきましょう。
教材っぽくしたい!
Prose(散文)
通常のコメントではなく以下の形式でコメントを記述すると、編集可能な文章を教材に入れることが可能です。
そのページで何を学ぶのか等の説明文に使用すると、より教材っぽくなります。
/*: ~ :/
PBファイル上ではこのように表示されます。教材っぽくなりましたね!

入力範囲の限定
以下のような書き方をすると、Pageの中でその箇所のみが編集可能エリアになります。
想定外の部分をいじって上手く動かなくなってしまった、などの事象を防ぎ、学習してほしい箇所に集中させるのに使えそうです。
/*#-editable-code Hoge*//*#-end-editable-code*/
例えば以下のように、latitide部分にこの書き方をすると…

PBファイル上でlatitudeの値のみが編集できるようになりました。
「この部分を変更するとどうなるか、試してみましょう!」みたいな使い方ができそうですね。

他にも独自の用語集なども作成できるので、ぜひ公式ドキュメントを見てみてください。
おわりに
本記事ではSwift Playground Bookの内容や作り方、できることなどを簡単にご説明しました。
おそらく開発人口が非常に少ない領域な気がしていますが、本記事で少しでも「意外と作れるのでは?」と思ってもらえたら幸いです!
フラーアドベントカレンダー、23日目は@9rotamaさんです。お楽しみに!






