美文网首页
Swift Framework - 隐藏公开协议

Swift Framework - 隐藏公开协议

作者: JonorZhang | 来源:发表于2018-04-28 00:02 被阅读125次

    一、问题由来

    在将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 let 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()
    // }
    

    三、总结一下

    解决方案核心思想就是就是创建一个 内部的中间代理人 去处理公开的协议

    相关文章

      网友评论

          本文标题:Swift Framework - 隐藏公开协议

          本文链接:https://www.haomeiwen.com/subject/ppbblftx.html