Slide 1

Slide 1 text

メタバースプラットフォームを支えるiOS 開発と運用 クラスター株式会社 / プラットフォーム事業本部 / ソフトウェアエンジニア Ahi To / TAAT

Slide 2

Slide 2 text

Cluster, Inc. 3 概要 ● clusterと ? ● cluster App 構成 ● 3D空間やサーバーと インターフェイス ● リポジトリ運用 ● CI / CD

Slide 3

Slide 3 text

Cluster, Inc. 4 自己紹介 Ahi To / TAAT クラスター株式会社 / ソフトウェアエンジニア メタバース 魅力と可能性に惹かれ、 2023年1月からクラスターにジョイン! taatn0te @TAAT626

Slide 4

Slide 4 text

Cluster, Inc. 5 clusterと ? VRからスマホまで遊べるメタバースプラットフォーム

Slide 5

Slide 5 text

Cluster, Inc. 6 clusterと ? マルチプラットフォーム対応 iOS Android macOS Windows Desktop / VR Meta Quest 2 没入感 高いVR もちろん、PCやスマホにも対応していて、手軽にメタ バースを楽しめる!マルチプラットフォーム ユーザーが同じ空間を共有で きる!

Slide 6

Slide 6 text

Cluster, Inc. 7 アバターワーク チーム バーチャル仕事部屋 cluster内でMTGや雑 談をしたり、そ 場で ワールドを 改 築 したり、リモートワークでもコ ミュニケーションが取りやすい! アバターでWeb会議 Web会議もアバターで参加できる!アバター ワーク感があって良い! クラスターに入社して1ヶ月経ってみて

Slide 7

Slide 7 text

8 cluster App 構成

Slide 8

Slide 8 text

Cluster, Inc. 9 cluster App 構成 outroom inroom バーチャル空間内 体験 バーチャル空間外 非同期な体験

Slide 9

Slide 9 text

Cluster, Inc. 10 cluster App 構成 outroom inroom cluster Unity-iPhone UnityFramework SwiftPackage xcframework Unity as a Library Unityで 構 築 したアプリケーションをネイティブアプリ ライブラリとして扱える Unity as a LibraryをSwiftPM経由で導入してiOSビルド環境を改善した話

Slide 10

Slide 10 text

Cluster, Inc. 11 cluster App 構成 iOSエンジニア 、バーチャル空間外 非同期的 な体験 機能開発を担当 outroom clusterで iOS 15.0以上をサポートしており、新規画 面で 積極的にSwiftUIを使用しているが、まだまだ UIKit 部分が多く、SwiftUIだけで できない部分もあ る で、SwiftUIとUIKitを併用している

Slide 11

Slide 11 text

12 3D空間やサーバーと インターフェイス

Slide 12

Slide 12 text

Cluster, Inc. 13 inroomやサーバーと インターフェイス outroom inroom Protocol Buffers Swagger server

Slide 13

Slide 13 text

Cluster, Inc. 14 Protocol Buffersと ? Protocol Buffers are language-neutral, platform-neutral extensible mechanisms for serializing structured data. Protocol Buffers 、Goolgeが開発した言語やプラットフォームに依存しない 構 化されたデータをシリアライズするため フォーマット https://protobuf.dev/ 異なるリポジトリ/システム/ランタイム間 インタフェースや保存形式として使いや すく、バイナリベースで高 にデータ転送できる で、クラスターで 、 inroom/outroom間だけでなく、inroom/サーバー間、サーバーどうし間などで も利用している。

Slide 14

Slide 14 text

Cluster, Inc. 15 Protocol Buffersと ? syntax = "proto3"; message User { int64 id = 1; string name = 2; string photoUrl = 3; bool isCertified = 4; } struct User { var id: Int64 = 0 var name: String = String() var photoURL: String = String() var isCertified: Bool = false var unknownFields = SwiftProtobuf.UnknownStorage() init() {} } .protoファイル 自動生成された.pb.swiftファイル swift-protobufでコンパイル $ brew install swift-protobuf $ protoc --swift_out=. BookInfo.proto SwiftProtobuf パッケージを追加 プロジェクトに追加すれ 使える swift-protobuf

Slide 15

Slide 15 text

Cluster, Inc. 16 Protocol Buffers clusterで 使用例 syntax = "proto3"; // outroom -> inroom に送られるメッセージ message InMessage { oneof msg { // 初期化してroomに入室する通知 ImsgInitializeEntry initialize_entry = 1; ... } } // inroom -> outroom に送られるメッセージ message OutMessage { oneof msg { // roomから退出した通知 OmsgNotifyExit notify_exit = 1; ... } } /// outroom -> inroom に送られるメッセージ struct InMessage { var initializeEntry: ImsgInitializeEntry { get { if case .initializeEntry(let v)? = msg {return v} return ImsgInitializeEntry() } set {msg = .initializeEntry(newValue)} } ... } /// inroom -> outroom に送られるメッセージ struct OutMessage { var notifyExit: OmsgNotifyExit { get { if case .notifyExit(let v)? = msg {return v} return OmsgNotifyExit() } set {msg = .notifyExit(newValue)} } ... } message.proto message.pb.swift

