SwiftUIを使ってOSSライブラリを作成してみた
OSSライブラリを作成したり、コントリビュートしたりするのはハードルが高いイメージありませんか。
この記事ではOSSライブラリの土台を作るところから始めて、そんなイメージを変えていきたいと思います。
はじめに
こんにちは。クラウドソリューショングループのtakinami.sです。
開発をしているとオープンソースのフレームワークやライブラリを導入することがあると思います。
今回はかねてより興味があったライブラリの作成にチャレンジしてみました。
また、自分がよく使う機能を自分自身でライブラリ化しておけば、いつの間にか開発が終了していて別のライブラリに乗り換えるというメンテナンスの手間も考慮せずに済むのではないかと考えたためでもあります。
ライブラリを管理しているのは自分なので、開発を続けるのも終了するのも自分の判断ですからね。
この記事はアイソルート Advent Calendar 2023の4日目の記事です。
プロジェクトを作ろう
今回は主にiOSアプリを対象とし、将来的にはプログレスバーのような使い方ができることを目指したライブラリの下地を作っていきます。
環境
今回使用した環境は以下の通りです。
- Swift:v5.8.1
- Xcode:v14.3.1
プロジェクトの作成
まずはXcodeを立ち上げ、『Create a new Xcode project』から新しいプロジェクトを作っていきます。
テンプレート選択に遷移したら、『Multiplatform』の中から『Swift Package』を選びます。
プロジェクト名を入力したら準備完了です。
この記事ではプロジェクト名を『HasuoProgressSpinner』としています。
余談ですが、『ハスお』は私が使うハンドルネームの1つです。
実装しよう
フォルダ構成
プロジェクトを作成すると以下のようなフォルダ構成になっています。
今回は画面に表示する部分を作っていくので、Sources > プロジェクト名フォルダの中で作業を行います。
また、プロジェクト作成時にはテスト用の設定もデフォルトで入っていますが、今回は一旦省きました。
別の機会で触れられればと思います。
(ViewフォルダやSucceedViewフォルダは今回の対応にあたって追加したものです。後ほど触れます。)
サポート対象のOSバージョンの設定
プロジェクト直下にあるPackage.swiftでライブラリがサポートするOSバージョンを指定します。
今回はSwiftUIが対応していることやOSバージョンのシェアを踏まえて、iOS14以上を対象としました。
また、iOS以外にもmacOSやtvOSも対象としてみました。
(と言いつつ、macOSではUIImageが使えなかったりするので、実装時にはそういったところも考慮に入れる必要があります)
import PackageDescription
let package = Package(
name: "HasuoProgressSpinner",
platforms: [
.iOS(.v14),
.macOS(.v11),
.tvOS(.v14),
.watchOS(.v7)
],
products: [
.library(
name: "HasuoProgressSpinner",
targets: ["HasuoProgressSpinner"]),
],
dependencies: [
],
targets: [
.target(
name: "HasuoProgressSpinner",
dependencies: [])
]
)
Viewを作る
先ほど軽く触れたように、Sources > プロジェクト名フォルダ > Viewフォルダの中で作業を行います。
今回メインとなるのはViewフォルダ直下にあるプロジェクト名のswiftファイルです。
では、今回実装したものを見ていきましょう。
import SwiftUI
public struct HsProgress: View {
var showType: String?
var text: String?
public init(showType: String?, text: String?) {
self.showType = showType
self.text = text
}
public var body: some View {
VStack {
Spacer()
HStack {
Spacer()
switch showType {
case "succeed":
SucceedView(text: text ?? "")
default:
EmptyView()
}
Spacer()
}
Spacer()
}
.background(Color(red: 0.5, green: 0.5, blue: 0.5, opacity: 0.5))
.frame(minWidth: 150, maxWidth: 200, minHeight: 150, maxHeight: 200)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
このうちinit()がライブラリが呼び出されると最初に実行される箇所になります。
ここで呼び出す時に充てて欲しい引数の設定を行っています。
今回の場合だとshowTypeやtextを指定できるようにしています。
var bodyの部分で実際に表示されるViewを作り込んでいきます。
showTypeでどういったViewを表示させたいかを指定し、textでViewの中の文言を設定するイメージです。
先ほどフォルダ構成部分のところで触れたSucceedViewフォルダに新しくswiftファイルを作成し、そちらで読み込みが成功した場合(showTypeがsucceedの場合)に表示させるSucceedViewを実装しました。
SucceedViewは以下のような実装になっています。
import SwiftUI
struct SucceedView: View {
let text: String?
var body: some View {
VStack {
Image(uiImage: .strokedCheckmark)
.resizable()
.scaledToFit()
.frame(width: 50, height: 50)
.clipped()
Text(text ?? "")
.multilineTextAlignment(.center)
}
}
}
実際にライブラリを呼び出す時にはHsProgress(showType: “succeed”, text: “成功しました”)のように記述します。
実装での注意事項として、外部からの呼び出しに対応できるようstructやinit()にはアクセス修飾子publicをつけてあげる必要があります。
外部からの呼び出しに対応したアクセス修飾子にはopenもありますが、基本的にはpublicで要件は満たせるかと思います。
公開しよう
ライセンス表記
ライブラリを使用するにあたってのライセンスを明記しておきましょう。
GitHubの「Create new file」からファイルを追加します。
ファイル名を「Licence」するとテンプレートを準備してくれるのでスムーズです。
今回はMITライセンスにしました。
リリースタグの設定
こちらもGitHub上で設定しておきましょう。
まだお試し段階なのでバージョンは1にも満たない0.0.1としました。
タグはx.x.xの形式にしないとSwift Packege Managerに対応できないようなので、注意です。
最後に
公開までの過程はそんなに複雑ではなかったように感じます。
ライブラリの管理というとCocosPodsやCarthageが有名ですが、Swift Package Managerを使う動きがだいぶ盛んになってきているので、今回はSwift Package Managerに対応させました。
むしろSwift Package Managerに対応しているかどうかがメンテナンスがきちんと行われているかの指標にもなり得ると考えています。
今回作ったライブラリはちゃんと運用していけるようメンテナンスしていきます。
皆さんもよく使う処理や表示をライブラリにして発信すると、世界の誰かの役に立つかもしれませんよ。