ビギグラマーのノート

自作PCやプログラミングについてのブログです。

【Swift】Frameworkをテスト環境と共に構築する

環境

Xcode: 11.2

Swift: 5

Frameworkの作成

 まずはじめにFrameworkとそのテスト環境を作成します。最初に作るのはFrameworkです。Single View Appから作り始めると後に追記するScriptの関係から多少めんどくさくなります。

f:id:BegiGrammer:20191102164839p:plain

 FrameworkのTargetでテスト用のSingleViewAppを追加します。

f:id:BegiGrammer:20191102165020p:plain

f:id:BegiGrammer:20191102165026p:plain

 次のステップとしてFrameworkに仮のclassを作っておきます。Frameworkの内容はこの場所等に書いていきます。

f:id:BegiGrammer:20191102165338p:plain

 さらに次にはTargetでCross-Platform > Aggregateを追加します。追加方法は上記のSingleViewAppの追加方法と同じです。Aggregateを追加することでFrameworkをSimulator用とDevice用の両者に対応するような結合したFrameworkを出力するようにします。

f:id:BegiGrammer:20191102165727p:plain

今作成したAggregateのBuildPhasesでRun Scriptを追加します。写真がちょっと違っていますが場所は同じです。

f:id:BegiGrammer:20191102170514p:plain

 この場所に貼り付けるScirptはこちらをコピペしてくればOKです。

gist.github.com

ビルドターゲットとして先ほど作成したAggregateを指定し、command + B等でビルドします。

f:id:BegiGrammer:20191102170757p:plain

このビルドでFrameworkの作成が完了しました。このFrameworkの場所は少々探しにくい位置にありますがProductsでShow In Finderをすることで素早くアクセスすることができます。

f:id:BegiGrammer:20191102171411p:plain

 Frameworkがある場所はDebug-universal内、今回はTestFramework.frameworkです。その他のフォルダには実機用とSimulator用のFrameworkが置いてあります。余談ですがこのFrameworkの違いはスマホ用とPC用で採用しているプロセッサの違いから来ているものなので、将来的にIntel Macから自社開発のCPU搭載Macとなった場合若干開発が楽になりそうです。

f:id:BegiGrammer:20191102172033p:plain

f:id:BegiGrammer:20191102172038p:plain

以下からは作成したFrameworkを実際のAppに組み込む方法となります。

追記 1

 いちいちめんどくさい場所からShow in Finderして持ってこずとも、Project直下にFrameworkが作成されている模様。Aggregateをビルドした際に勝手に開く場所ね。最初この方法でやった時には.frameworkはこの場所に作成されていなかったような覚えがありますが、知らないうちに環境変えてしまったのかよくわかりません。まあ、どちらからも取れるってことでここはひとつ。

 さらにBuildターゲット?を選択する際に写真ではGeneric iOS Deviceを選択していますが、一番上の選択肢にあると思うMy Macでも同様にできるようです。Simulatorは結局Mac上で動いているためユニバーサルFrameworkではどっちでも選べるのか?まあ、そんな感じに思っています。ただし、Generic iOS Deviceを選択した場合のみDeviceDataフォルダ下(ようは前述しためんどくさい深い場所、Show in Finderで飛べる)に生成されるようです。つまり、BuildターゲットはMyMacを選択し、Generic iOS Deviceはここでも一応できるよ程度に覚えておくのがいいかもしれません。

 

追記 2

 本記事ではまずProjectをFrameworkで作成し、後にSingleViewAppを追加しました。これを逆にするとどうなるでしょうか。つまりSingleViewAppでProject作成後Frameworkを追加した場合です。この場合Universalに.frameworkが作成されません。また追記1で記述した箇所にframeworkは同様に作成されません。

 結論からいうと${PROJECT_NAME}の変数がFrameworkの箇所を指さなくなる為Scriptが思った通りに実行されません。

 これはRunScriptを読んで貰えば分かるのですが、

"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework

という箇所でiOS側のframeworkを指定しているのですが、この${PROJECT_NAME}がFrameWorkではなく最初に作成されたSingleViewAppの方を指してしまうのです。そうするとBuild/Products/Debug-iphoneos/SingleViewAppName.frameworkにはFramework本体が作成されない為、ScriptがStep.1 Build Devices and Simulator versions以降実質的に実行されない状態となる為です。

 わかりづらい説明ですが、とりあえずFramework -> SingleViewAppの順で作成すれば問題ないという事です。どうしてもSingleViewApp作成後Frameworkを追加したい場合Run Scripを変更しなければなりません。

Frameworkの組込

 SingleViewAppでとりあえず空のProjectを作成しておきます。今回は"Test"という名のAppを作成しました。組込方法はいくつかあるのですが、とりあえずわかりやすい方法で回してきます。右クリックでAdd File to "Project"を選択し作成したFrameworkをAppに組み込みます。この際にCopy items if neededに選択をしておいてください。

f:id:BegiGrammer:20191102173906p:plain

 FrameworkをProjectに追加後、Targetsの"Project Name"(今回はTest)のCopy FilesにFrameworkを追加します。この時Copy Filesの項目が存在しない場合はRun Scriptと同じようにCopy Filesの項目を追加してください。またFrameworkを追加するためにCopy FilesのDestinationをFrameworkに変更してください。

f:id:BegiGrammer:20191102174426p:plain

f:id:BegiGrammer:20191102174440p:plain

これで自作Frameworkの組込が完了しました。後はCocoa podsと同じようにimportすれば使用が可能です。

f:id:BegiGrammer:20191102174630p:plain