1. 程式人生 > >關於xcode8的建立依賴其他第三方庫(cocoapods管理)的靜態庫framework

關於xcode8的建立依賴其他第三方庫(cocoapods管理)的靜態庫framework

我們在編寫 SDK 的時候, 有時候會用到一些常用元件, 比如 AFNetworking.
如果直接將AFNetworking編譯進 SDK ,那麼如果使用者在使用你寫的 SDK 的同時也使用了 AFNetworking,那麼會出現”duplicate symbol OBJC_CLASS$_xxx”的問題.
如果自己重新寫一個功能類似 AFNetworking 的元件,一來是很麻煩,二來像這種成熟的第三方庫, 都是經過很多人測試過,多次修改 bug的,自己寫的話,未必比得上,而且重複造輪子也是沒有多大意義的.
接下來我們就來開始寫一個簡單的 SDK,並且使用 AFNetworking

*1. 建立工程*

選Cocoa Touch Framework,
建立靜態庫framework的第一步:
至於為何不選擇 Cocoa Touch Static Library 是因為雖然後者也能建立靜態庫,但是最後得到的是一堆標頭檔案加上一個 .a 檔案,不容易部署, 而 Framework 則是把標頭檔案和編譯好的二進位制檔案打包為一個. framwork ,容易部署.
這裡寫圖片描述

*2. 加入 AFNetworking*

既然要使用 AFNetworking ,自然要先引入, 這裡我用 CocoaPods 來管理。
首先,你需要安裝一個CocoaPods 外掛,然後在終端操作。
終端開啟工程,開始編輯下載AFNetworking
編輯下載的第三方內容

然後pod install,下載AFNetworking.

* 3. 編寫 SDK*

拖入需要生成靜態庫的檔案

拖入需要生成靜態庫的檔案

在與工程同名檔案內部將需要暴漏出來的標頭檔案

編輯需要暴漏出的檔案頭部

*4. 配置*

在Targets->Build Phases ->Headers裡面把需要暴漏的標頭檔案拖拽到Public裡面
這裡寫圖片描述

接下來到 General 中設定需要支援的版本, Build Setting 中加入 armv7s

(注:此處為什麼新增armv7s?
首先了解一下什麼是ARM,ARM是微處理器,而armv6, armv7, armv7s是ARM CPU的不同指令集,

armv6裝置:iPhone, iPhone2, iPhone 3G,第一代、第二代iPod Touch

armv7裝置:iPhone 3GS,iPhone 4,iPhone 4S,iPad ,iPad 2,iPod Touch 3G,iPod Touch 4

armv7s裝置:iPhone 5,iPad4

arm64裝置:iPhone 5S,iPad Air,iphone6,iphone6plus,iPhone6s,iPhone6s Plus等

Xcode6更新後,預設不支援armv7s,也就是預設不會編譯armv7s架構,雖然其處理器架構會向下相容,但是無法進行相關優化操作。如果你提供的Framework預設不支援armv7s架構,但是使用者要支援armv7s架構,這時就會有衝突,Xcode無法構建程式碼原因是丟失某架構(armv7s架構)連結庫的錯誤,所以為了避免衝突,Framework預設支援armv7s架構,使用過程中由使用者自行決定是否支援。)

這裡寫圖片描述
將Build Active Architecture Only選項設為YES,導致其編譯時只生成當前機器的框架,將其設定為NO,不知生成當前的機器框架,所有的都有。
這裡寫圖片描述
1.選擇工程檔案>target第一項>Build Setting>搜尋linking,然後幾個需要設定的選項都顯現出來,首先是Dead Code Stripping設定為NO,
2.然後將Link With Standard Libraries關閉,
3.最後將Mach-O Type設為Static Library,framework可以是動態庫也可以是靜態庫,對於系統的framework是動態庫,而使用者製作的framework只能是靜態庫。動態庫,上傳appstore是不允許的。
這裡寫圖片描述

Architectures:包含哪些架構指令,這裡我們需要新增armv7s架構

Build Active Architecture Only:是否只為當前架構編譯

Dead Code Stripping:是否從framework中刪除未使用的程式碼

Link With Standard Libraries:是否連結蘋果標準庫

Mach-O Type:這裡有好幾種類型,我們需要選中static library

Other Linker Flags(本文沒有用到,提醒):連結引數,如果framework中使用了category,最好加上ObjC、all_load,確保執行時系統會載入其中的category

Other C Flags(本文沒有用到,提醒):額外的C語言連結引數,如果需要支援bitcode,需要加上-fembed-bitcode

