首页 > 解决方案 > 仅弃用 Swift 中的默认协议实现

问题描述

考虑我有一个协议Test。我想为一个新添加的属性提供一个默认实现,newProperty这样 10 个其他项目就不必在他们的模拟实现Test协议中添加它来进行单元测试。但是对于任何实际用例,我希望人们不要依赖这个默认实现并添加他们自己的实现或使用正确实现此协议的类。

@available(*, deprecated, message)因此,如果我在默认实现之前添加一个,Xcode 会警告仅使用默认实现的用户。或者即使使用Implementor类实例访问它也会发出警告newProperty

protocol Test {

    var newProperty: CGFloat { get }

    ...
}

extension Test {
    
    @available(*, deprecated, message: "Please ignore default implementation")
    var newProperty: CGFloat {
        get {
            return -1.0
        }
    }
}

class Implementor: Test {
    
    var newProperty: CGFloat 

    init() {
         newProperty = 100
    }

    ...

}

标签: swiftxcodeunit-testingattributesprotocols

解决方案


您可以通过区分您的测试目标并使扩展代码仅对您的测试目标可用来轻松实现它。

要区分代码中的不同测试目标,您可以添加preprocessor macros和添加custom swift flags到测试目标的构建设置中。

选择您的测试目标并在构建设置中搜索预处理器宏并添加TESTING=1到所有可用的构建配置

在此处输入图像描述

在同一目标中通过搜索其他 swift 标志添加自定义标志并添加-DTESTING到所有可用配置

在此处输入图像描述

最后在您的代码中,将扩展默认实现包装为

#if TESTING
extension Test {
    var newProperty: CGFloat {
        get {
            return -1.0
        }
    }
}
#endif

现在,如果您尝试Test在主项目目标中确认协议

class MyOwnView: UIView, Test {
    
}

你会得到错误:在此处输入图像描述

如果您打开测试目标并确认协议

    class SomeView: UIView, Test {

        
    }

它不会显示任何错误。

尽管您无法访问所有 10 个项目,但您只需要让他们做的就是将此宏和自定义标志添加到他们的测试目标中,我猜这几乎是可行的


推荐阅读