Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
SwiftPMのプラグイン機能をiOSアプリ開発に活用する / Development App...
Search
USAMI Kosuke
September 10, 2022
Programming
1
4.7k
SwiftPMのプラグイン機能をiOSアプリ開発に活用する / Development App With SwiftPM Plugins
※ Docswell に移行しました
https://www.docswell.com/s/usami-k/ZRXYJN-development-app-with-swiftpm-plugins
USAMI Kosuke
September 10, 2022
Tweet
Share
More Decks by USAMI Kosuke
See All by USAMI Kosuke
Onsager代数とその周辺 / Onsager algebra tsudoi
usamik26
0
530
Apple HIG 正式名称クイズ結果発表 / HIG Quiz Result
usamik26
0
110
ゆめみ大技林製作委員会の立ち上げの話 / daigirin project
usamik26
0
280
@ViewLoadingプロパティラッパの紹介と自前で実装する方法 / @ViewLoading property wrapper implementation
usamik26
0
430
これからUICollectionViewを実践活用する人のためのガイド / Guide to UICollectionView
usamik26
1
690
Xcodeとの最近の付き合い方のはなし / Approach To Xcode
usamik26
2
610
UICollectionView Compositional Layout
usamik26
0
680
Coding Swift with Visual Studio Code and Docker
usamik26
0
440
Swift Extension for Visual Studio Code
usamik26
2
910
Other Decks in Programming
See All in Programming
イベント駆動で成長して委員会
happymana
1
320
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
110
よくできたテンプレート言語として TypeScript + JSX を利用する試み / Using TypeScript + JSX outside of Web Frontend #TSKaigiKansai
izumin5210
6
1.7k
C++でシェーダを書く
fadis
6
4.1k
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
250
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.1k
役立つログに取り組もう
irof
28
9.6k
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
910
Less waste, more joy, and a lot more green: How Quarkus makes Java better
hollycummins
0
100
見せてあげますよ、「本物のLaravel批判」ってやつを。
77web
7
7.7k
TypeScriptでライブラリとの依存を限定的にする方法
tutinoko
2
660
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.4k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
4
370
What's in a price? How to price your products and services
michaelherold
243
12k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
The MySQL Ecosystem @ GitHub 2015
samlambert
250
12k
GraphQLとの向き合い方2022年版
quramy
43
13k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
47
2.1k
The Cult of Friendly URLs
andyhume
78
6k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
31
2.7k
Making Projects Easy
brettharned
115
5.9k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Transcript
SwiftPM のプラグイン機能を iOS アプリ開発に活用する 宇佐見公輔 / 株式会社ゆめみ
自己紹介 宇佐見公輔(うさみこうすけ) 株式会社ゆめみ / iOS テックリード このトーク以外にも、パンフレット記事を2 つ書きました。
このトークの内容 SwiftPM (Swift Package Manager )とは iOS アプリ開発でSwiftPM を活用する SwiftPM
のプラグイン機能とは iOS アプリ開発でSwiftPM プラグインを活用する ※ Swift Package Manager を略してSwiftPM と呼ぶことにする。
Swift Package Manager とは
Swift Package Manager とは Swift コードをパッケージとして管理する パッケージをビルドしてライブラリや実行プログラムを生成する ライブラリ:他のSwift コードでインポートできるモジュール 実行プログラム:シェル上で実行できるCLI
ツールなど 他のパッケージを依存物として利用できる
パッケージ パッケージはSwift ソースファイルと Package.swift で構成される ` `
Package.swift import PackageDescription let package = Package( name: "MyLibrary", products:
[ .library(name: "MyLibrary", targets: ["MyLibrary"]), ], dependencies: [], targets: [ .target(name: "MyLibrary", dependencies: []), ] )
配布されているパッケージの利用 dependencies: [ .package(url: "https://example.com/AwesomePackage", from: "1.0.0"), ], import PackageDescription
let package = Package( name: "MyLibrary", products: [ .library(name: "MyLibrary", targets: ["MyLibrary"]), ], targets: [ .target(name: "MyLibrary", dependencies: []), ] )
iOS アプリ開発で SwiftPM を活用する
Xcode プロジェクト iOS アプリはXcode プロジェクトを使って開発する
余談: Swift Playgrounds App Swift Playgrounds でも開発可能、プロジェクト形式が異なる 「ゆめみ大技林 '22 」に書いた(技術書典で配布)
※ これも面白いが、このトークではこれ以上述べない。
Xcode プロジェクトと SwiftPM 配布されているパッケージを利用する CocoaPods やCarthage で配布ライブラリを利用する代わりに、 SwiftPM で配布ライブラリを利用する アプリのコード(の一部)をパッケージ化する
コードをXcode プロジェクトの管理外に置ける
Xcode で配布パッケージを利用する Xcode の「File →Add Packages… 」で依存パッケージを追加できる ※ ライブラリ管理の手法として有益だが、このトークではこれ以上述べない。
アプリのコードをパッケージ化する ローカルのSwift パッケージをアプリでインポートする ※ このトークでは、こちらの手法を扱う。
アプリのコードをパッケージ化する 一部だけでなく、ほとんどのコードをパッケージに入れても良い
Xcode プロジェクト内のソース App.swift import UIKit import AppFeature @main final class
AppDelegate: AppFeature.AppDelegate {} final class SceneDelegate: AppFeature.SceneDelegate {}
Swift パッケージ内のソース AppDelegate.swift import UIKit open class AppDelegate: UIResponder, UIApplicationDelegate
{ public final func application(_ application: UIApplication, ...) -> Bool { return true } }
パッケージ化のメリット Xcode プロジェクト(xcodeproj )でのソースコード管理が減る xcodeproj は、ファイルの追加や削除などでGit のコンフリクトを招く Swift パッケージ管理だと、Git のコンフリクトを起こしにくい
アプリ内のモジュール分割が容易になる Swift パッケージのほうが簡単に扱える
パッケージ化で未解決の問題 ビルドスクリプトはXcode プロジェクトで管理する必要がある SwiftGen でコード生成 SwiftLint でコードチェック 実はこの問題は、SwiftPM のプラグイン機能で解決できる
SwiftPM のプラグイン 機能とは
SwiftPM のプラグイン機能 2022 年3 月のSwift 5.6 で追加された機能 コマンドプラグイン ビルド以外のタスクを定義できる ビルドツールプラグイン
ビルド時に行う処理を追加できる
プラグイン機能の活用方法 配布されているプラグインを使う 配布されているものは、現時点では多くはない プラグインを自分で実装する 独自の処理を行いたい場合はこの方法になる ※ プラグインの実装方法はパンフレット記事を参照。
ビルドツールプラグイン let package = Package( targets: [ .target( name: "MyTarget",
plugins: [ .plugin(name: "MyPlugin"), ] ), .plugin( name: "MyPlugin", capability: .buildTool() ), ] )
ビルドツールプラグインの処理内容 以下の2 つのタイミングで処理が実行される ビルド前(pre-build ) ビルド中(in-build ) プラグインであらかじめ定義された処理が実行される 処理内容を自分で決めたい場合は、プラグインを自分で実装する
外部ツールを使う プラグイン外のツールを実行できる Mac 内のコマンドを実行できる 公開されているコマンドラインツールをダウンロードできる artifact bundle 形式で公開されているバイナリが使える
iOS アプリ開発で SwiftPM プラグインを 活用する
Xcode と SwiftPM プラグイン Xcode でもSwiftPM プラグインは動作する Xcode 13.3 以降で動作する
Xcode 14 でSwiftPM 対応が改善されている(ビルドログなど) ただし、一部の動作に問題がある(後述)
事例: SwiftGen プラグイン SwiftGen 公式から、プラグインとartifact bundle が提供されている ビルド前(pre-build )にソースコード生成処理が行われる 生成先は
${DERIVED_SOURCES_DIR} 以下となる swiftgen.yml で定義する なお、ビルドツールだけでなくコマンドプラグインも提供されている ` ` ` `
SwiftGen プラグインの利用 (1) 注意:この方法が正式だが、現時点では問題がある let package = Package( dependencies: [
.package(url: "https://github.com/SwiftGen/SwiftGenPlugin", from: "6.6.2") ], targets: [ .target( name: "MyTarget", plugins: [ .plugin(name: "SwiftGenPlugin", package: "SwiftGenPlugin") ] ), ] )
Xcode で発生する問題 外部プラグイン利用時、Xcode が重くなる Xcode のCPU 使用率が100% 以上になる Xcode のエディタの動きがもたつく
外部プラグインの中でartifact bundle を使っていると発生する 外部ツールをダウンロードする機能 SwiftGen プラグインは swiftgen コマンドをartifact bundle で使用 ` `
Xcode で発生する問題の回避方法 Xcode の問題を回避するには、プラグインを自分で実装する artifact bundle の利用自体は問題ない 外部プラグインの中でartifact bundle が使われているとダメ
ローカルプラグインの中でartifact bundle を使うのは大丈夫
SwiftGen プラグインの利用 (2) let package = Package( targets: [ .plugin(
name: "SwiftGenPlugin", capability: .buildTool(), dependencies: ["swiftgen"]), .binaryTarget( name: "swiftgen", url: "https://github.com/SwiftGen/SwiftGen/releases/...", checksum: "..." ), ] )
事例: SwiftLint プラグイン SwiftLint 公式から、artifact bundle が提供されている これを利用して、自分でプラグインを実装すればよい
SwiftLint プラグインの実装 struct SwiftLintPlugins: BuildToolPlugin { func createBuildCommands(context: PluginContext, target:
Target) async throws -> [Command] { return [buildCommand( displayName: "Linting \(target.name)", executable: try context.tool(named: "swiftlint").path, arguments: [ "lint", "--in-process-sourcekit", target.directory.string ], environment: [:])] } }
SwiftLint プラグインの利用 let package = Package( targets: [ .plugin( name:
"SwiftLintXcode", capability: .buildTool(), dependencies: ["SwiftLintBinary"] ), .binaryTarget( name: "SwiftLintBinary", url: "https://github.com/realm/SwiftLint/releases/...", checksum: "..." ), ] )
まとめ Swift Package Manager (SwiftPM )とは iOS アプリ開発でSwiftPM を活用する SwiftPM
のプラグイン機能とは iOS アプリ開発でSwiftPM プラグインを活用する サンプル: https://github.com/usami-k/XcodeSwiftPMSample