1. 程式人生 > >cocoapods應用第一部分-xcode建立.framework相關

cocoapods應用第一部分-xcode建立.framework相關

問題的提出: 隨著專案的越來越大,可能會出現好幾個團隊共同維護一個專案的情況,例如:專案組A負責其中的A塊,專案組B負責其中的B塊.....這幾塊彼此之間既獨立,也相互聯絡.對於這種情況,可以採用約定的方式,比如,你只修改你那塊,不要修改公共的.如果要修改公共的,那麼必須要通知一下其它組,大家共同決定怎麼修改,這種方式有一個很大的問題,很有可能不經意間就改了別的團隊的程式碼.還有維護的越來越複雜等. 諸如此類的問題,很自然的我們會考慮每個團隊建立一個靜態庫  IOS的靜態庫有兩種,.a和.framework,  動態庫.framework居多.   靜態庫建議也生成.framework模式的,好處是.framework包含了相關的.h檔案等..a檔案還要自己新增相關的.h檔案    靜態庫:連結時,靜態庫會被完整地複製到可執行檔案中,被多次使用就有多份冗餘拷貝.例如我們在我們的程式中使用了百度地圖的.a檔案,另外一個應用也使用了百度地圖.a.這樣整個系統中,會出現兩個 百度地圖.a檔案    動態庫:連結時不復制,程式執行時由系統動態載入到記憶體,供程式呼叫,系統只加載一次,多個程式共用,節省記憶體.系統提供的庫基本上都屬於此類,例如UIKit等,A應用和B應用中都用到了UIKit,系統只加載了一份在記憶體中.IOS中對於第三方的動態庫,很遺憾,目前還不支援的. 一:framework的製作    從xcode6開始,已經提供了製作.framework的選項了
下面我們用系統自帶的來新建.framework.然後再新增一個依賴庫 AFNetworking 1) xcode的選單欄  File -> New Project  建立一個名為  YohunlUtilsLib 的Cocoa Touch Framework的工程. 將Target 改為 7.0(由於現在大多數應用都還要支援7.0sdk,故此處我們修改為支援7.0)
這時候,編譯一下,你可能會遇到警告  
          (null): Embedded dylibs/frameworks only run on iOS 8 or later 彆著急,這個是由於 從IOS8開始,建立的framework可以是動態的(並不是完全意義上的動態,這裡的動態,其實還是要嵌入到我們的應用中,而不能夠從網上下載,然後用dlopen動態載入的). 我們要修改 Mach-O Type.從預設的Dynamic Library 改為 Static Library,再編譯,警告消失

那麼選擇 Dynamic Library 還是   Static Library 有什麼影響呢? 我已經實際的檢驗過了.(我採用了一個包含了 第三方庫 AFnetworking的測試工程)   Static Library 支援IOS8.0 sdk以下的,從目前來看,大多數工程都還要支援7.0 sdk,所以我們最常用的就是Static Library   當我們使用   Static Library時候,生成的framework直接如同新增普通檔案的形式新增進來就可以了.它會自動在
不過當我們執行的時候,會提示: 當生成後,新增到示例工程中,
好吧,這種模式的新增,看來有些問題呀,還要自己新增依賴庫,這些依賴庫都是系統的,根據提示自己新增就可以了 再執行,OK 當我們使用 Dynamic Library模式(只有IOS8.0及以上才支援
)的時候.如同普通檔案一樣新增到示例工程中去的話,執行,會出現提示: dyld: Library not loaded: @rpath/NetTestLib.framework/NetTestLib
  Referenced from: /Users/yohunl/Library/Developer/CoreSimulator/Devices/B1DBCA26-C113-4C74-BB81-297D4AF1E0C8/data/Containers/Bundle/Application/C1B4F6D5-96FD-4245-8E6D-4F1C569EEF6F/TestFramework.app/TestFramework
  Reason: image not found
解決的方式  在工程的配置  Embedded Binaries下面新增.而不是在 Linked Frameworks and Libraries下新增.這種方式,不需要新增 AFNetworking所需要的系統庫,這一點不知道是什麼原因!!!如果有知道原因的,請也告知我一下啊
再執行,OK 2)  命令列,進入目錄下  pod init 建立一個podfile檔案,因為我們製作的.framework需要用到AFNetworking網路庫 PS:你也可以用任意的方式建立這個podfile檔案     開啟它,因為我採用 pod init命令建立的,開啟後你會發現它已經有內容了
修改其內容為                    platform :ios, '7.0'                    inhibit_all_warnings!                   target 'YohunlUtilsLib' do                         pod 'AFNetworking'                   end                   target 'YohunlUtilsLibTests' do                   end 再執行 pod install 建立依賴 開啟工程,新增一個檔案  YONetwork.h,在其中新增方法 @interfaceYONetwork :NSObject/**
 * 
獲取github上使用者的repo
 *
 * 
@paramuser   使用者名稱
 * 
@paramsuccess成功的回撥
 * 
@paramfailure失敗的回撥
 */