接下來可以編譯試試有沒有什麼錯誤和警告
如果沒有,就可以進行下一步了

*5. 增加合併模擬器和真機的 Aggregate Target*

由於編譯的時候,只會編譯當前選中裝置的版本,為了編譯一份同時能夠運行於真機和模擬器的 SDK ,我們再增加一個 target
這裡寫圖片描述
在這個 Target 裡面選擇 Build Phase, 新建一個 Run Script
然後新增指令碼程式碼:
這裡寫圖片描述
指令碼程式碼:

#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
WORKSPACE_NAME=${PROJECT_NAME}.xcworkspace
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions
xcodebuild -workspace "${WORKSPACE_NAME}" -scheme "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphoneos ONLY_ACTIVE_ARCH=NO   BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -workspace "${WORKSPACE_NAME}" -scheme "${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}/"
# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# 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}"

這裡寫圖片描述

設定這個 Target 為 Release
這裡寫圖片描述

然後編輯執行,這裡選擇真機執行會比較好。執行完成後會彈出合成好的framework資料夾路徑,然後就可以拖入專案使用了。
執行完成自動開啟的介面
也可以使用終端,對分別build生成的模擬器和真機的framework進行合併。

(終端程式碼:lipo -create 模擬器的二進位制檔案 真機的二進位制檔案 -output 生成新二進位制檔案的路徑),然後再把真機的framework裡面的二進位制檔案替換掉,接下來這個真機的framework就是合成的最終靜態庫檔案。

*6. 試用。*

拖入的專案工程。
這裡寫圖片描述
新增配置標頭檔案路徑
這裡寫圖片描述這裡寫圖片描述
這裡,在使用終端將我們這個工程裡面加入AFNetworking(這裡不再贅述)。
執行,就可以使用了。
(之前自己碰到我的專案裡面呼叫拖進去的framework,想要繼承裡面的一個類,在新建的時候subclass of竟然找不到裡面的那個類。以為是哪裡配置出現問題了。後來發現是專案編輯執行的時候就沒有呼叫framework的那個類,可以在appdelegate裡面講我們的framework的寫入所有的暴漏標頭檔案的那個.h檔案匯入,那麼工程就會預編譯到,在新建的時候就會找得到你的framework裡買呢所有的暴漏類的標頭檔案了)。

*7. 總結*

架構

對於模擬器來說4s和5的模架構是i386的32位架構,5s至今是x86_64的64位架構。對於真機來說3GS~4s是armv7架構,5和5c是armv7s架構,5s至今是arm64架構

靜態庫

靜態庫: 連結時完整地拷貝至可執行檔案中,被多次使用就有多份冗餘拷貝。

動態庫

動態庫:連結時不會拷貝至可執行檔案中,執行時動態載入進記憶體,供程式呼叫,只加載一次,多個程式可以共用。

相關推薦

關於xcode8建立依賴其他第三方cocoapods管理靜態framework

我們在編寫 SDK 的時候, 有時候會用到一些常用元件, 比如 AFNetworking. 如果直接將AFNetworking編譯進 SDK ,那麼如果使用者在使用你寫的 SDK 的同時也使用了 AFNetworking,那麼會出現”duplicate sym

Visual Studio 2017 動態鏈接DLL /LIB 靜態鏈接(LIB)的思考

imp 動態 -o ffffff library code mic mage .org 軟件工程方面能夠快速的發展,我相信源代碼重用起到了不可忽略的作用。在Linux平臺下就C++而言,有以so結尾的動態鏈接庫文件,也有以.a結尾的靜態連接庫文件,這

FreeSWITCH第三方音頻的簡單介紹

優勢 帶寬 blog 網絡 ndt 目標 領域 合成 通道 FreeSWITCH使用了大量的第三方庫,本文檔主要介紹音頻相關庫的信息: 視頻相關庫的信息介紹參考:http://www.cnblogs.com/yoyotl/p/5488890.html 其他相關庫的信

C語言函式篇靜態和動態建立和使用

使用庫函式是原始碼的一種保護?我猜的. 庫函式其實不是新鮮的東西,我們一直都在用,比如C庫. 我們執行pringf() 這個函式的時候,就是呼叫C庫的函式.   下面記錄靜態庫和動態庫的生成和使用.   靜態庫:libxxx.a 動態庫:libxxx.so  

oracle11goracle12c通用使用active duplicate活動複製建立資料庫遷移

1、庫環境說明 target庫:172.16.24.144   db_name=cc,db_unique_name=cc 庫是完整的,啟動到open階段 SQL> select instance_name,status from v$instance ; INSTAN

