Embedded frameworkの理解と作成方法

Embedded frameworkの理解と作成方法

Table of Contents

開発中のビルド時間の短縮やレイヤードアーキテクチャをより疎結合にする設計や、Extensionや他Platformなどでコード共有したい場合は、Embedded frameworkで解決できます。

Embedded Frameworkとは?

事前に組み込まれたフレームワークです。static libraryみたいな扱いです。

例を使って説明

例えばiOSアプリターゲットにA,B,Cというソースコードが含まれてたとします。
このうちCファイルを別のframeworkターゲットとして抜き出して、
それを元のiOSアプリターゲットのフレームワークとして組み込む方法です。

Embedded Frameworkのメリット

一見助長に感じる制御フローですが、次のケースでその恩恵を得られます。

ケース1: 他プラットフォームのコード共有

最近のアプリケーションではiPhone(iOS)に留まらず、watchOSやtvOSなど複数端末で一つのサービスを横断して使うことでサービス体験を向上させてます。
またAPIのバージョンアップによりアプリ外のサービスにも機能拡張できるApp Extensionによりアプリ外にもサービスロジックが必要になるなど、現状のアプリは、複数プラットフォーム展開によるコード流用のニーズが高いです。

watchOS AppExtension
watchOSTempl AppExtension

Embedded frameworkは、iOSアプリターゲットからコードを抽出し別ターゲットで管理することでiOSアプリターゲット以外でもframeworkとして使うことができることで、コード共有を実現しています。

ケース2: ビルド時間の短縮

Xcodeで使われているビルダーではインクリメンタルビルドをサポートしており、開発中では主にこのビルド方式が多く使われます。 このインクリメンタルビルドは変更があった箇所と変更に影響ある箇所だけをビルドすることでビルド時間短縮します。

これをコードをframeworkで分離することでコード改修した箇所でframework先まではビルドされることはないので、より少ない時間でビルドが終わります。

同じ理論でビルド時間短縮してるのがCocoaPodsからのCarthageになります。

ケース3: レイヤードアーキテクチャの疎結合を強化

Embedded frameworkといってもframeworkと同じ扱いになり、framework内の機能を使うにはimportしないとコンパイルエラーとなります。
つまり言語レベルでレイヤー間のアクセス違反を検知してくれるようになります。
(検知といっても検知した後はエンジニアが気づく必要があるので完璧とはいえないですが)

Embedded Frameworkを作る

仕組みがシンプルですが、実装方法もシンプルです。

  1. Frameworkターゲット追加
  2. 作成されたフォルダ内にコード実装
  3. アプリターゲット > Generalからフレームワークを追加
  4. アプリ側コードからimportして呼び出し

では実際にLogicというEmbedded frameworkを用意し、中にはCalculatorという構造体を用意してみます。

Frameworkターゲット追加

プロジェクトのGeneralからターゲット追加します。↓

XcodeTargetGeneral

Frameworkを選択します。↓
注意点としてXcodeは定期的にUIを変更するため、時期によってはこの画面や名称とは違うケースがあります。

XcodeAddTarget

作成されたフォルダ内にコード実装

Frameworkターゲットを追加するとターゲットと一緒にフォルダも作成されます。

XcodeAddedFrameworkTarget

コードは何でもいいですが、今回は下記コードをFrameworkの管理するフォルダに追加します。

public struct Calculator {
    public static func plus(vals: Int...) -> Int {
        vals.reduce(0, +)
    }
}

アクセススコープに注意

framework全般の常識として外部から使われることを想定しているクラスやメソッドのスコープをpublicにして呼び出し元から見えるようにします。
スコープ未指定だとframework外だと見えないので注意です。

アプリターゲット > Generalからフレームワークを追加

作成したframeworkをiOSアプリターゲットから使えるようにするために関連付けする必要があります。
アプリターゲットのGeneralからframework追加を行います。

XcodeAddFramework

を選ぶことで選択ダイアログが出てきますが、内部ターゲットになるのですぐ見つけれます。

XcodeAddFrameworkDialog

アプリ側コードからimportして呼び出し

あとは使いたい場所でimportして呼び出すだけです。

import UIKit
import logic

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        print(Calculator.plus(vals: 0, 1, 2))
    }
}

今回のコードはGitHubにあげてあります。実際にXcode立ち上げて確認したい方はどうぞ。

このエントリーをはてなブックマークに追加