UITest 项目中的协议一致性错误

Posted

技术标签:

【中文标题】UITest 项目中的协议一致性错误【英文标题】:Protocol Conformance Error in UITest Project 【发布时间】:2020-04-26 19:59:26 【问题描述】:

我在 Swift 中的 UITest 项目中遇到了一个非常奇怪的错误。

Undefined symbols for architecture x86_64:
  "protocol conformance descriptor for IntroductionToMocking.User : Swift.Decodable in IntroductionToMocking", referenced from:
      lazy protocol witness table accessor for type IntroductionToMocking.User and conformance IntroductionToMocking.User : Swift.Decodable in IntroductionToMocking in MockHTTPClient.o
  "protocol descriptor for IntroductionToMocking.HTTPClientProtocol", referenced from:
      protocol conformance descriptor for IntroductionToMockingUITests.MockHTTPClient : IntroductionToMocking.HTTPClientProtocol in IntroductionToMockingUITests in MockHTTPClient.o
  "type metadata for IntroductionToMocking.User", referenced from:
      IntroductionToMockingUITests.MockHTTPClient.authenticate(username: Swift.String, password: Swift.String, completion: (IntroductionToMocking.User?) -> ()) -> () in MockHTTPClient.o
      lazy protocol witness table accessor for type IntroductionToMocking.User and conformance IntroductionToMocking.User : Swift.Decodable in IntroductionToMocking in MockHTTPClient.o

在我的 UITest 项目中,我创建了使用 HTTPClientProtocol 的 MockHTTPClient,如下所示:

import Foundation
@testable import IntroductionToMocking

class MockHTTPClient: HTTPClientProtocol 

    func authenticate(username: String, password: String, completion: @escaping (User?) -> Void) 


        guard let url = Bundle(for: MockHTTPClient.self).url(forResource: "auth-success-response", withExtension: "json"),
            let data = try? Data(contentsOf: url) else 
                return completion(nil)
        

        let user = try? JSONDecoder().decode(User.self, from: data)
        completion(user)
    


协议在主项目中定义如下:

import Foundation

protocol HTTPClientProtocol 
    func authenticate(username: String, password: String, completion: @escaping (User?) -> Void )

我无法弄清楚发生了什么以及为什么会出现错误。有任何想法吗?

【问题讨论】:

@TylerTheCompiler 是的,我已经导入了。 我在 Xcode 12 中看到了相同的 3 个错误,因为项目在 Xcode 11 中编译良好!您解决了这个问题吗? @AshleyMills 你解决了这个问题吗? 可能您的模型之一符合 Identifiable 并且您正在运行 ios 【参考方案1】:

在我的情况下,问题与通用应用程序有关。我遇到了问题中提到的相同错误。 这里提到的解决方法https://developer.apple.com/forums/thread/654309 对我有用。这并不理想,但将文件添加到测试目标可以编译和运行测试。

解决方法是将文件也添加到测试目标。 好像是编译时合成代码出错

例如,在我运行测试时的编译错误中,我看到了这个错误:

Undefined symbols for architecture x86_64:
  "nominal type descriptor for MyApp.SMPSmallWidgetConfig", referenced from:
      _symbolic _____y_____G 9Tests_iOS35SMPWidgetsConfigDefaultsPersistenceC 12MyApp014SMPSmallWidgetD0V in SMPWidgetsConfigDefaultsPersistenceTests.o
      _symbolic _____y______ySay_____G_____GSo17OS_dispatch_queueCG 7Combine10PublishersO11SubscribeOnV AA12AnyPublisherV 12MyApp20SMPSmallWidgetConfigV s5NeverO in SMPWidgetsConfigDefaultsPersistenceTests.o
      _symbolic _____y______y______ySay_____G_____GSo17OS_dispatch_queueCGAIG 7Combine10PublishersO9ReceiveOnV AC09SubscribeD0V AA12AnyPublisherV 12MyApp20SMPSmallWidgetConfigV s5NeverO in SMPWidgetsConfigDefaultsPersistenceTests.o
      _symbolic Say_____GSg 12MyApp20SMPSmallWidgetConfigV in SMPWidgetsConfigDefaultsPersistenceTests.o
      _symbolic _____ySay_____G_____G 7Combine12AnyPublisherV 12MyApp20SMPSmallWidgetConfigV s5NeverO in SMPWidgetsConfigDefaultsPersistenceTests.o
      _symbolic Say_____GSgz_Xx 12MyApp20SMPSmallWidgetConfigV in SMPWidgetsConfigDefaultsPersistenceTests.o
      _symbolic Say_____GIegg_ 12MyApp20SMPSmallWidgetConfigV in SMPWidgetsConfigDefaultsPersistenceTests.o
      ...
  "protocol conformance descriptor for MyApp.SMPSmallWidgetConfig : Swift.Equatable in MyApp", referenced from:
      lazy protocol witness table accessor for type MyApp.SMPSmallWidgetConfig and conformance MyApp.SMPSmallWidgetConfig : Swift.Equatable in MyApp in SMPWidgetsConfigDefaultsPersistenceTests.o
  "protocol conformance descriptor for MyApp.SMPSmallWidgetConfig : Swift.Encodable in MyApp", referenced from:
      lazy protocol witness table accessor for type MyApp.SMPSmallWidgetConfig and conformance MyApp.SMPSmallWidgetConfig : Swift.Encodable in MyApp in SMPWidgetsConfigDefaultsPersistenceTests.o
  "type metadata for MyApp.SMPSmallWidgetConfig", referenced from:
      lazy protocol witness table accessor for type MyApp.SMPSmallWidgetConfig and conformance MyApp.SMPSmallWidgetConfig : Swift.Encodable in MyApp in SMPWidgetsConfigDefaultsPersistenceTests.o
      lazy protocol witness table accessor for type MyApp.SMPSmallWidgetConfig and conformance MyApp.SMPSmallWidgetConfig : Swift.Equatable in MyApp in SMPWidgetsConfigDefaultsPersistenceTests.o
  "static MyApp.SMPSmallWidgetConfig.defaultSMPSmallWidgetConfig() -> MyApp.SMPSmallWidgetConfig", referenced from:
      Tests_iOS.SMPWidgetsConfigDefaultsPersistenceTests.(givenSmallConfig in _F12F8146E6B85CC300C4FE7EE03F2059)() -> MyApp.SMPSmallWidgetConfig in SMPWidgetsConfigDefaultsPersistenceTests.o
ld: symbol(s) not found for architecture x86_64

SMPSmallWidgetConfig 添加到测试目标可以解决编译问题。 这当然是除了拥有 @testable import MyApp 在测试中

【讨论】:

我在回复中添加了有关解决方法的详细信息。我希望它可以帮助@matt

以上是关于UITest 项目中的协议一致性错误的主要内容,如果未能解决你的问题,请参考以下文章

OpenTok/TokBox 的 Swift 协议一致性错误

错误:“ViewController”与扩展协议的冗余一致性

多种协议的 Swift 类一致性(XCode 7、iOS 9、Swift 2.1)

白话分布式一致性协议 | raft协议

协议一致性检查

分布式系统中的一致性协议