一、问题由来
在将Swift代码打包成Framework的时候遇到个问题:
我有一个公开类MyClass
,这个类遵从了一个公开协议PublicProtocol
,代码如下:
// 这是一个不能更改访问控制的系统/第三方公开协议,你无法改成internal之类的
public protocol PublicProtocol {
public func publicFunction()
}
------------以上割掉----------------
// 这是我的公开类
public class MyClass {
// 这里有很多属性、方法
}
// 让这个类遵从上面的协议
extension class MyClass: PublicProtocol {
public func publicFunction() {
print("i am doing something")
}
}
- 编译生成Framework
- import模块
- cmd+click进入模块接口(不是.h文件哦)
- 你能看到接口大致如下:
// 这是我的公开类
public class MyClass {
//这里有很多属性、方法
}
// 让这个类遵从协议
extension class MyClass: PublicProtocol {
public func publicFunction()
}
纳尼???别人能在Framework的接口里看到我遵循的协议,这样似乎不太友好啊😂
作为一个有情怀(强迫症)的程序猿,这种情况我当然不能忍,如果只是去掉publicFunction()
的public
修饰会怎样呢? 就像这样:
extension class MyClass: PublicProtocol {
// 不加public修饰
func publicFunction() {
}
}
纳尼???这不符合Swift编程规则?是的,Xcode会报错如下错误:
Method 'publicFunction()' must be declared public because it
matches a requirement in public protocol 'PublicProtocol'
不折腾了,先看看度娘怎么说...竟然没有! 是不是国猿们都不用Swift做框架啊?
于是马上Google、Stackoverflow、github漫天搜,只找到了如下一种方案,虽然不是特别优雅。
二、解决方案
你也可以👇戳这里 看原问题
// ===== 1. 公开协议 =====
// 这是一个不能更改访问控制的系统/第三方公开协议,你无法改成internal之类的
public protocol PublicProtocol {
public func publicFunction()
}
------------以上割掉----------------
// ===== 2. 创建一个 公开协议 的 内部代理 =====
// 代理协议
internal protocol PublicProtocolProxy {
internal func publicFunction() // 方法名可以一样
}
// 代理类
internal class ProxyClass: PublicProtocol {
// delegate就是MyClass对象,注意要使用weak哦
internal weak delegate: PublicProtocolProxy
func publicFunction() {
// 直接调用代理方法告诉我的`MyClass对象`即可
delegate?.publicFunction()
}
}
// ===== 3. 这是我要公开的类 =====
public class MyClass {
//这里有很多属性、方法
// 创建一个私有代理人去处理公开协议
private lazy var proxy = ProxyClass(delegate: self)
}
// 这里遵循的协议就变成了PublicProtocolProxy
extension class MyClass: PublicProtocolProxy {
// 方法名不变, 同时又避免了必须声明public
func publicFunction() {
}
}
这样别人在Framework接口中就看不到我遵循的协议啦,看下面👇:
public class MyClass {
//这里有很多属性、方法
}
extension class MyClass {
}
// 没改之前是这样的
// extension class MyClass: PublicProtocol {
// public func publicFunction()
// }
三、总结一下
解决方案核心思想就是就是创建一个 内部的中间代理人 去处理公开的协议