.png?tr=w-1000,h-1000,c-at_max?tr=w-1000,height-1000,c-at_max)
プレイドインターン体験記:初めてフルスタックでの開発
Posted on
自己紹介
こんにちは!8月1日からプレイドでインターンをしている櫻井絵理香です。
普段は京都の大学に通っています。
これまでiOS開発をメイン(正直、iOS開発しかほとんどしたことがありませんでした...)でやってきましたが、今回のプレイドでのインターンでは初めてフルスタックで開発をしました。私は今回のプレイドのインターンでは、「モバイルアプリのNative UI構築に関する課題を解決する」新規事業・プロダクト開発のチームに配属されました。
Webのフロントエンド、バックエンド、インフラアーキテクチャ、そしてiOS SDKまで、超フルスタックな体験をさせていただき、自分にとって大きな挑戦となりました。普段慣れ親しんだiOS開発の領域を飛び出して、新しい技術スタックに触れることで多くの学びを得ることができました。
この記事では、そんな貴重な体験について詳しくお話ししたいと思います。
インターンでの内容
デモアプリの実装
SDKの機能や使用感を実際に体験してプロダクトの理解を深めるために、Figmaのデザインに沿ったデモアプリの実装を行いました。インターン開始時に「やりたいことはあるか?」と聞かれた際、CI構築とテスト実装への挑戦を希望していたため、デモアプリでこれらの技術要素を組み込むことになりました。アプリ開発では実際にSDKをコードベースに統合し、その動作を確認しました。SDKの内部実装を詳細に調査するのは初めての経験でした。
画像はデモアプリのもの
CIとテスト実装の実践的学習
GitHub Actionsによる継続的インテグレーション
初めてGitHub Actionsを使用し、プルリクエスト時の自動テスト実行環境を構築しました。ワークフローファイルの設定からテスト結果の可視化まで、継続的インテグレーションの仕組みを実践的に学習できました。
段階的なテスト戦略の確立
プロジェクトIDの変更をテキストで手動入力することの煩わしさを解決するため、管理画面側でプロジェクトIDをQRコード化し、SDK側で読み取って即座にプロジェクトIDを反映する機能を実装しました。この新機能の品質を保証するため、QRコード読み込み機能を中心としたユニットテストを実装し、Swift Testingフレームワークを使用してViewModelの状態管理をテストしました。
具体的には、QRコード検出時の状態変化、スキャン開始/停止の制御、カメラ権限拒否時のエラーハンドリングなど、ユーザーの実際の使用パターンを想定したテストケースを作成しました。
テスト実装を通じて「何を保証すべきか」という設計思想の重要性を学びました。単純な動作確認だけでなく、スキャン中でない場合のQRコード無視処理や、複数回の検出処理など、境界条件や異常系も含めた包括的な品質保証の考え方を身につけることができました。
一方でUIテストでは従来手法の限界を実感しました。要素特定の困難さ、UI変更への脆弱性、環境依存による不安定性、そして工数の大きさが課題となりました。この解決策としてMagicPodを導入し、ノーコードでの効率的なUIテスト自動化を実現しました。
グラデーションカラーの実装
デモアプリ実装を通じて実際のプロダクトの機能や使用感を掴むことができたため、次のステップとして実際のプロダクトへ新機能を追加しました。プロダクトの管理画面でグラデーションカラーを指定し、それがSDKに反映される機能を実装しました。この実装を通じて、フルスタック開発における問題解決力やスキーマ設計の重要性について多くの学びを得ることができました。特に印象的だったのは、スキーマを定義してmake generateコマンドでコードと型が自動生成される体験と、GraphQLを初めて触ることでプロダクトの根幹部分に関わることの責任感でした。
実装の全体像
アーキテクチャは以下のような流れになっています
- 管理画面でグラデーションカラーを指定
- データベースとGCSに保存
- iOS SDK側でGCSからJSONを読み取り
- JSONをパースしてレンダリング
以下に動作の流れのイメージ図を記載します。
フルスタック開発における問題解決力
長い連携チェーンでのデバッグの難しさ
管理画面(フロント)→ バックエンド → GCS → SDK → アプリという長い連携チェーンで開発を進める中で、最も困ったのは「どこで問題が起きているか分からない」状況でした。
- フロントからバックエンドにJSONが正しく読み込めているか
- GCSに正しく送信できているか
- SDK側でJSONが正しくパースできているか
これらを一つずつ確認していく作業は想像以上に大変でした。
問題を小さく分割する習慣
この経験を通じて、問題を小さく絞って解決していく方法が身につきました。各段階でのデータ整合性を確認し、どの部分で失敗しているかを特定する習慣は、今後のフルスタック開発でも必須のスキルだと感じています。
GraphQLスキーマ設計の責任と互換性管理
プロダクトの核となるデータ構造への責任
GraphQLを触ること自体が初めてで、特にJSONがプロダクトの大事な部分であることを理解した時、その定義から関わることの重大さを実感しました。スキーマの変更がプロダクト全体に与える影響の大きさは、新規プロダクトならではの貴重な体験でした。
互換性を考慮した設計の重要性
最も頭を悩ませたのは互換性の問題でした
- 後方互換性: 古いJSONで新しいSDKが正常に動作するか
- 前方互換性: 古いSDKで新しいJSONが処理できるか
これらの両方を考慮しながらスキーマを設計することで、将来的な変更に柔軟に対応できる基盤を作ることの重要性を学びました。
インターンシップで学んだコーディングの基本
インターン期間中に最も重要だと実感したのは、レイヤー構造を意識したコード設計です。各層の役割を明確に分離し、適切な抽象化レベルを維持することの重要性を学びました。
単一のモジュールで複数の概念を同時に定義してしまうと、コードの保守性が著しく低下することを実際の開発で経験しました。プレゼンテーション層、ビジネスロジック層、データアクセス層といった責務の分離により、システム全体の理解しやすさと拡張性が大幅に向上することを実感できました。
Claude Codeでの限界
Claude Codeは非常に有効なツールですが、その限界についても理解を深めました。新規のiOSアプリ開発のような、ゼロから構築する慣れ親しんだ技術領域では優秀な開発パートナーとして機能しました。
しかし、既存のWebアプリケーションなど、触ったことのない技術スタックでは期待通りの結果を得ることが困難でした。コードが動作するだけでは不十分で、なぜそのような実装を選択したのかという設計思想の理解が不可欠であることを学びました。ツールに依存するのではなく、各コードの抽象化レベルを正確に把握し、システム全体の中での位置づけを理解することの重要性を実感しました。あと、めっちゃ重複でコード書いてくる。差分だけ見ててもダメ、既存のアプリだとすでに実装済みのものがあるかもしれないので、そこを注意しなければならないと感じました。
まとめ
今回のグラデーションカラー機能の実装は、単なる機能追加を超えて、フルスタック開発における多くの重要な概念を学ぶ機会となりました。特に以下の点は今後の開発でも大切にしていきたいと思います
- 問題を小さく分割し、段階的にデバッグする習慣
- スキーマ設計における互換性への配慮
- 自動生成ツールを活用した開発効率の向上
- プロダクト全体のアーキテクチャを意識した設計
フルスタック開発は確かに複雑で困難な面もありますが、プロダクト全体を俯瞰し、エンドユーザーまでの一連の流れを自分の手で作り上げることができる魅力的な野だと改めて感じました。今回の経験を活かして、より良いプロダクト開発に貢献していきたいと思います。
プレイドで働いてみての感想
これまでの私の開発経験は主にiOSアプリ開発に限定されており、SwiftとFirebaseを中心とした比較的狭い技術スタックでの開発が中心でした。しかし、今回のインターンでは初めてフルスタック開発に挑戦し、フロントエンドからバックエンドまでの一連の開発フローを体験することができました。この経験は、技術者としての視野を大きく広げる貴重な機会となりました。
他のインターン先で既存アプリケーションの保守・運用は経験したことはあるのですが、今回は新規プロダクトの機能開発に携わることができました。ゼロから機能を設計・実装していく過程は新鮮で、プロダクトが成長していく様子を間近で見ることができたのは非常に貴重な体験でした。スタートアップフェーズのプロダクト開発に関わることで、技術的な判断だけでなく、ビジネス観点も含めた総合的な開発プロセスを学ぶことができました。
プレイドでは、オンライン・オフライン問わず、チームメンバーとのコミュニケーションが非常に取りやすく、疑問点があれば気軽に相談できる雰囲気がありました。そのため、インターン期間を通じて楽しみながら多くのことを学ぶことができ、充実した時間を過ごすことができました!