Excite Smartphone Engineer's Blog

2012年 11月 06日

Xcode4.5.1でiOS用のframeworkを作成する

スマートフォン推進室の渡辺です。

今回は「iOS用frameworkの作り方」について書いていきます。
frameworkは簡単に扱えるので非常に便利です。
しかし自分でframeworkを作ろうとすると、Xcode4.5.1時点ではまだiOS用のFrameworkテンプレートが無いため作成には少々手間がかかります。
実際に「Excite.framework」を作成する流れでframeworkを作成するにはどうするかをご紹介いたします。





XcodeのCommand Line Toolsをインストール
プロジェクトを作成
公開用ヘッダ・リソースファイルフォルダの作成
framework用のターゲット作成
framework用プロパティリスト作成
framework作成スクリプトの設定
ビルド

XcodeのCommand Line Toolsをインストール


まずCommand Line Tools をインストールします。
Xcodeを起動し、メニューの「Xcode」→「Preferences…」を開きます。
e0291676_15463690.jpg

Download のComponents にCommand Line Toolsがあるので、もしInstallボタンが表示されていたらボタンをクリックしてインストールします。
下記はインストールが終了した時の表示です。
e0291676_1544264.png

プロジェクトを作成


まずはプロジェクトを作成します。
e0291676_15472574.jpg

「Framework & Library」の「Cocoa Touch Static Library」を選択しNextで作成します。
今回は「Excite」というプロジェクトを作ります。
「Excite.framework」じゃない点に注意してください。
e0291676_15475855.jpg

公開用ヘッダ・リソースファイルフォルダの作成


frameworkで公開するためのヘッダファイルとリソースファイル置き場を用意します。
e0291676_154995.jpg

Exciteで右クリックメニューをだし、「Add Files to "Excite"…」を選択します。
ファイル選択画面の左下にある「New Folder」で「Headers」を作って「Add」します。
同様に「Resources」も作成しておきます。
e0291676_15493820.jpg

※このHeadersとResourcesフォルダはframeworkを使用するプロジェクトから見える状態になります。
※もしプライベートなヘッダ等がある場合はここに入れないようにしてください。

framework用のターゲット作成


実際にframeworkを作成するためのターゲットを追加します。
Add TargetでiOS→Other→Aggregate選択しNextボタンで作成します。
e0291676_15503326.jpg

Product名は最終的に作成する名前(xxx.framework)にします。
今回は「Excite.framework」を入力します。
e0291676_1551361.jpg

ビルドしやすいようにframeworkのSchemeだけ残します。
ManageSchemeでExcite のチェックを外します。
e0291676_15514444.jpg

e0291676_1552418.jpg

framework用プロパティリスト作成


フレームワーク用のInfo.plistを作成します。
Exciteで右クリックメニューをだし、「New File...」を選択します。
テンプレートは「iOS」→「Resource」→「Property List」です。
e0291676_15523994.jpg

名前は「Info.plist」とします。
このファイルは後で設定するスクリプトで使用しますので、Targetの指定は必要ありません。
e0291676_15531024.jpg

作成したInfo.plistファイルを編集します。
コピー&ペーストするには、「Open As」→「Source Code」で開きます。
e0291676_1553428.jpg

コピー元のplistはこちら。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Excite</string>
<key>CFBundleGetInfoString</key>
<string>Excite</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.company.exciteframework</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Excite</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright company. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

コピーしたら「Property List」で開き直して適宜修正してください。

framework作成スクリプトの設定


frameworkはビルドされたファイルを規定されたフォルダに配置した集合体(フォルダ)なので、ビルドしたバイナリやヘッダファイルなどをコピーする必要があります。
自動化をするため、frameworkを作成するスクリプトを設定します。
まずスクリプトの設定枠を用意します。
Excite.frameworkの「Build Phases」を選択し、右下の「Add Build Phase」から「Add Run Script」を選択します。
e0291676_15591211.jpg

Run Scriptが追加されているので展開します。
e0291676_1604111.jpg

"Type a script or drag a script file from your workspace"と書かれているテキストフィールドにスクリプトをコピーします。

# ==========
# 変数設定
# ==========

INFOPLIST='Info.plist'
FRAMEWORK_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleName" ${INFOPLIST})
BUILD_TARGET_NAME=$FRAMEWORK_NAME
FRAMEWORK_BUILD_CONFIGURATION="Release"
FRAMEWORK_VERSION_NUMBER=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${INFOPLIST})
FRAMEWORK_VERSION=A
FRAMEWORK_BUILD_PATH="Framework"
FRAMEWORK_DIR="${FRAMEWORK_BUILD_PATH}/${FRAMEWORK_NAME}.framework"
PACKAGENAME="${FRAMEWORK_NAME}.${FRAMEWORK_VERSION_NUMBER}.zip"