- (
void)getGithubReposForUser:(NSString*)user withSuccess:(void(^)(idresponseObject))success failure:(void(^)(NSError*error))failure;


/**
 * 
測試 getGithubReposForUser:withSuccess:failure
 */

- (
void)test; @end #import"YONetwork.h"
#import
"AFNetworking.h"@implementationYONetwork
- (
void)getGithubReposForUser:(NSString*)user withSuccess:(void(^)(idresponseObject))success failure:(void(^)(NSError*error))failure
{
   
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManagermanager];
    [manager
GET:[NSStringstringWithFormat:@"https://api.github.com/users/%@/repos", user] parameters:nilsuccess:^(AFHTTPRequestOperation*operation,id responseObject) {
        success(responseObject);
    }
failure:^(AFHTTPRequestOperation*operation,NSError*error) {
        failure(error);
    }];
}


- (
void) test {
    [
selfgetGithubReposForUser:@"yohunl"withSuccess:^(idresponseObject) {
       
NSLog(@"getGithubReposForUser response = %@",responseObject);
    }
failure:^(NSError*error) {
       
NSLog(@"getGithubReposForUser error = %@",error);
    }];
}
@end
編譯執行 (command + B),生成相應的.framework檔案  選單 -  organizer 
可以看到目錄結構如下:
其中的 YohunlUtilsLib.framework 就是我們要的  : 注意,YohunlUtilsLib.framework中並沒有包含AFNetworking庫的內容,這一點我們可以用如下的命令來驗證. 命令進入 Debug-iphoneos $ lipo -info YohunlUtilsLib.framework/YohunlUtilsLib 輸出 Architectures in the fat file: YohunlUtilsLib.framework/YohunlUtilsLib are: armv7 arm64 說明我們生成的真機framework:YohunlUtilsLib.framework 包含了兩種架構 armv7 arm64 分離出每一種架構 $ mkdir armV7  當前目錄建立資料夾,用於存放分離後的架構,和分離出的.o檔案 $ lipo YohunlUtilsLib.framework/YohunlUtilsLib -thin armv7 -output ./armv7/YohunlUtilsLib_armv7  分離出armv7架構到資料夾armV7下 $ cd armV7 進入資料夾 $ ar -x YohunlUtilsLib_armv7  分離出armv7架構的所有的.o檔案 分離後,如圖:
可以看到,最後的.framework中,並沒有包含我們pod新增的 AFNetworking.所以 當我們把我們生成的YohunlUtilsLib.framework給別人使用過的時候,別人自己要在專案中新增 AFNetworking,否則會提示找不到的錯誤. 3) 我們使用命令來合併我們生成的真機和模擬器的framework 建立一個新的target
target建立後
新增如下的合併模擬器和真機的指令碼 # Constants
SF_TARGET_NAME=${PROJECT_NAME}
#自定義的用來存放最後合併的framework
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal



#IPHONE_DEVICE_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos

WORKSPACE_NAME=${PROJECT_NAME}.xcworkspace
YO_SCHEME=${PROJECT_NAME}

#clean build是先清除原來的build
xcodebuild -workspace ${WORKSPACE_NAME} -scheme ${YO_SCHEME} -sdk iphonesimulator -configuration
"${CONFIGURATION}"clean build
xcodebuild -workspace ${WORKSPACE_NAME} -scheme ${YO_SCHEME} -sdk iphoneos -configuration
"${CONFIGURATION}"clean build

# build project#xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}" -configuration "${CONFIGURATION}" -sdk iphoneos BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}" CONFIGURATION_BUILD_DIR="${IPHONE_DEVICE_BUILD_DIR}/arm64" SYMROOT="${SYMROOT}" ARCHS='arm64' VALID_ARCHS='arm64' $ACTION#xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}" -configuration "${CONFIGURATION}" -sdk iphoneos BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}"  CONFIGURATION_BUILD_DIR="${IPHONE_DEVICE_BUILD_DIR}/armv7" SYMROOT="${SYMROOT}" ARCHS='armv7 armv7s' VALID_ARCHS='armv7 armv7s' $ACTION# Copy the framework structure to the universal folder (clean it first)#因為framework的合併,lipo只是合併了最後的二進位制可執行檔案,所以其它的需要我們自己複製過來#先移除原來的
rm -rf
"${UNIVERSAL_OUTPUTFOLDER}"
mkdir -p
"${UNIVERSAL_OUTPUTFOLDER}"
cp -R
"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework"#合併模擬器和真機的架構
lipo -create 
"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}""${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"-output"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}"

