スマートフォン推進室の渡辺です。
今回は「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…」を開きます。
Download のComponents にCommand Line Toolsがあるので、もしInstallボタンが表示されていたらボタンをクリックしてインストールします。
下記はインストールが終了した時の表示です。
プロジェクトを作成
まずはプロジェクトを作成します。
「Framework & Library」の「Cocoa Touch Static Library」を選択しNextで作成します。
今回は「Excite」というプロジェクトを作ります。
「Excite.framework」じゃない点に注意してください。
公開用ヘッダ・リソースファイルフォルダの作成
frameworkで公開するためのヘッダファイルとリソースファイル置き場を用意します。
Exciteで右クリックメニューをだし、「Add Files to "Excite"…」を選択します。
ファイル選択画面の左下にある「New Folder」で「Headers」を作って「Add」します。
同様に「Resources」も作成しておきます。
※このHeadersとResourcesフォルダはframeworkを使用するプロジェクトから見える状態になります。
※もしプライベートなヘッダ等がある場合はここに入れないようにしてください。
framework用のターゲット作成
実際にframeworkを作成するためのターゲットを追加します。
Add TargetでiOS→Other→Aggregate選択しNextボタンで作成します。
Product名は最終的に作成する名前(xxx.framework)にします。
今回は「Excite.framework」を入力します。
ビルドしやすいようにframeworkのSchemeだけ残します。
ManageSchemeでExcite のチェックを外します。
framework用プロパティリスト作成
フレームワーク用のInfo.plistを作成します。
Exciteで右クリックメニューをだし、「New File...」を選択します。
テンプレートは「iOS」→「Resource」→「Property List」です。
名前は「Info.plist」とします。
このファイルは後で設定するスクリプトで使用しますので、Targetの指定は必要ありません。
作成したInfo.plistファイルを編集します。
コピー&ペーストするには、「Open As」→「Source Code」で開きます。
コピー元の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」を選択します。
Run Scriptが追加されているので展開します。
"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 作成」などで検索するとたくさんの記事がヒットしますので、他のサイトも参考にしてみてください。