Xcode10 創建 framework (Objective-c),bundle(包含xib、image),第三方庫,使用報錯


一、生成部分

參考:http://www.cocoachina.com/ios/20150127/11022.html

https://www.jianshu.com/p/87dbf57cfe4a (里面的腳本有問題,我參考另一篇文章做了修改)

https://www.jianshu.com/p/ef3d5b7e7006?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=qq

https://ask.csdn.net/questions/701924

1.打開Xcode,新建Project。類型:Cocoa Touch Framework,language:Objective-c。

生成項目后記得把Deployment Target調到需要的最低支持的iOS版本

2.隨便建建一個類Converter,寫一個HelloWorld函數。

Converter.h里聲明函數

+(void)helloWorld;

 Converter.m里實現函數

+(void)helloWorld {
    NSLog(@"Hello World");
}

並且在LYFHelloWorld.h(建工程時候系統自動生成的)里聲明所有要公開的頭文件,以便將來使用這個庫時可以引用

 3.·將你要公開的頭文件移動到Public下,要隱藏的放在Private或者Project下

·如果有xib和圖片資源,不要把它們加到Copy Bundle Resource里。(如果已經加了,就移除,因為就算添加了也無法使用。)

因為后面會把它們整合到一個LYFHelloWorldResource.bundle里,所以先提前修改所有使用image和xib的代碼,在名字前加將要創建的bundle的名字:"LYFHelloWorldResource.bundle/"。如果xib里面用到了圖片,把圖片名字前也加上"LYFHelloWorldResource.bundle/",這樣會導致圖片不顯示,但是另一個項目使用這個framework時候路徑是對的。

//因為后面會把資源放到LYFHelloWorldResource.bundle里
//[UIImage imageNamed:@"IMG_0799.jpg"],就算圖片在Assets.xcassets里,圖片名要帶后綴例如".jpg",因為要把Assets.xcassets里的圖片都移到bundle里。
[UIImage imageNamed:@"LYFHelloWorldResource.bundle/IMG_0799.jpg"]
// [[NSBundle mainBundle] loadNibNamed:@"LYFShowView" owner:self options:nil].firstObject
[[NSBundle mainBundle] loadNibNamed:@"LYFHelloWorldResource.bundle/LYFShowView" owner:self options:nil].firstObject

 

4.修改配置。

前兩個自己不理解(https://my.oschina.net/Jerod/blog/756465),試驗了一下沒什么大問題,所以沒做修改。

第三個不改的話,別人用你的庫會閃退報錯:Reason: image not found

5.增加armv7s。(如果不需要支持iPhone5,5C,就可以跳過這一步)

    • arm7: 在最老的支持iOS7的設備上使用

    • arm7s: 在iPhone5和5C上使用

    • arm64: 運行於iPhone5S的64位 ARM 處理器 上

    • i386: 32位模擬器上使用

    • x86_64: 64為模擬器上使用

8.選擇需要編譯release或debug

這時候

選中模擬器編譯,可以生成可在模擬器中用的庫,(如果在終端lipo -info  ....../LYFHelloWorld.framework/LYFHelloWorld,結果是: x86_64)

選中Generic iOS Device編譯,可以生產可在真機中使用的庫,(如果 lipo -info 這個,結果是:armv7 arm64 armv7s)

如果要生成模擬器和真機都可以用的庫,(即lipo -info結果是:i386 armv7 armv7s x86_64 arm64)。

有兩種辦法

(1)·命令行合並兩個庫

#lipo -create 模擬器庫 真機庫  -output 新地址/庫名
lipo -create /Users/yongfaliu/Library/Developer/Xcode/DerivedData/LYFHelloWorld-cwlpmormfoqzfvctlyefrysrtqux/Build/Products/Debug-iphonesimulator/LYFHelloWorld.framework/LYFHelloWorld /Users/yongfaliu/Library/Developer/Xcode/DerivedData/LYFHelloWorld-cwlpmormfoqzfvctlyefrysrtqux/Build/Products/Debug-iphoneos/LYFHelloWorld.framework/LYFHelloWorld -output /Users/yongfaliu/Desktop/new/LYFHelloWorld

 

·用生產的新庫替換原來的任何一個。被替換二進制文件的FrameWork就同時可以在模擬器和真機上使用

(2).在Xcode內完成

·新建Aggregate

·為新建的Target添加腳本

·很早以前的腳本在新環境下最后生成的庫大小為0kb,這是新的。

#!/bin/sh
#要build的target名
TARGET_NAME=${PROJECT_NAME}
if [[ $1 ]]
then
TARGET_NAME=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products/"

#創建輸出目錄,並刪除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework"

#分別編譯模擬器和真機的Framework
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

#拷貝framework到univer目錄
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}"

#合並framework,輸出最終的framework到build目錄
lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"

#刪除編譯之后生成的無關的配置文件
dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/"
for file in ls $dir_path
do
if [[ ${file} =~ ".xcconfig" ]]
then
rm -f "${dir_path}/${file}"
fi
done

#判斷build文件夾是否存在,存在則刪除
if [ -d "${SRCROOT}/build" ]
then
rm -rf "${SRCROOT}/build"
fi

rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"

#打開合並后的文件夾
open "${UNIVERSAL_OUTPUT_FOLDER}"

·然后Edite Scheme里選擇需要編譯release或debug,選最新的Target編譯,新的庫最后會在彈出的Finder里

9.將庫拖到新的工程里就可以使用。當然要聲明頭文件。

10.如果有代碼里用到了image和xib文件,還要創建bundle文件。

·這里命名為"LYFHelloWorldResource.bundle"(第3步里提到過)。修改Deployment Target的最低支持iOS版本和選擇release或debug。

·修改配置。第一個是因為bundle默認是macOS的,第二個不改編譯會報錯,第三個不改圖片格式是tiff

·將image和xib添加到Copy Bundle Resource里,將Assets.xcassets里的圖片拖出來直接放到到項目里,然后也添加到Copy Bundle Resource里面。

 

·選擇bundle編譯之后。像framework一樣,拖到新工程里就可以了。

11.如果用到了第三方庫,就最好用pod管理。像正常項目一樣,初始化pod,添加第三方庫,然后編譯出framework。使用這個framework的新項目也要在pod中添加相同的第三方庫。這樣兩邊都能夠正常運行。

二、使用報錯

參考:https://blog.csdn.net/u012243474/article/details/52619344

https://www.jianshu.com/p/0e2f6afa43dd

https://developer.apple.com/library/archive/qa/qa1490/_index.html

1.使用庫的時候報:Reason: image not found

將生成庫的target里的Build Settings里的Mach-O Type修改為Static Library,重新生成庫

2.使用庫的時候報:unrecognized selector sent to

因為庫里有分類,使用庫的時候,調用分類的方法就會這樣報錯,要修改使用庫的項目的鏈接配置。

(1)如果只有分類,把Build Settings里的Other Linker Flags修改為-ObjC;

(2)如果庫里同時有類和分類,把Build Settings里的Other Linker Flags修改為:(第二個可以把庫拖進去,再添加"/庫名")

-force_load

 $(SRCROOT)/XXXXX/framework/Debug/XXXXX.framework/XXXXX

3.使用庫的時候,編譯報:ld: symbol(s) not found for architecture

因為庫用到了第三方庫,而使用庫的項目沒有。把需要的第三方庫添加進來


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM