15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

オリジナルのCocoa Touch Frameworkの作成方法

Last updated at Posted at 2015-12-20

 よそに提供する処理をFramework化したら便利かも?と思って試してみました。
実装内容(.mファイル)を隠蔽して誰かにコードを提供したい時に役立ちそうです。

 ちなみに隠蔽できるのは実装内容だけです。
Framework内で利用するリソース(画像やら音楽など)は丸見えですのでご注意を!
(アクセスキーファイルとかは持たせないこと...)

#1. Cocoa Touch Frameworkプロジェクトを作成する
 Cocoa Touch Framework作成用のテンプレートを使います。

スクリーンショット 2015-12-20 9.34.15.png

#2. Frameworkで提供する処理を実装する
 Frameworkで提供する処理を実装していきます。
Objective-CとSwiftで方法が少し変わるので,それぞれ解説しています。
ちなみに,Swiftで提供する方が楽です...。個人的には。

(1) SwiftでFrameworkを作る場合

 普通に.swiftファイルを作成していけばOKです。
ただし,今回は別のTargetに機能を提供するのでアクセス修飾子に注意です。
具体的にはpublic属性付きでクラスや関数を定義していきます。

SwiftClass.swift
public class SwiftClass {
    
    public init() {
        // 初期化処理
    }
    
    /**
     Frameworkで提供している機能
     */
    public func inputCommand() -> String {
        return "波動拳"
    }
}

※Swiftで提供クラスを作成する場合,[プロジェクト名].hの記述は不要です。

(2) Objective-CでFrameworkを作る場合

 Objective-Cの場合も基本はSwiftと同じです。
Swiftと違う点は,Frameworkで外部に提供する機能を[プロジェクト名].hファイルに記述する点です。

MyFramework.h
#import <UIKit/UIKit.h>

//! Project version number for MyFramework.
FOUNDATION_EXPORT double MyFrameworkVersionNumber;

//! Project version string for MyFramework.
FOUNDATION_EXPORT const unsigned char MyFrameworkVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <MyFramework/PublicHeader.h>

// 外部提供するクラス
#import <MyFramework/ObjcClass.h>

3. arm/x86_64/i386全対応のバイナリを作成する

 ここが個人的にハマった点でした。
実機(arm)とシミュレータ(x86_64 i386)では対応するCPUアーキテクチャが異なります。
そのため,両対応したバイナリを含むFrameworkを作る必要があります。
(バイナリが実行環境のアーキテクチャに対応していないとビルドエラー)

 How to build Cocoa Touch Framework for i386 and x86_64 architecture?

 BuildPhaseのRunScriptで以下のコードを実行します。

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

if [ "true" == ${ALREADYINVOKED:-false} ]
then
echo "RECURSION: Detected, stopping"
else
export ALREADYINVOKED="true"

# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework"

# Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"

# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"

# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"

fi

 プロジェクトのRootに.frameworkファイルが作成されます。

#4. Frameworkを利用する
 あとは簡単。
import [フレームワーク名] でOKです。

15
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?