open
"${UNIVERSAL_OUTPUTFOLDER}"
對於以上的指令碼,其中用到了很多的 xcode預定義的變數,這些變數怎麼來的呢?你可以在命令列下, 輸入 xcodebuild -workspace YohunlUtilsLib.xcworkspace -scheme YohunlUtilsLib -sdk iphonesimulator -configuration Debug -showBuildSettings > xcodebuild_showBuildSettings.txt 來將所有的xcode預定義變數都匯入到文字xcodebuild_showBuildSettings.txt 中,然後你就可以選用你需要的啦 當然了,我們一般都應該合併release模式的,而不是debug模式的framework,這個可以在

ccmmand+B 編譯 如果不出錯的話,應該會彈出
到此處,我們的framework建立好了,下面可以建立一個測試工程來測試一下,是否可以了 4)建立一個single View Application的測試上述framework的工程 TestFrameworkDemo 將上一步生成的 Release-universal/YohunlUtilsLib.framework 加入到工程 TestFrameworkDemo 再寫一個測試用例:
執行,這時候,你會收到錯誤提示
還記得前面說過吧,我們打包的framework並不包含 此時,我們有兩種方式解決這個問題:  1. 將我們生成 YohunlUtilsLib.framework 過程中生成的libAFNetworking.a 拷貝過來,新增到工程中(當然了,你要自己合併 libAFNetworking的真機和模擬器的.a檔案) [這種方式的好處是可以保證我們的YohunlUtilsLib.framework使用到的libAFNetworking和我們一樣的版本,保證了相容性,,但同時也增加了整合的複雜性,我們要申明我們的framework用到了哪些第三方和第三方的版本資訊] 2.在TestFrameworkDemo 工程中,增加 podFile檔案,在其中加入 依賴  pod 'AFNetworking'   重新pod install一下 [推薦這種方式,因為,我們用到的第三方都可以使用pod管理,方便],下面就以這種方法來說明
執行,OK!!! 二:使用 pod 的命令  pod lib create 來建立 使用pod的framework 注意:各個版本的cocoapods生成的示例工程結構什麼的,會有點不一樣,比如最新的帶有demo的生成的lib工程就本身就是target的名字,但是之前版本target的名字是 名字_example pod lib create 工程名  使會讓你確認4個問題,由此來建立工程,4個問題都是很簡單的,你可以自行選擇

注意到了沒?這裡我們的 YohunlUtilsPod 目錄下,並沒有podfile檔案,那麼我們建立的庫要怎麼依賴第三方的啊.這裡就是 YohunlUtilsPod.podspec 檔案出場了,在這個檔案中,可以制定我們生成的framework依賴於什麼.有關於spec檔案,是關鍵檔案,原則上,只要我們把這個檔案交給別人,別人就可以新增我們的lib到工程裡了
編輯YohunlUtilsPod.podspec 檔案(此檔案實際上是 ruby格式的,如果你用ruby相關的編輯器開啟,就能高亮顯示了),修改內容為 Pod::Spec.new do |s|
  s.name             = "YohunlUtilsPod"
  s.version          = "1.0.0"
  s.summary          = "
測試pod生成frameworkYohunlUtilsPod."

  s.description      = "
測試用的,我們用來測試使用pod lib create 生成的framework工程"

  s.homepage         = "https://github.com/yohunl/YohunlUtilsPod"
  # s.screenshots     = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
  s.license          = 'MIT'
  s.author           = { "yohunl" => "[email protected]" }
  s.source           = { :git => "https://github.com/yohunl/YohunlUtilsPod.git", :tag => s.version.to_s }

  # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'

  s.platform     = :ios, '7.0'
  s.requires_arc = true

  s.source_files = 'Pod/Classes/**/*'
  s.resource_bundles = {
    'YohunlUtilsPod' => ['Pod/Assets/*.png']
  }

  # s.public_header_files = 'Pod/Classes/**/*.h'
  # s.frameworks = 'UIKit', 'MapKit'
   s.dependency 'AFNetworking'