Slide 16

Slide 16 text

Cluster, Inc. 17 Protocol Buffers clusterで 使用例 inroom outroom Bridge InMessage OutMessage polling polling

Slide 17

Slide 17 text

Cluster, Inc. 18 Swaggerと ? Swaggerと 、REST API 仕様を記述するため フォーマットであるOpen APIを 使用してAPIを設計・ビルド・ドキュメントテーションするため ツールである。 ● Swagger Editor:ブラウザでAPI仕様書(.yaml)を書くため エディター ● Swagger UI:API仕様書からドキュメントを生成するツール ● Swagger Codegen:API仕様書からコードを生成するツール(OpenAPI Generatorもある) https://swagger.io/docs/specification/about/ API定義を書くだけで、APIドキュメントを自動生成、各プラットフォーム向け クライア ントコード(APIクラスやデータモデル)を自動生成してくれる で、サーバーサイド・ク ライアントサイド 対応コストを大幅に低減できる!

Slide 18

Slide 18 text

Cluster, Inc. 19 Swagger Editor Swagger Editor

Slide 19

Slide 19 text

Cluster, Inc. 20 Swaggerからコードを自動生成 クラスターで 、OpenAPI Generatorというツールを使って、swagger.yamlからク ライアント用 APIクラス コードを自動生成している。 open class DefaultAPI { /** Returns a user by ID. - parameter userId: (path) User ID - parameter apiResponseQueue: The queue on which api response is dispatched. - parameter completion: completion handler to receive the data and the error objects */ @discardableResult open class func usersUserIdGet(userId: Int64, apiResponseQueue: DispatchQueue = OpenAPIClientAPI.apiResponseQueue, completion: @escaping ((_ data: Void?, _ error: Error?) -> Void)) -> RequestTask { return usersUserIdGetWithRequestBuilder(userId: userId).execute(apiResponseQueue) { result in switch result { case .success: completion((), nil) case let .failure(error): completion(nil, error) } } } } openapi: 3.0.0 info: title: Sample API version: 1.0.0 servers: - url: http://api.example.com/v1 paths: /users/{userId}: get: summary: Returns a user by ID. parameters: - name: userId in: path required: true description: User ID schema: type : integer format: int64 minimum: 1 responses: '200': description: OK

Slide 20

Slide 20 text

Cluster, Inc. 21 Swaggerからコードを自動生成 WWDC2023でSwift OpenAPI Generatorが登場し、コマンドでコード生成する必 要 なく、ほぼXcodeで完結する で、移行を検討中。 Meet Swift OpenAPI Generator

Slide 21

Slide 21 text

22 リポジトリ運用

Slide 22

Slide 22 text

Cluster, Inc. 23 Monorepo クラスターで 、一部を除いて基本的にMonorepo(単一リポジトリ)で運用している。 よく対比されるPolyrepo(プロジェクトごとに別リポジトリ)と それぞれ メリット・デメ リットがあるが、以下 理由でMonorepoを採用。 ● 単一リポジトリな で、構成や依存関係(Feature Flagを含む)がシンプルで、マ ルチプラットフォーム向け リリースを行いやすい ● チーム編成が変わっても、リポジトリを統合・分割する必要がない ● 同じリポジトリ内で技術(言語やバージョン、CI設定、ブランチ運用など)を統一しや すい

Slide 23

Slide 23 text

Cluster, Inc. 24 Feature Flagによるトランクベース開発 トランクベース開発と 、開発者が細かく頻繁なアップデートをコア「トランク」また main ブランチにマージするバージョン管理手法です。 ● 常にmainブランチからブランチを作成、小さい粒度で開発・マージする ● 競合解消 コストが低く、プルリクエストが巨大にならない で、影響範囲 把握 やレビューがしやすい ● mainブランチに変更が集約される、常に最新 状態でデリバリーできる Atlassian 継続的インテグレーション

Slide 24

Slide 24 text

Cluster, Inc. 25 Feature Flagによるトランクベース開発 ただし、mainブランチに開発中 変更をマージすると、リリースコードにも影響が出てし まう。そこで、Feature Flagと呼 れる「必要に応じて機能をON/OFFできる」手法を 使う。 ON OFF OFF 開発中 機能でもFeature Flag OFFでマージOK リリース前にFeature FlagをONにして QAを実施してリリース

