組件化之路---Swift如何創建Framework(1)

動態庫與靜態庫

什么是靜態庫

靜態庫(Static Library),可以將它理解為一個二進制文件,通過公共的 .h 文件,可以獲取到 .a 中暴露的方法或者屬性等。在最后編譯 APP 的時候.a 將被鏈接到最終的可執行文件中,由于不能控制加載的方式和時機,所以稱為靜態庫

什么是動態庫

動態庫(Dynamic Framework), 在 iOS 系統的框架是以 .framework 結尾的,就是動態框架。Framework 其實是一個 bundle,也可以理解為是一個特殊的文件夾。系統的 framework 是存在于系統內部,而不會打包進 APP 中,這可以保證 app 啟動速度。相比靜態庫,使用起來很方便。

靜態庫和動態庫的區別

靜態庫和動態庫區別主要體現在編譯和運行時期,在編譯APP的時候靜態庫的.a文件就會被鏈接到可執行文件當中去,從一定程度上來講靜態庫也會增加包的大??;
動態庫在編譯時并不會編譯到可執行文件當中,而是在程序運行的過程當中使用到了動態庫才會進行載入

創建并配置Framework

創建Framework
創建Framework.png
配置Framework
  • 動態&靜態庫選擇


    庫類型.png
  • 支持的版本


    設置支持.png
  • 創建bundle文件


    資源文件.png
構建API
  • 示例API構建

JJXConst.swift文件

import Foundation

public let JJX_SDK_Version = "0.3.1";

JJXSDKInfo.swift文件

import Foundation


public class JJXSDKInfo: NSObject {
    public func fetchSDKVersion() -> String {
        return JJX_SDK_Version
    }
}

JJXSDKManager.swift文件

import UIKit

public class JJXSDKManager: NSObject {
    
    public static let sharedInstance = JJXSDKManager()
    //版本信息
    public let sdkInfo: JJXSDKInfo

    //MARK: private
    private override init() {
        sdkInfo = JJXSDKInfo.init()
    }
}

  • 暴露swift文件
    為何此處會選擇暴露swift文件?
    如果我們僅僅是將API編寫完成,然后編譯成Framework,將其拖入到其他工程當中進行使用,是可以選擇不在此處暴露swift文件的。后續在使用Cocoapods將Framework進行發布的時候發現如果不將swift文件進行暴露,庫就無法正常的進行使用。(目前其中的原因還不太了解,后續再繼續查找相關的資料進行補充,此處如果理解不正確還請大家指教?。。。?/p>

    swift文件.png

如何對Framework提供的API進行測試

測試Framework的方法
  • 方法一:編譯出Framework,拖入其他測試工程中進行API的測試
  • 方法二:創建依賴的測試工程,進行API的測試

兩種方法都是可以對API進行測試的,此處是不推薦使用方法一,如果編譯成Framework拖入其他工程進行測試,那么在測試的過程中如果發現API有問題,并不能夠很好的對問題進行定位,所以更加推薦方法二,使用依賴工程的方式,可以很方便的在API中打斷點進行問題定位,也更利于對庫進行代碼上的修改

創建依賴測試工程

使用Xcode新建一個工程,隨便起一個名字,比如JJXSDKExample

將Framework工程嵌入到測試工程中
  • 將SDK項目工程拖入到測試工程目錄中,如圖所示


    目錄移動.png
  • 在測試工程中導入SDK項目工程,如圖所示


    SDK工程導入.png
編譯運行測試
  • 編譯SDK
    在編寫測試工程代碼時,需要先對 JJXSDKDemo進行編譯,才會在上圖中生成對應的JJXSDKDemo.framework文件,右擊"JJXSDKDemo.framework",選擇"show in finder" 可以查看到編譯生成的Framework具體地址。如果修改了SDK工程的代碼,需要對SDK進行重新的編譯

  • 測試SDK API

import UIKit
import JJXSDKDemo

class ViewController: UIViewController {
    
    var sdk : JJXSDKManager?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        sdk = JJXSDKManager.sharedInstance
        print(sdk?.sdkInfo.fetchSDKVersion() ?? "---")
    }
}

到此,關于動態庫的創建以及測試就完成了。在最后,我們需要掌握如何對動態庫CPU的架構進行合并,讓庫既能夠在模擬器上使用,同時也可以在真機上使用

如何編譯出真機和模擬器都支持的CPU架構

模擬器

i386:適合在32位上的模擬器使用
x86_64:適合在64位上的模擬器進行使用

真機

arm7:適合于支持ios7上的設備使用
arm7s:適用于iphon5 和iphone 5c使用
arm64:在64位處理器上使用

CPU架構合并
  • 新建Target : File --- New --- Target


    菜單.png
  • 選擇Aggregate


    Aggregate.png
  • 創建script


    script.png
  • 編寫腳本文件

以范例中的腳本內容為例,具體PROJECT_NAME的值根據自己的需求進行命名

#!/bin/sh

# make configuration name
# CONFIGURATION_NAME = "ReleaseJJXSDKDemo"

#universal output folder
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# make frame name
PROJECT_NAME = "JJXSDKDemo"

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

# make sure the output directory exists
rm -rf "${UNIVERSAL_OUTPUTFOLDER}"
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# 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 "${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}" 

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

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


  • 修改為Release版本


    Edit Scheme.png
debug修改為release.png

最后,運行UniversalSDKDemo,便可編譯出同時具有模擬器和真機架構的Framework

寫在最后:組件化之路---通過cocoapods進行動態庫的發布及維護

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容