end  驗證podspec檔案是否正確是使用命令  在podspec所在目錄下執行  pod lib lint
如果提示錯誤的話,它會給出詳細的提示,你照著修改就好了,備註:我已經將原始碼上傳到了github上(你也可以上傳你的私有git伺服器,一般公司都應該有自己的git伺服器) 更改完後,在工程中再加入  YONetwork.h和.YONetwork.m  再執行 pod install   如果提示  SZ-lingdaiping:Example yohunl$ pod install
Updating local specs repositories
Analyzing dependencies
Fetching podspec for `YohunlUtilsPod` from `../`
[!] Unable to satisfy the following requirements:- `YohunlUtilsPod (from `../`)` required by `Podfile`- `YohunlUtilsPod (from `../`)` required by `Podfile` - `YohunlUtilsPod (= 0.1.0)` required by `Podfile.lock` 那麼刪掉  Podfile.lock檔案,因為我們更改了podspec檔案裡的庫的版本號了 看到沒,是在 Development Pods資料夾下,因為並沒有上傳到官方去,所以,在此處是 私有的,所以在Development Pods資料夾下  . 接下來,如同第一個一樣,新增一個新的target,新增 run script指令碼 ,執行它,得到  
建立一個測試工程
注意上面圖裡面的文字,此處因為我們的framework工程採用dynamic 模式的(上文有論述!!!)  所以需要在Embedded Binaries下新增相應的庫.至於為什麼還要新增 AFNetworking.framework,上面也有論述,是因為我們打包的.framework並沒有包含AFNetworking.framework,如果不加上,執行起來,還是要報錯的哦 好了,第一部分講完了 那麼我們怎麼使用 像我們使用其它開源庫那樣的,只要在demo工程裡新增一句 pod ‘YohunlUtilsPod' 然後pod install一下就可以新增呢?(當然了,這種方式,我們一般是直接原始碼模式的framework加入demo工程) 這就是第二部分要講的. 參考文件:

相關推薦

cocoapods應用第一部分-xcode建立.framework相關

問題的提出: 隨著專案的越來越大,可能會出現好幾個團隊共同維護一個專案的情況,例如:專案組A負責其中的A塊,專案組B負責其中的B塊.....這幾塊彼此之間既獨立,也相互聯絡.對於這種情況,可以採用約定的方式,比如,你只修改你那塊,不要修改公共的.如果要修改公共的,那麼必須要

cocoapods應用第一部分-xcode創建.framework相關

all 輸入 一次 oot 不出 模擬 builds bject pos 問題的提出: 隨著項目的越來越大,可能會出現好幾個團隊共同維護一個項目的情況,比如:項目組A負責當中的A塊,項目組B負責當中的B塊.....這幾塊彼此之間既獨立,也相互聯系.對於這樣的情況,

cocoapods應用第二部分-私有庫相關

我們在這裡,使用的是 第一部分使用pod lib create YohunlUtilsPod 建立的framework工程來說明.其建立過程在此就不重複了,當然你也可以下載我已經建立好的demo https://github.com/yohunl/YohunlUti

Xcode應用】使用Xcode除錯framework

使用Xcode除錯framework的方法: 整合生成framework的工程 整合生成framework的工程到主工程中 在主工程中新增對framework的依賴 從生成framework的工程下啟動app 編輯Scheme,指定Executab

Microsoft Azure IoT Hub應用第一部分:向雲端傳送資料

By Toradex Leonardo Graboski Veiga 1). 簡介 物聯網(Internet of Things)概念的本質其實就是關於傳送資料到網路,所以稱為雲服務。隨著時代發展和技術進步,人們可以使用尺寸更小功耗更低的電子裝置並很容易的連線到雲端,不過有

Linux的shell腳本random相關應用和批量修改建立練習

shell腳本random 批量創建用戶和文件一.三種取隨機數並加密的方法1.random的取數並加密取數的方法:取隨機數的方法:取隨機數的並加密的方法:加密後截取不同的位數:2.data時間取隨機數並加密3.openssl取隨機數並加密二.隨機數的應用1.批量創建以隨機數開頭的文件題目1:在/westos目

Django來敲門~第一部分【4. 創建第一個模塊應用

params star 編輯 調用 關聯 配置 poll imp python3 成若缺,其用不弊。大盈若沖,其用不窮。大直若屈。大巧若拙。大辯若訥。靜勝躁,寒勝熱。清靜為天下正 ——老子《道德經》 本章內容 創建應用(app) 開發第一個

