イナヅマTVログ

InazumaUtils.framework

[iOS][Objective-C][Xcode 4.6.3] そうだFramework(.framework)を作ってみよう

| 1件のコメント

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
Static Library

Choose options for your new project
Product Name: Utils
Utils

Headersフォルダ作成
Group Headers を作成する。
*公開ヘッダーはこの中に追加する

Group Headers をフォルダへリンクする。
Headers
作成したグループ”Headers”を選択。
File inspector > Identity
フォルダを作成しGroupとリンクさせる。

Classesグループを作成。
.mおよび非公開ヘッダーファイル格納用。
Headersと同様にClassesフォルダ作成。

ファイル追加
ヘッダーファイル(.h)はHeadersへ追加。

.mファイルはClassesへ追加。

*公開ヘッダーファイルはフォルダHeadersに入ってないといけない。
Utils.xcodeproj

TARGETS追加
Add Target > OS X > Other > Aggregate
Add target

Choose options for your new project
Product Name: InazumaUtils.framework
InazumaUtils.framework

Linker設定
Linking > Other Linker Flags
-ObjC
-all_load
Linker

Header Search設定
Search Paths > Header Search Paths
$(BUILT_PRODUCTS_DIR)
$(BUILT_PRODUCTS_DIR)

Build setting

Info.plist追加
Resourcesグループ作成
*appプロジェクトの.plistをコピーし書き換えました。
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>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
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)

Run Script

[Product] > Build(command+B)
InazumaUtils.framework を選択しビルド。
InazumaUtils.framework

ビルドに成功するとプロジェクトフォルダ/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>

Project

非公開ヘッダーが作れない

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)

1件のコメント

  1. ピンバック: [iOS][Objective-C][Xcode 4.6.3] そうだStatic Library(.a)を作ってみよう « イナヅマTVログ

コメントを残す