环境
macOS Catalina Version 10.15 (19A583) Xcode Version 11.x
framework文件
创建framework工程,新建NManager.swift文件,内容:1
2
3
4
5
6
7
8
9
10
11
12import UIKit
@objc class NManager: NSObject {
@objc public func sayHello() {
print("hello")
}
public func sayWorld() {
print("world")
}
@objc func saySwift() {
print("swift")
}
}
问题:编译出现 symbol dyld_stub_binder not found (normally in libSystem.dylib).
解决:工程中的 Link Binary With Libraries -> 加上libSystem.tbd
新建swift语言工程调用
add framework文件
主要代码1
2
3
4import someFramework
let manager = NManager()
manager.sayHello()
manager.sayWorld()
新建oc语言工程调用
add framework文件添加到工程中,注意选择项选中Copy items if needed
主要代码1
2
3#import <someFramework/someFramework-Swift.h>
NManager *manager = [NManager new];
[manager sayHello];
问题:编译出现 image not found
解决:在工程Target中的 General -> Frameworks,Libraries,and Embedded Content中将 Embed 改为 Embed Without Signing 或 Embed & Sign 皆可以
target方式引入Framework
新建项目引入(看上面)
(下面是)target方式引入
我们把原先的添加了的framework先丢掉,左上角 File -> save as workspace
关闭这个.xcodeproj 文件重新打开这个 .xcworkspace
将我们的 Framework 项目 拖到 workspace 中,与 App的target 并行
问题:会遇到拖进来的项目没有被正确的识别出来,也没有多出来一个target
解决:关掉xcode其它已打开的所有工程项目,保持只留下当前一个项目运行,然后再重新拖项目或重启xcode只打开这一个项目,试试,以后运行,也只保持这一个项目运行,具体原因可能和xcode有关
这个时候就会发现,我们就有两个项目了可以分别 build 了
到 App 中 工程文件 -> General ->embedded binaries 中将 Framework 下的 .framework 加进来
试一试,scheme 选择 App, build 一下是success,
我们再来到我们的 XPManager.h ,添加几行代码(当测试)
当然还是先build一下我们的XPKit,否则Demo里的framework不更新呐
可以直接在项目里用。那么边写边测,还能设断点,完美~跟平时写app没两样
当你调用并且运行,发现又报错了
且这次我们已经加到 Embedded Binaries 中了,原因是,如果我们在OC项目中引用swift framework,还需要到 build setting 中设置如下: Always Embed Swift Standard Libraries 确认为 Yes
到此为止才是真正完美 ~
另外: Framework因为真机和模拟器的原因,需要两次编译并lipo -create的方式合并,麻烦
用Shell脚本创建通用包
创建通用包用到的次数不多,上面的方法够用了,但是如果你还是觉得不方便、很繁琐。那你可以跟我这样做
选择XPKit 工程点击左下角 +
创建一个 Aggregate 。去个名字,类似 CommonBuilder
image.png
选中 CommonBuilder -> Build Phases -> 添加New Run Script Phase
在编辑器内输入我们的脚本代码,请全部复制,黏贴,记得修改第二步引号内的内容为你的framework name1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39# Merge Script
# 1
# Set bash script to exit immediately if any commands fail.
set -e
# 2
# Setup some constants for use later on.
FRAMEWORK_NAME="Your framework name"
# 3
# If remnants from a previous build exist, delete them.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
# 4
# Build the framework for device and for simulator (using
# all needed architectures).
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch arm64 -arch armv7 -arch armv7s only_active_arch=no defines_module=yes -sdk "iphoneos"
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch x86_64 -arch i386 only_active_arch=no defines_module=yes -sdk "iphonesimulator"
# 5
# Remove .framework file if exists on Desktop from previous run.
if [ -d "${HOME}/Desktop/${FRAMEWORK_NAME}.framework" ]; then
rm -rf "${HOME}/Desktop/${FRAMEWORK_NAME}.framework"
fi
# 6
# Copy the device version of framework to Desktop.
cp -r "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework" "${HOME}/Desktop/${FRAMEWORK_NAME}.framework"
# 7
# Replace the framework executable within the framework with
# a new version created by merging the device and simulator
# frameworks' executables with lipo.
lipo -create -output "${HOME}/Desktop/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"
# 8
# Copy the Swift module mappings for the simulator into the
# framework. The device mappings already exist from step 6.
cp -r "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${HOME}/Desktop/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule"
# 9
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi
如图:
scheme 选择 CommonBuilder,任意模拟器,编译,报错了看看报了什么错
Command /bin/sh failed with exit code 65
你们以后看到这些不用慌,网上看,信息都在上面
=== BUILD TARGET XPKit OF PROJECT XPKit WITH CONFIGURATION Release ===
Check dependencies
No architectures to compile for (ARCHS=x86_64 i386, VALID_ARCHS=arm64 armv7 armv7s).
BUILD FAILED
分析一下,这里都是我们提到过的指令集。 VALID_ARCHS=arm64 armv7 armv7s 这就是我们开始在 Build Setting ->Valid Architectures 中设置的内容,很明显,意思是脚本里,要制作包含 x86_64 和 i386的包,但是我们的Valid Architectures 中没有。
那么解决问题就方便了,分别添加x86_64 和 i386
出错: iOS 13 does not support 32-bit programs
解决:把编译选项里的 Build Active Architecture Only 设为 No, 同时将 Valid Architectures 只设为 arm64,arm64e,x86_64,将arm7,arm7s删掉,同时将上面的编译脚本中的arm7,arm7s也要删掉
编译成功~
来到桌面我们发现XPKit.framework,已经静悄悄的在桌面上了,这就是我们的通用包