Slide 25

Slide 25 text

Cluster, Inc. 26 Feature Flag 定義 enum FeatureFlag: String, CaseIterable { case feature1 case feature2 case feature3 } extension FeatureFlag { private var defaultValue: Bool { switch self { case .feature1: return true case .feature2: return false case .feature3: return false } var enabled: Bool { // development buildの場合、UserDefaultから保存したフラグを参照 if Constants.isDevelopmentBuild { return UserDefaultsWrapper.featureFlag(self) ?? true } return defaultValue } func setEnabled(value: Bool) { if Constants.isDevelopmentBuild { UserDefaultsWrapper.setFeatureFlag(self, value: value) } } } if FeatureFlag.feature1.enabled { // 機能がON:開発・検証用 } else { // 機能がOFF:プロダクション用 } clusterで デバッグ用 設定画面があり、そ こでフラグをON/OFFできる。 機能 リリース時にフラグをONに変更して、リ リースビルドを行う。リリース後に安定したら定 義したフラグを削除して、feature.enabled 分岐 みを残す。

Slide 26

Slide 26 text

27 CI / CD

Slide 27

Slide 27 text

Cluster, Inc. 28 GitHub Actionsを活用 クラスターで 、GitHubでプルリクエストを作成した時に、GitHub ActionsでLint やユニットテスト ワークフローを実行している。 ios_swiftlint ● SwiftLintでコードを解析して、スタイルや規則をチェックして警告やエラーを出す。 ● プルリクエスト作成時に実行され、これが通らないとマージできない。

Slide 28

Slide 28 text

Cluster, Inc. 29 GitHub Actionを活用 ios_unit_test ● ユニットテストを実行して、swifty-code-coverageというActionを使って、ViewControllerや ViewなどViewレイアーを除外したコードカバレッジを出力する。 ● cronで定期的に実行され、テストがエラー 場合にSlackに通知する。 - uses: michaelhenry/[email protected] with: build-path: Alefgard/ios/DerivedData target: cluster.app is-spm: false ignore-filename-regex: '.build|Tests|Pods|Carthage|DerivedData|SourcePackages|api|(ViewController|View|Header| Footer|Row|Cell|Label|\.pb)\.swift$' if: success() || failure()

Slide 29

Slide 29 text

Cluster, Inc. 30 定期的なテストアプリ配信 Jenkinsジョブで、ブランチ監視・定期的なトリガーで全プラットフォーム向け テスト アプリをビルドして配信している。 ※GitHub Actionsに移行中 手動実行 ブランチ監視 定期実行 クライアントビルド 全体 エントリー ポイント メタデータチェック (Unity) ユニットテスト (Unity) Android build Quest2 build iOS build Mac build Windows build iOS Android Quest2 macOS Windows 各プラットフォーム向 けにビルドを配信

Slide 30

Slide 30 text

Cluster, Inc. 31 iOS Android Quest2 macOS Windows 各プラットフォーム向けにビルドを配信 リリースフロー 毎週マルチプラットフォーム(iOS / Android / Meta Quest2 / macOS / Windows)向けにリリースを実施! branch cut RC build QA 審査提出 リリース Mon Tue Wed Thu Fri or Mon PC,モバイル,VRに対応したマルチプラットフォームアプリ リリースフロー

Slide 31

Slide 31 text

32 まとめ

Slide 32

Slide 32 text

Cluster, Inc. 33 まとめ ● cluster App バーチャル空間内外を担うinroomとoutroomで構成され、 Unity as a Libraryとしてプロジェクトに導入 ● 3D空間やサーバーと 間で、それぞれProtocol BuffersとSwaggerを使 用。共通インターフェイスを定義し、コード 自動生成でデータ やり取りコストを 低減 ● Monorepo + Feature Flagでトランクベース開発を採用し、小さくアップデート することで、競合解消やレビューコストを低減 ● GitHub ActionsやJenkinsを活用して、Lintやユニットテストを実行、マルチ プラットフォーム向け 配信を自動で実施

Slide 33

Slide 33 text

34 One more thing…

Slide 34

Slide 34 text

Cluster, Inc. 35 Apple Vision Pro対応 ついにWWDC 2023でApple Vision Proが発表されました!空間コンピューティ ングを切り拓いていくVision Proに、clusterも対応予定! JUSTIN SULLIVAN/GETTY IMAGES

Slide 35

Slide 35 text

Cluster, Inc. 36 https://recruit.cluster.mu/wp-content/themes/Original/assets/images/top-text.svg We are hiring! iOSエンジニア じめ各職種で採用強化中! そ 才能を Clusterで解き放て。

Slide 36

Slide 36 text

No content