$30 off During Our Annual Pro Sale. View Details »

iOSDC2023_Cluster

 iOSDC2023_Cluster

Cluster, Inc.

August 31, 2023
Tweet

More Decks by Cluster, Inc.

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  7. 8
    cluster App 構成

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  13. 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/サーバー間、サーバーどうし間などで
    も利用している。

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

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

    View Slide

  17. 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クラスやデータモデル)を自動生成してくれる で、サーバーサイド・ク
    ライアントサイド 対応コストを大幅に低減できる!

    View Slide

  18. Cluster, Inc. 19
    Swagger Editor
    Swagger Editor

    View Slide

  19. 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

    View Slide

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

    View Slide

  21. 22
    リポジトリ運用

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. 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
    分岐 みを残す。

    View Slide

  26. 27
    CI / CD

    View Slide

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

    View Slide

  28. 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()

    View Slide

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

    View Slide

  30. 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に対応したマルチプラットフォームアプリ リリースフロー

    View Slide

  31. 32
    まとめ

    View Slide

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

    View Slide

  33. 34
    One more thing…

    View Slide

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

    View Slide

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

    View Slide

  36. View Slide