月別アーカイブ: 2014年1月

Xcode 5 で framework を作成

iOSアプリ「タカラモノデイズ」のリリースから約半年ー。
今後に使えそうな機能をまとめようと思い Xcode で framework を作成してみた。

framework 作成概要

【Xcodeバージョン:5.0.2

項目 概要
プロジェクト作成 framework 用のプロジェクトを作成する
ディレクトリ作成 公開用ヘッダおよびリソースのディレクトリを作成する
プロパティリスト作成 Info.plist を作成する
ターゲット追加 ビルドターゲットを追加する
スクリプト作成 ビルド用のシェルスクリプトを作成する
ビルド ビルドし framework を作成する

framework 作成手順

◆プロジェクト作成
1. メニューから [File] » [New] » [Project…] を選択
2. [iOS] » [Framework & Library] の「Cocoa Touch Static Library」を選択し、[Next] ボタン押下
xcode_framework01
3.「Product Name」 を入力し、[Next] ボタン押下
xcode_framework02
4. 適当な場所を選択し、[Create] ボタン押下

◆ディレクトリ作成
1. “Sample” ディレクトリのコンテキストメニューで [Add Files to “Sample”…] を選択
xcode_framework03-01
2. [New Folder] ボタンを押下
3.「Name of new folder」に “Headers” を入力し、[Create] ボタン押下
xcode_framework03-02
4. [Add] ボタン押下  ※同様にリソース用ディレクトリ(Resources)も作成する。
5. 作成した “Headers” ディレクトリに公開するヘッダファイルを置く

最終的にはこんな感じになる↓ 
xcode_framework04
(Resources は後述。Classes は必要に応じて作成する。)

◆プロパティリスト作成
1. “Resources” ディレクトリのコンテキストメニューで [New File..] を選択
xcode_framework05-1
2. [iOS] » [Resource] の「Property List」を選択し、[Next] ボタン押下
xcode_framework05-2
3.「Save As:」に “Info.plist” と入力し、[Create] ボタンを押下
xcode_framework05-4
4. Info.plist のサブメニューで、[Open As] » [Source Code] を選択
xcode_framework05-3
5. Info.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>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleIdentifier</key>
    <string>com.company.${PRODUCT_NAME:rfc1034identifier}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleGetInfoString</key>
    <string>${PRODUCT_NAME}</string>
    <key>NSPrincipalClass</key>
    <string></string>
    <key>CFBundlePackageType</key>
    <string>FMWK</string>
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright © All rights reserved.</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0.0</string>
</dict>
</plist>

◆ターゲット作成
1. [TARGETS] » [Add Target…] を選択
xcode_framework06-1
2. [iOS] » [Other] の「Aggregate」を選択し、[Next] ボタン押下
xcode_framework06-2
3.「Product Name」を入力し、[Finish] ボタン押下
xcode_framework06-3

◆スクリプト作成
1. [TARGETS] » [Sample.framework] » [Buld Phases] を選択
xcode_framework07-1
2. メニューの[Editor] » [Add Build Phase] » [Add Run Script Build Phase] を選択
xcode_framework07-2
3. [Build Phases] » [Run Script] に下記のようなスクリプトを入力

# Environment Variables
INFO_PLIST="Resources/Info.plist"
FRAMEWORK_NAME=${PROJECT_NAME}
FRAMEWORK_VERSION_NUMBER=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${SRCROOT}/${PROJECT_NAME}/${INFO_PLIST})
FRAMEWORK_VERSION=A
FRAMEWORK_BUILD_PATH="${SRCROOT}/build/${CONFIGURATION}-framework"
FRAMEWORK_DIR="${FRAMEWORK_BUILD_PATH}/${FRAMEWORK_NAME}.framework"
FRAMEWORK_PACKAGE_NAME="${FRAMEWORK_NAME}.${FRAMEWORK_VERSION_NUMBER}.zip"

# Clean directories
[ -d "${FRAMEWORK_BUILD_PATH}" ] && rm -rf "${FRAMEWORK_BUILD_PATH}"

# Build simulator and device binaries
xcodebuild -project ${PROJECT_NAME}.xcodeproj \
 -sdk iphonesimulator${IPHONEOS_DEPLOYMENT_TARGET} \
 -target "${PROJECT_NAME}" \
 -configuration ${CONFIGURATION} clean build
xcodebuild -project ${PROJECT_NAME}.xcodeproj \
 -sdk iphoneos${IPHONEOS_DEPLOYMENT_TARGET} \
 -target "${PROJECT_NAME}" \
 -configuration ${CONFIGURATION} clean build

# Create directories
mkdir -p ${FRAMEWORK_DIR}
mkdir -p ${FRAMEWORK_DIR}/Versions
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Headers
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Resources

# Create symbolic link
ln -s ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION} ${FRAMEWORK_DIR}/Versions/Current
ln -s ${FRAMEWORK_DIR}/Versions/Current/Headers ${FRAMEWORK_DIR}/Headers
ln -s ${FRAMEWORK_DIR}/Versions/Current/Resources ${FRAMEWORK_DIR}/Resources
ln -s ${FRAMEWORK_DIR}/Versions/Current/${FRAMEWORK_NAME} ${FRAMEWORK_DIR}/${FRAMEWORK_NAME}

# Create the universal library
lipo -create \
${SRCROOT}/build/${CONFIGURATION}-iphoneos/lib${FRAMEWORK_NAME}.a \
${SRCROOT}/build/${CONFIGURATION}-iphonesimulator/lib${FRAMEWORK_NAME}.a \
-output "${FRAMEWORK_DIR}/Versions/Current/${FRAMEWORK_NAME}"

# Copy files
ls ${SRCROOT}/${PROJECT_NAME}/Headers/*.h > /dev/null 2>&1 && cp ${SRCROOT}/${PROJECT_NAME}/Headers/*.h ${FRAMEWORK_DIR}/Headers
cp ${SRCROOT}/${PROJECT_NAME}/${INFO_PLIST} ${FRAMEWORK_DIR}/Resources

# Create zip
cd ${FRAMEWORK_BUILD_PATH}
zip -ry ${FRAMEWORK_PACKAGE_NAME} $(basename $FRAMEWORK_DIR)

※スクリプトが間違っていたので修正。(coppieee さん、ご指摘ありがとうございました)
最後から2行目
【誤】cp ${FRAMEWORK_BUILD_PATH}
【正】cd ${FRAMEWORK_BUILD_PATH}

◆ビルド
1. ビルドターゲットを「Sample.framework」に変更
xcode_framework08-1
2. メニューの[Product] » [Build] を選択

ビルドが成功すると、
デバッグビルドの場合は「build/Debug-framework」
リリースビルドの場合は「build/Release-framework」
Sample.framework が作成される。