一、Framework與.a基礎
此處等下一期
二、工程嵌套聯調靜態庫
1、新建一個主工程
2、新建一個Library工程
3、將靜態庫工程拖到主工程文件夾下
如果你要拖到其他目錄,就要改Library Search Paths
4、將Library工程下.a文件拖入主工程的Link Binary With Libraries
image.png
如果有必要(運行時崩潰),將靜態庫需要加入 Embedded Binaries 中
image.png
5. 主工程添加對子工程的依賴,避免每次修改都要手動編譯子工程
如下圖給主工程添加對子工程的依賴,這樣每次編譯主工程的時候也會編譯子工程。
image.png
三、在靜態庫中使用圖片以及 xib 等資源文件
1、添加 Bundle Target
image.png
因為iOS框架中沒有bundle,要選中OS X框架找到bundle,如下圖
image.png
2、將資源文件加入 bundle 中
將工程中的資源文件都加入到剛剛建的bundle中,如xib、圖片。點+號或直接拖都行。
image.png
3、iOS Deployment Target改為你支持的最低版本
image.png
4、設置base SDK 為latest iOS
image.png
5、編譯 Bundle
image.png
6、主工程添加對子工程的依賴,避免每次修改都要手動編譯子工程
image.png
7、加載 Bundle 里的資源文件
7.1、加載圖片
使用運行時替換 [UIImage imageNamed:]
方法,減少修改代碼的工作量。
相關代碼在以下幾個類中
image.png
// 在AppDelegate中執行以下代碼即可swizzle 所有 [UIImage imageNamed:]
#import "UIImage+Swizzle.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[UIImage kk_autoLoadImageInBundle];
return YES;
}
- UIImage+Swizzle.m
//
// 修改所有的 [UIImage imageNamed:]的實現,改為先從同一項目中的 .bundle 文件中加載,沒有再使用系統默認實現加載
+ (void)kk_autoLoadImageInBundle {
SEL original = @selector(imageNamed:);
SEL new = @selector(hook_kk_imageWithName:);
[self kk_swizzleClassMethod:original with:new];
}
// 1. 從 .bundle 中加載圖片
// 2. 按照默認的方法加載圖片
+ (instancetype)hook_kk_imageWithName:(NSString *)imageName {
UIImage *image = [NSBundle kk_imageInBundle:kk_BundleName imageName:imageName];
if (!image) {
image = [self hook_kk_imageWithName:imageName];
}
return image;
}
- NSObject+Swizzle.m
#import "NSObject+Swizzle.h"
#import <objc/objc.h>
#import <objc/runtime.h>
@implementation NSObject (Swizzle)
+ (BOOL)kk_swizzleInstanceMethod:(SEL)originalSel with:(SEL)newSel {
Class class = object_getClass(self);
Method originalMethod = class_getInstanceMethod(class, originalSel);
Method newMethod = class_getInstanceMethod(class, newSel);
if (!originalMethod || !newMethod) return NO;
method_exchangeImplementations(originalMethod, newMethod);
return YES;
}
+ (BOOL)kk_swizzleClassMethod:(SEL)originalSel with:(SEL)newSel {
Class class = object_getClass(self);
Method originalMethod = class_getClassMethod(class, originalSel);
Method newMethod = class_getClassMethod(class, newSel);
if (!originalMethod || !newMethod) return NO;
method_exchangeImplementations(originalMethod, newMethod);
return YES;
}
@end
7.2、加載 xib
7.2.1 加載xib對應的UIViewController
需要重寫xib對應控制器的 init 方法,否則可能出現找不到xib文件導致crash
參考bundle打包xib文件
- (instancetype)init {
NSBundle *bundle = [NSBundle kk_bundleWithName:kBundleTargetName];
self = [super initWithNibName:@"CalculatePriceViewController" bundle:bundle];
return self;
}
代碼參見:github](https://github.com/action456789/SKS_Collection/blob/master/SKS_Collection/Classes/Category/Framework開發/NSBundle%2BResource.h))
7.2.1 加載xib對應的UIVIew
需要重寫xib對應View的 init 方法,,否則可能出現找不到xib文件導致crash
@implementation OfflineView
//重寫要加載的view的init方法
- (instancetype)init {
if (self = [super init]) {
NSBundle *bundle = [NSBundle kk_bundleWithName:kk_BundleName];
self = [[bundle loadNibNamed:@"OfflineView" owner:self options:nil] lastObject];
}
return self;
}
@end
7.3、加載 Localizable.strings
第一步:在Bundle中新建國際化文件
image.png
第二步:添加語言,并將之前的國際化文件中的代碼復制過來
image.png
第三步:
使用 NSBundle+Resource 如下方法
+ (NSString *)mj_localizedStringForKey:(NSString *)key;
+ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value;
然后使用如下宏定義
// 加載 Bundle 中的國際化語句
#undef NSLocalizedString
#define NSLocalizedString(key, comment) \
[NSBundle mj_localizedStringForKey:(key)]
然后就可以自動的加載Bundle中的字符串了
四、將整個App打包為Framework
需要注意的地方
- 整個項目都要解除 AppDelegate 的依賴,AppDelegate不能打入Framework中
- 圖片和xib文件需要按照 三 中的處理
- 可以使用 runtime 動態加載圖片和xib文件,減少工作量
- 注意點:bundle中的國際化文件需要重新新建,添加語言,然后將之前App中的內容復制過來,直接拖進去是無效的
image.png
實際操作中存在的問題
- 圖片同時存在@2x和@3x后綴導致加載的圖片為nil的問題
解決辦法為只要@2x的圖片
五、使用 appledoc
生成文檔
- 安裝
brew install appledoc
- 查看版本
appledoc --version
- 查看幫助
appledoc --help
- 生成文檔
appledoc --output ./doc --project-name "D103Framework" --project-company "RICISUNG" --company-id "RICISUNG" .
”.“ 和前面的符號一定要加 空格 否則就會報錯。
image.png