Codeblocks建立和呼叫DLL動態連結C語言

建立一個最簡單的只有一個get_id() 函式的DLL庫  一、建立C語言動態連結庫 1.新建一個動態庫的工程 File - New - Project - DLL - Go 新建的工程原來的main.cpp和main.h刪除,新建兩個檔案simple.h, simple

IOS 多工程依賴.a靜態和Bundle

前言:當開發到了一定程度後,積累的工具類或者封裝的東西就越來越多,而很多工程會重複使用到這些類,但是又不想每個工程都匯入一遍,可能會想到將這些打包成(.a)庫或者bundle,但是這樣子有變動的時候又得重新編譯一遍,再匯入,耗費不少時間。解決的方法很多,比如建立

NDK學習( 二),在NDK開發中引入第三方AndroidStudio Cmake

在NDK中可能需要複用之前已經編譯好的so檔案,所以本章的目標是給一個之前編譯好的so檔案外加一個需要呼叫介面的標頭檔案,在現在專案中複用。 在本次實踐過程中,已經有編譯完成的各種cpu架構的libstringutil-lib.so以及標頭檔案,Stringutil.h

informatica 建立儲存Repository Service和整合服務Integration Service

       安裝好infa的伺服器客戶端後,建立infa的儲存庫(Repository Service)和整合服務(Integration Service),這個過程需要注意的是字符集。         通過server的 Informatica administrato

使用Lotus Enterprise Integrator LEI將Domino附件移至關系數據圖文過程

art 成功 extern nal ext http 沒有 其中 需要 參考IBM解決方案:http://www.ibm.com/developerworks/cn/lotus/LEI-attachments/index.html 轉載請註明出處:http://blog.

Python 3.5 連接Mysql數據pymysql 方式

ima 用戶名 oca rim 遊標對象 ide char 名稱 etc 由於 MySQLdb 模塊還不支持 Python3.x,官方的Mysql連接包只支持到3.4,所以 Python3.5 如果想連接MySQL需要安裝 pymysql 模塊。 pymysql 模塊可以通

封裝的一套簡單輕量級JS 類RapidDevelopmentFramework.JS

需要 and arr ucc rda 找到 目的 tco 類庫 1.最近好久沒有更新自己的博客了,一直在考慮自己應該寫一些什麽。4.2日從蘇州回到南京的路上感覺自己的內心些崩潰和失落,我就不多說了? 猛然之間我認為自己需要找一下內心的平衡。決定開發屬於自己一套快速開發的JS

達夢數據第二部分

insert def 技術分享 lob 建立 pat com let ext 1.達夢數據庫創建表 達夢數據安裝完成之後,打開DM管理工具,可以進行數據庫的相關操作。可以通過新建查詢,在SQL命令窗口輸入sql語句,創建表,sql輸入完成之後,選擇sql進行執行,則會在表空

sql server 2008 之利用SQL Server Management Studio創建數據最基礎

sql server 2008 數據庫 基礎本文出自 “大李子” 博客,謝絕轉載!sql server 2008 之利用SQL Server Management Studio創建數據庫(最基礎)

Python學習筆記十六拓展Scipy

mage http 十六 .cn 學習筆記 eight -1 images 分享 Python學習筆記(十六)拓展庫Scipy

Python操作數據mysql redis

tex 行數 元組 cursor nosql sql數據庫 字段 函數 mysql數據庫 一、python操作mysql數據庫: 數據庫信息:(例如211.149.218.16 szz 123456) 操作mysql用pymysql模塊

facebook第三方登陸使用sharedSDK無法加載網址:這個URL的域名未包含應用的域名

page http forum 使用 tar class tid 三方 技術分享 http://bbs.mob.com/forum.php?mod=viewthread&tid=8134&extra=page%3D1 facebook第三方登陸(使用

keepalived 代理後端數據雙主基本配置註解

keepalived AA復制 高可用 keepalived 代理後端服務器基本配置1.環境後端兩臺服務器有雙主數據庫環境2.配置Keepalived主配置文件(/etc/keepalived/keepalived.conf) :keepalived 代理後端數據庫(雙主)基本配置註解

C++算法參考手冊

ref art OS ++ span spa AR href color C++算法庫(參考手冊) 算法庫C++算法庫(參考手冊)

[轉]Spark 踩坑記:數據Hbase+Mysql

cep 直接 策略 https rds 但是 更新 base ID https://cloud.tencent.com/developer/article/1004820 Spark 踩坑記:數據庫(Hbase+Mysql) 前言 在使用Spark Streaming的過程