iOSDC2020のセッションでAltSwiftUIというライブラリが紹介されました。
SwiftUIは導入するのにビルドターゲットをiOS13以降にする必要がありますが、このライブラリを使えばiOS11からSwiftUIライクにViewを組むことができます。
紹介されたときはこのライブラリが今後どう普及していくのか楽しみだったのですが、iOSDCが終わり数ヶ月経った現在もあまり導入例の記事やリポジトリがなかったため、少し触ってみることにしました。
この記事ではSwiftUIとの全ての違いを網羅することはできませんので、さらに気になられた方はAltSwiftUIのリポジトリをクローンしExampleのプロジェクトを動かしてみることをお勧めします。この記事を読むよりそっちの方がよっぽど勉強になる
導入方法
CocoaPodsで導入することができます。
pod 'AltSwiftUI'
検証環境
iOS 12.0
Xcode12.2
AltSwiftUI 1.3.2
実際にViewを組んでみる
ボタンをタップするとテキストが表示されるだけの単純なviewを組んでみて、SwiftUIと実装にどのように差があるかみていきます。
まずこちらがSwiftUIのコードです。あまりSwiftUI自体もキャッチアップできていないため、お作法がなっていないところもあるかもしれませんがご容赦ください🙏
// SwiftUI
import SwiftUI
struct ContentView: View {
@State private var isPushed = false
var body: some View {
VStack(alignment: .center) {
Image("Image")
.resizable()
.scaledToFit()
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)
if isPushed {
Text("Merry Christmas🎉")
.font(.system(size: 20, weight: .bold))
.padding(.bottom, 20)
}
Button(action: {
isPushed.toggle()
}, label: {
Text("Button")
})
.accentColor(.orange)
.frame(width: UIScreen.main.bounds.width - 24, height: 44)
.font(.system(size: 14, weight: .bold))
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.orange, lineWidth: 2))
}
.offset(x: 0, y: -150)
}
}
そしてこちらがAltSwiftUIのソースです。
ほぼ同じように実装できているように見えますが多少差があります。
// AltSwiftUI
import AltSwiftUI
struct ContentView: View {
var viewStore = ViewValues()
@AltSwiftUI.State private var isPushed = false
var body: View {
VStack(alignment: .center) {
Image("Image")
.resizable()
.scaledToFit()
.frame(width: UIScreen.main.bounds.width , height: UIScreen.main.bounds.width)
if isPushed {
Text("Merry Christmas🎉")
.font(.system(size: 20, weight: .bold))
.padding(.bottom, 20)
}
Button(action: {
isPushed.toggle()
}, label: {
Text("Button")
})
.accentColor(.orange)
.border(.orange, width: 2)
.font(.system(size: 14, weight: .bold))
.frame(width: UIScreen.main.bounds.width - 24, height: 44)
.cornerRadius(10)
}
.offset(x: 0, y: -150)
}
}
ではここからはいくつかの違いについて触れていきます。
viewStore
AltSwiftUIはviewStore
の実装を求められます。
求められるものは書いておきましょう!笑
someの有無
SwiftUIではViewの前にsome
をつけたものをbody
に準拠させていますが、AltSwiftUIではつける必要がありません。つける必要がないというのは正確ではなく、つけることができないという方が正しいです。
some
はSwift5.1から使えるようになったものなので、iOS11をサポートしようとすると使えません。このsome
については詳しくはこちらの記事に書かれています(あまり理解していないのでどなたか教えてください・・・)
Property Wrapper
AltSwiftUIではSwiftUIのProperty Wrapperも使用できます。使う際は@AltSwiftUI.State
のように指定する必要があります。最新のリリースをみるとこの指定がなくても直接@State
で使えるようだったのですが、なぜかエラーで使えませんでした。わかり次第、追記します。
RoundedRectangleが使えなかった
ボタンの角丸を表現するのにSwiftUIではRoundedRectangle
を使用したのですが、AltSwiftUIでは使えませんでした。しかしborder
とcornerRadius
を使えば表現できるので、さほど問題でもないかなと思います。
他をあまり調べていませんが、こういった差はちょこちょこありそうなので使う時に注意が必要かもしれません。
Preview機能は?
SwiftUIというとPreview機能が目玉のひとつでしょう。コードの変更がリアルタイムでViewに反映されるため、ずいぶんと実装が楽になりました。
AltSwiftUIでPreviewを実現するためには、SwiftUIとAltSwiftUIそれぞれのPreviewProvider
を準拠させる手法が公式から紹介されています。実際この方法でPreviewすることができました。
#if DEBUG && canImport(SwiftUI)
import SwiftUI
import protocol SwiftUI.PreviewProvider
import protocol AltSwiftUI.View
struct MyPreview: AltPreviewProvider, PreviewProvider {
static var previewView: View {
ContentView()
}
}
#endif
まとめ
さわってみた感想としては
- SwiftUIとほぼ同様なシンタックスで宣言的にコードがかけるのが良い
- SwiftUIに移行する時ラクかも?
- 予期せぬバグなどは心配なので最小のコンポーネントから試すのがよさそう
と思いました。一方これからSwiftUIが普及していく中で、わざわざAltSwiftUIを使う機会は限定的かな?とも感じました。しかし携わるプロジェクトによってはiOS12以前をサポートしなければならない場面も存在すると思います。そういった方がSwiftUIを実務で取り入れつつ学ぶにはよいかもしれません。