iOS SDK封裝Framework帶資源文件封裝

前言

  • 製做SDK封裝Framework帶資源文件封裝

1、新建主項目

主項目的ProjectName是HelloFramework( SDK的主項目 )markdown

2、建立Framework

在主項目裏建立Framework,暫時命名MyFramework架構

Project - > Editor - > Add Larget - > Cocoa Touch Frameworkapp

1.png

3、配置Framework信息

一、Architectures 配置支持的指令集

  • Project - > Target - > MyFramework - > Build Settings
  • Architectures配置支持的指令集,增長arm64e、armv7s

以下:框架

2.png

備註:系統已經默認配置了 arm6四、armv7iphone

指令集 支持設備設備
armv6 iPhone、iPhone 3G、iPod 1G、iPod 2G
armv7 iPhone 3GS、iPhone 四、iPod 3G、iPod 4G、iPod 5G、iPad、iPad 二、iPad 三、iPad Mini
armv7s iPhone 五、iPhone 5C、iPad 4
arm64 iPhone 5s、iPhone 六、iPhone 6P、 iPhone 6s、 iPhone 6sP、 iPhone 七、iPhone 7P、iPad Air、Retina iPad Mini
arm64e iPhone XR、iPhone XS Max

二、Build Active Architecture Only修改成NO,不然生成的靜態庫就只支持當前選擇設備的架構。

Build Active Architecture Only 修改成 NOide

三、Mach-O Type 選擇是Static Library(靜態庫)仍是Dynamic Library(動態庫默認)

Mach-O Type 設置爲 Static Library(靜態庫)oop

備註:使用動態庫要注意須要在 Linked Frameworks and Libraries 和 Embedded Binaries 都加入對應的動態庫。ui

以下:atom

3.png

四、設置Headers Phase

步驟:Target - > MyFramework - > Build Phases - > Headersspa

  • Public:須要暴露出來的 h 文件
  • Private:不想公開的 h 文件
  • Project:顯示你MyFramework裏面的全部你建立的 h 文件

5.png

五、設置最低兼容版本

以下:

4.png

六、新建一個FrameworkManager文件

在FrameworkManager類裏實現了一個方法

//.h文件聲明
#import <Foundation/Foundation.h>

@interface MyFrameworkManager : NSObject

+ (UIViewController*)creatFrameworkFileViewController;

@end
複製代碼
//.m文件實現
#import "MyFrameworkManager.h"
#import "FrameworkFileViewController.h"

@implementation MyFrameworkManager

+ (UIViewController*)creatFrameworkFileViewController{
    FrameworkFileViewController *vc = [[FrameworkFileViewController alloc] initWithNibName:GetNibName(@"FrameworkFileViewController") bundle:[NSBundle mainBundle]];
    
    NSLog(@"subviews:%@",vc.view.subviews);
    return vc;
}
@end
複製代碼

七、引入頭文件

默認生成的.h文件中,個人是MyFramework.h,把全部須要暴露的.h文件都用#import 引入,記住必定要將全部須要暴露的.h文件都引入,也就是上面Headers-Public中加的全部.h文件,否則編譯後生成的.framework在引用的時候會有警告。 以下:

4.png

八、回到主項目,引用MyFrameworkManager

/// 引入頭文件
#import <MyFramework/MyFramework.h>

// 主項目當中
UIViewController *vc = [MyFrameworkManager creatFrameworkFileViewController];
複製代碼

九、生成Framework包

打包Framework:分爲真機和模擬器,這兩個生成的framework是不同的。(若是說你須要生成一個既能夠真機使用又能夠模擬器使用的,那就分別生成,最後在合併在一塊兒)。按照下圖將編譯的 Device 選擇爲真機 ,而後按下 Command + B 開始編譯,編譯成功後右鍵 Products 文件夾下的 .framework 文件,點擊 Show in Finder。

4、xib文件和圖片的存放和引用

友情提示:資源文件都放在Bundle文件當中,若是放在Framework文件當中,後面打包上傳的時候會出現Found an unexpected Mach-O header code: 0x72613c21

建立bundle,放置資源文件(nib文件,圖片)

一、新建一個bundle文件,這裏暫時命名爲KJFramework.bundle

以下:

6.png

二、顯示包內容,將圖片等資源放入bundle文件當中

以下:

7.png

第一種編譯成nib文件

一、將xib文件編譯成nib文件

8.png

  • 打開終端:cd 須要轉換的xib目錄
  • 輸入編譯:ibtool --errors --warnings --output-format human-readable-text --compile ibtool --errors --warnings --output-format human-readable-text --compile FrameworkFileViewController.nib FrameworkFileViewController.xib

編譯完成會生成以下文件:

9.png

第二種生成nib文件

一、編譯文件,Command + B 生成Framework文件

5.png

二、Show in Finder Framework文件,從中找到一個FrameworkFileViewController.nib文件

備註:一旦xib文件發生變化,就須要從新編譯nib文件,而後替換

三、讀取bundle資源包中的圖片

把Bundle文件導入到咱們的framework中,咱們用到圖片的時候,就取Bundle中的圖片來用。

//FrameworkFileViewController.m文件實現
#import "FrameworkFileViewController.h"

@interface FrameworkFileViewController ()

@property (unsafe_unretained, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation FrameworkFileViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.imageView.image = [UIImage imageNamed:GetBundleImage(@"tiaotiaosu")];
}

- (IBAction)changeImage:(UIButton *)sender {
    if (_imageView.highlighted) {
        self.imageView.image = [UIImage imageNamed:GetBundleImage(@"jienigui")];
    }else{
        self.imageView.highlightedImage = [UIImage imageNamed:GetBundleImage(@"kabisou")];
    }
    self.imageView.highlighted = !self.imageView.highlighted;
}

