注
本記事は技育祭2022春の勉強会セッションで行われるハンズオンのための資料です。
前提条件
- Xcode がインストールされています
- GitHub(GitLab 等でも可)のアカウントを持っています
- 上記アカウントへのプッシュ可能なローカル環境が構築されています
ゴール
下準備
-
ライブラリー名を決めます
例:
Omikuji
-
ライブラリーの置き場を決めます
例:
~/Documents/Omikuji
(=/Users/MyAccount/Documents/Omikuji
)
Swift Package を作成
-
Xcode を開き、新規プロジェクトを作ります
-
Multiplatform タブから Swift Package プロジェクトを選び、次に進みます
-
先ほど決めた置き場とライブラリー名で保存し、Create Git repository on my Mac オプションにチェックを入れます
-
もし git の GUI クライアント(例:SourceTree や Fork)を利用しているなら、該当パスをクライアントに追加します(しなくてもターミナルから git 使えるので問題ありません、好みに応じて使い分けてください)
-
初期状態で作られたものを確認します
Xcode に戻ると、Omikuji/Sources/Omikuji/Omikuji.swift というファイルがあるので、それをクリックすると初期状態で下記のようなコードがすでに書かれていることが確認できます:
Omikuji.swiftpublic struct Omikuji { public private(set) var text = "Hello, World!" public init() { } }
軽い動作確認
-
複数の Xcode で同じプロジェクトを開けないため、一旦ライブラリーを開いてる Xcode を閉じます
-
ライブラリーを利用するアプリプロジェクトを作成します
Xcode で新規 Multiplatform App プロジェクトを、ライブラリーの親フォルダーに作成します
例:~/Documents/OmikujiApp
-
プロジェクト設定の Package Dependencies タブから、先ほど作ったライブラリーをローカルパスで追加します
-
iOS もしくは macOS アプリターゲット(動作確認したいターゲットで OK です;両方入れても可)設定の General タブから、先ほど作ったライブラリーを Frameworks, Libraries, and Embedded Content に追加
-
Shared の
ContentView.swift
を開いて、ライブラリーの出力を確認します先頭に
import Omikuji
を追加し、Text("Hello, world!")
の部分をText(Omikuji().text)
で置き換え、プレビュー画面がHello, World!
に変わったかどうか(小文字のw
から大文字のW
に変わったかどうか)を確認しますContentView.swiftimport SwiftUI +import Omikuji struct ContentView: View { var body: some View { - Text("Hello, world") + Text(Omikuji().text) .padding() } }
ライブラリーの機能を実装
-
動作確認アプリから直接 Omikuji パッケージの編集ができるので、そのまま Packages/Omikuji/Sources/Omikuji を開きます
-
せっかく Swift は日本語プログラミングに対応しているので、日本語で実装しようと思います。というわけで既存の
Omikuji.swift
を削除し、新たにおみくじ.swift
ファイルを作ります -
おみくじですので、
大吉
中吉
小吉
吉
末吉
凶
大凶
のenum
を作りますライブラリー外のモジュール、すなわち検証アプリやライブラリーを利用するアプリで利用するので、
public
で作る必要がありますおみくじ.swiftpublic enum おみくじ { case 大吉 case 中吉 case 小吉 case 吉 case 末吉 case 凶 case 大凶 }
-
おみくじを引きたいので、
引く()
という静的メソッドを作りますSwift には全ての case を配列で羅列してくれるためのプロトコル
CaseIterable
と、配列からランダムな要素を取り出すためのメソッドrandomElement()
があるので、これらを活用して実装しますおみくじ.swift-public enum おみくじ { +public enum おみくじ: CaseIterable { case 大吉 case 中吉 case 小吉 case 吉 case 末吉 case 凶 case 大凶 } + +extension おみくじ { + + public static func 引く() -> Self { + allCases.randomElement()! + } + +}
-
画面で引いた結果を表示したいので、
おみくじ
をString
として、CustomStringConvertible
に適合しますおみくじ.swift-public enum おみくじ: CaseIterable { +public enum おみくじ: String, CaseIterable { // ... } // ... +extension おみくじ: CustomStringConvertible { + + public var description: String { + rawValue + } + +}
-
検証アプリの
ContentView.swift
に戻り、今の実装を確認してみますText
の内容をおみくじ.引く().description
で置き換えれば OK ですContentView.swiftstruct ContentView: View { var body: some View { - Text(Omikuji().text) + Text(おみくじ.引く().description) .padding() } }
-
動作が無事確認できたら git にコミットします
ターミナルから直接使っている場合は
% git add . % git commit -m "初コミット"
のように全ての差分をステージングし、
初コミット
などのコミットメッセージでコミットすれば OK です。コミットメッセージの内容は自由です。
また SourceTree や Fork を使っている場合は、それらのツールの使い方に従って全ての差分をコミットします。
OSS として公開
-
GitHub(もしくは GitLab とかでも問題ありません)で新しい空リポジトリーを作成します
例:
https://github.com/my-account/omikuji
-
作られたリモートリポジトリーをローカルの git リポジトリーに設定します
ターミナルから git を利用している場合は
% git remote add origin https://github.com/my-account/omikuji
SourceTree などの GUI アプリの場合はアプリの使い方に従って設定します
-
リポジトリーを GitHub に Push します
ターミナルから git を利用している場合は
% git push --set-upstream origin main
SourceTree などの GUI アプリの場合はアプリの使い方に従って設定します
-
GitHub から最新の main ブランチをリリースします
リリースバージョンはセマンティックバージョニングをお勧めします。それに従うと今回は初期開発リリースとしてバージョン 0.1.0 でリリースします。この際のタグは
v0.1.0
とします
-
【オプショナル】SNS とかで自分が作ったライブラリーを宣伝します
そりゃあみんなに使ってほしいですよね!?
作られたライブラリーを実際に利用
-
上に作った動作確認用のプロジェクトを開き、確認のためのローカルライブラリーの設定を削除
プロジェクト配下の
Packages
を丸ごと削除(元のデータを消したいわけではないので、Remove Reference で削除します)
-
再びプロジェクト設定の Package Dependencies タブから、公開 URL を入れてライブラリーを導入します
-
もう一回
ContentView.swift
を開いて動作確認しますこの際プレビューで表示されているおみくじの結果がおそらく変わります。もし変わらなかったら何回か別のファイルに切り替えてまた
ContentView.swift
ファイルに戻ってみてください。その度にプレビューが再生成され、新しいおみくじ結果が表示されるはずです
以上
これであなたも自分の Swift Package ライブラリーの配布ができるようになりました!
また、今後は更に README.md を充実させてみるなどで、より人に使ってもらいやすいライブラリーに仕上げてみてもいいと思いますよ!
早くできた人へ
既にある程度の Swift 経験がある人なら今回のハンズオンはとてもスムーズに早くできちゃったかもしれません。というわけでそんなあなたに、とっておきな追加課題を出しましょう。実施は任意です。
-
今回のおみくじは完全にランダムであり、(乱数アルゴリズムのばらつきを無視すれば)どの結果でも同じ確率が出てきます。ところが実際に神社やお寺で引いたおみくじは(場所にもよりますが)いい結果が出る確率が高いです。この
引く
メソッドもそうなるように調整してみましょう。 -
いい結果が出なかった人が、次にもう一回引きたいと思う人もいます。そんな時にもし同じ結果が出てしまうとちょっとゲンナリしますよね。そんなわがままな人のために、前回とは必ず違う結果が出る
再度引く
メソッドを作ってみましょう。その時、前回と違う結果を回避するためにどんな方法があるか(例えば前回の結果を引数からもらうか、それとも引く
メソッドと同じく引数なしでどうにかするか;そして前回の結果を知った上でそれをどのように回避するかなど)も自由に考えて、それぞれのアプローチのメリットデメリットも考えてみましょう。 -
上記のブラッシュアップをリリースしてみましょう。その時、本記事にも既に出てた「セマンティックバージョニング」でバージョン番号を付ける際にはどのバージョンにすべきかも考えておきましょう。そしてリリースノートも忘れずに書いておきましょう。