Cron 觸發器及相關內容 (第一部分)

我們在上章中有承諾過會花更多時間來講 Quartz 的 CronTrigger,所以不會讓你失望的。SimpleTrigger 對於需要在指定的毫秒處及時執行的作業還是不錯的,但是假如你的作業需要更復雜的執行計劃時,你也就要 CronTrigger 給你提供更強更靈活的功能。一. Cron 的快

第一行程式碼Android》學習總結第二章 Activity建立相關設定

一、id標籤 如果在XML檔案中引用一個id,則使用@id/id_name; 如果在XML檔案中定義一個id,則使用@+id/id_name。 二、程式中設定主活動 在AndroidMaifest.xml中設定 <intent-filter>   

數字影象處理的筆記(一)第一部分:概念和應用領域

影象處理的部分先做一個大概的記錄,後續深入學習後展開。內容圍繞影象的分割和增強展開。 只是相關技術的某些應用,也可能不盡準確,為了記錄和學習。 第一部分:概念和應用領域 第二部分:相關的程式碼實現 ----------------------------針對畫素本身的操作,非

使用Boost::Python在C++應用程式中嵌入Python:第一部分

在本系列教程的簡介中,我說了將Python程式碼整合到Granola程式碼庫中的動機。簡而言之,它可以使我使用Python語言和標準庫的好處來完成在C++中通常很痛苦或笨拙的任務。當然,底線是我不必移植任何已有的C++程式碼。 今天,我們看一下使用boost::pyth

某銀行信用卡中心——大資料反欺詐應用案例 2017-06-23 10:54 本篇案例為資料猿推出的大型“金融大資料主題策劃”活動(檢視詳情)第一部分的系列案例/徵文;感謝 百融金服 的投遞 作為整體

某銀行信用卡中心——大資料反欺詐應用案例 2017-06-23 10:54 本篇案例為資料猿推出的大型“金融大資料主題策劃”活動(檢視詳情)第一部分的系列案例/徵文;感謝 百融金服 的投遞 作為整體活動的第二部分,2017年6月29日,由資料猿主辦,上海金融

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

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

yii開發第一部分之執行流程

soap active def 情況 bug 控制 actions 時也 哈希 一 目錄文件 |-framework 框架核心庫 |--base 底層類庫文件夾,包含CApplication(應用類,負責全局的用戶請求處理,它管理的應用

【Linux探索之旅】第一部分第三課:測試並安裝Ubuntu

u盤 nco 過程 sans ubunt windows u盤啟動盤 系統 .com 內容簡單介紹 1、第一部分第三課:測試並安裝Ubuntu 2、第一部分第四課預告:磁盤分區 測試並安裝Ubuntu 大家好,經過前兩個比較偏理論(是否

PYTHON學習---第一部分

編碼格式 love 算數 存在 是我 tin exec 進行 finally 第一個程序 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # Author:xll 4 print("Hello World!") 在

C語言——第一部分 C語言概述以及編程基礎

編程語言 c語言 C語言 第一部分 編程基礎 1.通過”語言“來控制計算機,讓計算機為我們做事情,這樣的語言就叫做編程語言(Programming Language)。2.編程語言也有固定的格式和詞匯,例如:編程語言有很多種,常用的有C語言、C++、Java、C#、PHP、JavaScript等,每種

UNIX網絡編程-第一部分(簡介)-筆錄

unix網絡編程第一部分-簡介 緒論:10000小時定律已成,現今將之前所學知識溫顧,所學所感所想記錄第一話:1.在學習軟件編程的時候,我們第一步是先學會一門語言,然後實現一個小模塊(封裝成類,函數等),來完成某個具體功能或解決某個具體問題。然後在參與真正項目的時候,往往涉及到大量的封裝,模塊與模塊之間的如何

Linux內核中網絡數據包的接收-第一部分 概念和框架

csdn 請求 版本號 post sched nec alloc nts 多核cpu 與網絡數據包的發送不同,網絡收包是異步的的。由於你不確定誰會在什麽時候突然發一個網絡包給你。因此這個網絡收包邏輯事實上包括兩件事:1.數據包到來後的通知2.收到通知並從數據包中獲取數據

css3 選擇器 權重問題 (第一部分

top 例子 checked ont css3 訪問 關鍵字 att border 其實我現在寫的這些博文筆記都是我很早之前學習的時候所寫的筆記,只不過之前是沒有寫博客的習慣,所以都是寫在word文檔中個人需要的時候看而已。最近剛剛開了博客,所以想將自己的筆記貼到博客。