- (IBAction)dismiss:(UIButton *)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}
@end
複製代碼

5、引入第三方庫

一、pod時候選擇Framework文件

3.png

二、使用Framework文件的時候,一樣須要引入所需的第三方庫

6、Framework 的導出與文檔

一、切換到 Release 模式

Product --> Edit Scheme --> Build Configuration

6.png

二、導出 Framework

(1)在 Target 爲 MyFramework 下,選擇模擬器和Generic iOS Device各自 Command + B 一次
(2)在工程目錄 Products 下 -> 右擊 Framework -> Show in Finder,會看到有兩個文件夾,一個是真機包,一個是模擬器包。

  • 真機包:Release-iphoneos
  • 模擬機包:Release-iphonesimulator

查看包所支持框架:lipo -info 路徑/MyFramework.framework/MyFramework

1.png

armv7 arm64 armv7s arm64e 說明是真機

i386 x86_64 說明是模擬機

(3)將合成的MyFramework 包替換其中的一個,而後這個 MyFramework.framework就是咱們須要

合併:lipo -create 真機路徑/MyFramework.framework/MyFramework 模擬器路徑/MyFramework.framework/MyFramework -output 真機路徑/MyFramework.framework/MyFramework

再次查看包支持框架:兩者均在,說明合併成功

2.png

友情提示:實踐證實弄模擬機的i38六、x86_64沒有什麼用處,並且後面上傳時候還會報錯,讓你剔除這兩框架。

7、Bug總結

一、error: Invalid bitcode signature

clang: error: linker command failed with exit code 1 (use -v to see invocation)

1.png

  • 緣由:Deployment Target 版本低於Framework要求的最低版本
  • 解決方案:修改 Deployment Target 版本

二、Could not load NIB in bundle

2.png

  • 緣由:加載NIB時候未找到文件
  • 解決方案:

Targets -> Build Phases -> Link Binary With Libraries、Copy Bundle Resources 處都加上引入的Framework文件

1.png

三、ld: symbol(s) not found for architecture x86_64

  • 緣由:Framework文件框架當中缺乏x86_64,也就是模擬機框架
  • 解決方案:本人出現緣由是由於,我只合成了真機的Framework文件,因此在模擬機跑的時候報缺乏框架,可是在真機上能夠正常運行。
  • 生成模擬機Framework文件和真機Framework文件,而後將兩個文件合成。

四、ld: symbol(s) not found for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation) 2.png

  • 緣由:未引入所需的三方庫
  • 解決方案:pod 須要的三方庫

從圖能夠看出缺乏 MJRefresh 和 CHTCollectionViewWaterfallLayout

五、All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture armv7

工程中引入的第三方靜態庫真機調試沒有問題,打包的時候報錯 1.png

  • 緣由:第三方庫不兼容 XCode7later 以後默認開啓 BitCode
  • 解決方案:
  • 第一種:更新Framework文件使包含 Bitcode(armv7)。
  • 第二種:選擇工程,在 Build Settings 中,把 ENABLE_BITCODE 設置爲NO

2.png

六、Found an unexpected Mach-O header code: 0x72613c21

打好包以後上傳時候出現錯誤!!!

  • 第一種緣由:Framework是一個Static Library,我把他添加在Embedded Binaries裏面了。

  • 解決方案:

  • 第一種:從 Embedded Binaries(動態庫裏來文件)中刪除靜態Framework文件(KJFramework.framework)可是你直接刪除會發現下面 Linked Frameworks and Libraries(簽署了框架和庫)中 Framework 文件也沒了。這是須要從新往 Linked Frameworks and Libraries 裏添加剛剛被刪除的Framework文件。

  • 第二種:從新將Framework文件封裝成Dynamic Library(動態庫),使用動態庫要注意須要在 Linked Frameworks and Libraries 和 Embedded Binaries 都加入對應的動態庫。


  • 第二種緣由:把Framework文件添加到了 Copy Bundle Resources當中
  • 解決方案:從 Copy Bundle Resources 中將Framework文件刪除,這是你可能會出現,加載不出來你封裝在Framework文件當中的資源文件,所以你須要把資源文件單獨提煉出來用 Bundle 來裝。

七、dyld: Library not loaded: @rpath/KJFramework.framework/KJFramework

4.png

  • 緣由:
  • 解決方案:此處加上Framework文件便可

2.png

八、"Unsupported Architectures. The executable for yht.temp_caseinsensitive_rename.app/Frameworks/VideoCore.framework contains unsupported architectures '[x86_64, i386]'."

55.png

  • 緣由:說明自建的這個SDK裏面包含了x86_6四、i386 架構,固然這個AppStore是不容許的
  • 解決方案:剔除掉x86_64, i386這兩個架構
  • TARGETS -> Build Phases -> 點擊加號選擇 New Run Script Phase -> 而後複製粘貼下面代碼

6.png

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"  
      
    # This script loops through the frameworks embedded in the application and  
    # removes unused architectures.  
    find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK  
    do  
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)  
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"  
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"  
      
    EXTRACTED_ARCHS=()  
      
    for ARCH in $ARCHS  
    do  
    echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"  
    lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"  
    EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")  
    done  
      
    echo "Merging extracted architectures: ${ARCHS}"  
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"  
    rm "${EXTRACTED_ARCHS[@]}"  
      
    echo "Replacing original executable with thinned version"  
    rm "$FRAMEWORK_EXECUTABLE_PATH"  
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"  
      
    done  
複製代碼
相關文章
相關標籤/搜索