# ==========
# ビルド
# ==========
xcodebuild -configuration ${FRAMEWORK_BUILD_CONFIGURATION} -target ${BUILD_TARGET_NAME} clean
xcodebuild -configuration ${FRAMEWORK_BUILD_CONFIGURATION} -target ${BUILD_TARGET_NAME} -sdk iphonesimulator${IPHONEOS_DEPLOYMENT_TARGET}
[ $? != 0 ] && exit 1
xcodebuild -configuration ${FRAMEWORK_BUILD_CONFIGURATION} -target ${BUILD_TARGET_NAME} -sdk iphoneos${IPHONEOS_DEPLOYMENT_TARGET}
[ $? != 0 ] && exit 1

# ==========
# frameworkディレクトリ作成
# ==========

[ -d "${FRAMEWORK_BUILD_PATH}" ] && rm -rf "${FRAMEWORK_BUILD_PATH}"
mkdir -p ${FRAMEWORK_DIR}
mkdir -p ${FRAMEWORK_DIR}/Versions
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Resources
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Headers
ln -s ${FRAMEWORK_VERSION} ${FRAMEWORK_DIR}/Versions/Current
ln -s Versions/Current/Headers ${FRAMEWORK_DIR}/Headers
ln -s Versions/Current/Resources ${FRAMEWORK_DIR}/Resources
ln -s Versions/Current/${FRAMEWORK_NAME} ${FRAMEWORK_DIR}/${FRAMEWORK_NAME}

# ==========
# framework作成
# ==========
lipo -create \
build/${FRAMEWORK_BUILD_CONFIGURATION}-iphoneos/lib${FRAMEWORK_NAME}.a \
build/${FRAMEWORK_BUILD_CONFIGURATION}-iphonesimulator/lib${FRAMEWORK_NAME}.a \
-o "${FRAMEWORK_DIR}/Versions/Current/${FRAMEWORK_NAME}"

cp ${BUILD_TARGET_NAME}/Headers/*.h ${FRAMEWORK_DIR}/Headers/
cp ${BUILD_TARGET_NAME}/Resources/* ${FRAMEWORK_DIR}/Resources/
cp ${INFOPLIST} ${FRAMEWORK_DIR}/Resources/
cd ${FRAMEWORK_BUILD_PATH}
chmod -fR 777 "${FRAMEWORK_NAME}.framework"
zip -ry ${PACKAGENAME} $(basename $FRAMEWORK_DIR)

ビルド


すべての設定が終わりました。
実際にビルドしてみましょう。
ビルドが成功すると、Frameworkフォルダが自動で作られで、その中にExcite.frameworkとzipができます。
実際にこのframeworkを使用する時は、Excite.frameworkを使用するプロジェクトにコピーして、他のframework同様にリンクして使用します。

frameworkごとにこの作業をしなければいけないのでちょっと手間ですがメリットも大きいので是非活用してみてください。

なお、この記事を作成するにあたり様々なサイトを参考にさせていただきました。
「iOS framework 作成」などで検索するとたくさんの記事がヒットしますので、他のサイトも参考にしてみてください。

by sp_tech | 2012-11-06 12:47 | iOS | Trackback | Comments(2)
トラックバックURL : http://blog.excite.co.jp/spdev/tb/18688449
トラックバックする(会員専用) [ヘルプ]
Commented by shiratsu at 2012-12-24 12:12 x
お世話になります

ちょっと自分でフレームワークを作って、今後の開発を楽にしようと思って、
こちらのページ等を参考にフレームワークを作ったのですが、、、

実際テストプロジェクトに組み込んだのですが、上手くリンクしてくれません
プログラム上で呼び出す分には、参照できてるのですが、、、

ld: framework not found フレームワーク名
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ビルドすると上記のエラーが出ます。
フレームワーク名はフレームワーク名.frameworkで作ってます

どなたか分かる方いらっしゃいますでしょうか??

よろしくお願いします。
Commented by symbol of at 2015-08-18 20:47 x
I’m a redhead and nothing is different about me.
symbol of love bracelet replica http://www.21eduinfo.com/cartier-love-bangle-witness-several-legendary-enjoy-romance/


<< 2012サマーインターンシップ      エキサイトブログでのコードシン... >>