Xcode 4.6.3でiOS Framework(.framework)を作る過程を忘れないためのメモ。
【前提知識】
iOS Frameworkテンプレートは無い。
先人の知恵を借りるとiOS用Frameworkは作れる。
*疑問
なぜAppleはiOS Frameworkテンプレートを用意してない?
カスタムなiOS Frameworkは作っちゃいけないの?
【参考サイト】
Apple: Introduction to Framework Programming Guide
Xcode4でのiOS Frameworkの作り方
iOS: 自作Frameworkを作る
Xcode4.5.1でiOS用のframeworkを作成する
Xcode4.6でiOS framework作成
[iOS] Static Library (5) Frameworkを作成する
How to create custom iOS Framework using xCode ?
【作成のポイント】
Static Libraryを作る方法と基本は同じ。
公開ヘッダーファイルは実在するフォルダに入れる。
ビルド時にシェルスクリプトを走らせる。
Static Libraryプロジェクトを作る
[File] > New > Project (command+shift+N)
Choose a template for your new project
Framework & Library > Cocoa Touch Static Library
Choose options for your new project
Product Name: Utils
Headersフォルダ作成
Group Headers を作成する。
*公開ヘッダーはこの中に追加する
Group Headers をフォルダへリンクする。
作成したグループ”Headers”を選択。
File inspector > Identity
フォルダを作成しGroupとリンクさせる。
Classesグループを作成。
.mおよび非公開ヘッダーファイル格納用。
Headersと同様にClassesフォルダ作成。
ファイル追加
ヘッダーファイル(.h)はHeadersへ追加。
.mファイルはClassesへ追加。
*公開ヘッダーファイルはフォルダHeadersに入ってないといけない。
TARGETS追加
Add Target > OS X > Other > Aggregate
Choose options for your new project
Product Name: InazumaUtils.framework
Linker設定
Linking > Other Linker Flags
-ObjC
-all_load
Header Search設定
Search Paths > Header Search Paths
$(BUILT_PRODUCTS_DIR)
Info.plist追加
Resourcesグループ作成
*appプロジェクトの.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>en</string> <key>CFBundleExecutable</key> <string>InazumaUtils</string> <key>CFBundleIconFile</key> <string></string> <key>CFBundleIdentifier</key> <string>com.inazumatv.InazumaUtils</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>InazumaUtils</string> <key>CFBundlePackageType</key> <string>FWMK</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleShortVersionString</key> <string>1.0.0</string> <key>CFBundleVersion</key> <string>1.0</string> <key>NSPrincipalClass</key> <string></string> <key>NSHumanReadableCopyright</key> <string>Copyright © 2013年 inazumatv.com. All rights reserved.</string> <key>CFBundleGetInfoString</key> <string>InazumaUtils</string> </dict> </plist> |
Add Run Script
InazumaUtils.framework選択
Build Phases > Add Build Phase > Add Run Script
Script追加
# ========== # 変数設定 echo "[0] prepare ${INFOPLIST}" # ========== 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" # ========== # ビルド echo "[1] build 1" # ========== 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 echo "[1] build 2" xcodebuild -configuration ${FRAMEWORK_BUILD_CONFIGURATION} -target ${BUILD_TARGET_NAME} -sdk iphoneos${IPHONEOS_DEPLOYMENT_TARGET} [ $? != 0 ] && exit 1 # ========== # frameworkディレクトリ作成 echo "[2] mkdir 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作成 echo "[3] lipo 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) echo "[4] Framework: Copying assets into current version..." cp -r Headers/* ${FRAMEWORK_DIR}/Headers/ cp ${INFOPLIST} ${FRAMEWORK_DIR}/Resources/Info.plist # ============================= echo "[5] zip archive" cd ${FRAMEWORK_BUILD_PATH} chmod -fR 777 "${FRAMEWORK_NAME}.framework" zip -ry ${PACKAGENAME} $(basename $FRAMEWORK_DIR) |
[Product] > Build(command+B)
InazumaUtils.framework を選択しビルド。
ビルドに成功するとプロジェクトフォルダ/Frameworkにファイルが作られる。
InazumaUtils.frameworkをProject NavigatorのFrameworksへ追加すると使用可能。
同階層のzipファイルはInazumaUtils.frameworkをzip圧縮しInfo.plistの”Bundle versions string, short”で設定したバージョンナンバーを付けたもの。
配布する際はzipファイルを渡せば良いかと思います。
Deployment TargetをiOS 5.1にする
注意
Deployment Targetを最新版以外にする時は対象のiOS SDKが必要です。
Xcode 4.6.3へiOS SDK 5.1を追加したのようにSDKを追加して下さい。
InazumaUtils.frameworkを使う
FrameworksへInazumaUtils.frameworkを追加(コピー)する。
#import <InazumaUtils/InazumaUtils.h> #import <InazumaUtils/IZDevice.h> |
非公開ヘッダーが作れない
Classファイルの作り方がまずい可能性大だけど。
ヘッダーファイルは全て公開ディレクトリHeadersに作らないとエラーになる。
困ったなぁ〜
update
依存ライブラリ, frameworkを同梱できない
制作しているframeworkで使用しているframeworkを同梱する方法が分からない。
今の状態は使用するアプリ側に必要ライブラリ, frameworkを伝え追加してもらっている。
ココの情報とかみたいだけど…
【私訳】iOSのスタティックフレームワークを高速かつ効果的に、作成・開発・配布する方法
上記原文:How to create, develop, and distribute iOS Static Frameworks quickly and efficiently
原文はgithubにありサンプルソースも配布されている。
Universal Framework iPhone iOS (2.0)
ピンバック: [iOS][Objective-C][Xcode 4.6.3] そうだStatic Library(.a)を作ってみよう « イナヅマTVログ