【问题标题】:How do I import a Swift file from another Swift file?如何从另一个 Swift 文件导入 Swift 文件?
【发布时间】:2014-07-24 15:38:11
【问题描述】:

我只是想从另一个文件中包含我的 Swift 类,比如它的测试

PrimeNumberModel.swift

import Foundation

class PrimeNumberModel { }

PrimeNumberModelTests.swift

import XCTest
import PrimeNumberModel  // gives me "No such module 'PrimeNumberModel'"

class PrimeNumberModelTests: XCTestCase {
    let testObject = PrimeNumberModel()  // "Use of unresolved identifier 'PrimeNumberModel'"    
}

两个 swift 文件在同一个目录中。

【问题讨论】:

  • 根据苹果文档,当两个文件具有相同的目标时,您不需要导入。可悲的是,测试有不同的目标。一种可能的解决方案是使用 yourModule/PrimeNumberModel 执行导入语句。
  • @joseph.hainline 我面临同样的问题。它将如何解决?我现在卡住了。

标签: swift xcode6


【解决方案1】:

我的XCTestCase 文件中也有同样的问题,但在常规项目文件中没有。

摆脱:

使用未解析的标识符“PrimeNumberModel”

我需要import 测试文件中的基本模块。在我的例子中,我的 target 被称为“myproject”,我添加了 import myproject 并且该类被识别。

【讨论】:

  • 这需要更多的支持。建议仅将 .swift 文件添加到测试目标的答案并不完全错误,但这不是应该这样做的方式
  • 但是我的项目名称“Wildlife League”里面有空格怎么办?
  • 从 Beta 4 开始,您还需要确保您的访问控制设置正确。您需要将您正在测试的类和您在该类中测试的函数明确设置为public。否则XCTestCase 子类将无法“看到”您要测试的内容。我昨晚在这上面浪费了几个小时:)
  • 如果我没记错的话,产品模块名称(在目标构建设置中)并不总是与目标名称相同,应该是模块名称在import 语句中使用
  • 如果 Swift 目标的名称中有空格,您可以通过在 import 语句中用下划线替换空格来导入它。 “我的 Swift 班级”变成了“My_Swift_Class”。
【解决方案2】:

更新 Swift 2.x、3.x、4.x 和 5.x

现在您不需要将public 添加到测试方法中。 在较新版本的 Swift 上,只需添加 @testable 关键字。

PrimeNumberModelTests.swift

import XCTest
@testable import MyProject

class PrimeNumberModelTests: XCTestCase {
    let testObject = PrimeNumberModel()
}

而你的内部方法可以保留Internal

PrimeNumberModel.swift

import Foundation

class PrimeNumberModel {
   init() {
   }
}

请注意,即使使用 @testableprivate(和 fileprivate)符号也不可用。


斯威夫特 1.x

这里有两个来自 Swift 的相关概念(作为 Xcode 6 beta 6)。

  1. 您不需要导入 Swift 类,但需要导入外部模块(目标)
  2. Swift 中默认的Access Control 级别是Internal access

考虑到测试在PrimeNumberModelTests.swift 上的另一个目标上,您需要import 包含您要测试的类的目标,如果您的目标 被称为MyProject 则需要将import MyProject 添加到PrimeNumberModelTests

PrimeNumberModelTests.swift

import XCTest
import MyProject

class PrimeNumberModelTests: XCTestCase {
    let testObject = PrimeNumberModel()
}

但这不足以测试您的课程PrimeNumberModel,因为默认访问控制级别是Internal Access,您的课程对测试包不可见,因此您需要将其设为Public Access 和所有您要测试的方法:

PrimeNumberModel.swift

import Foundation

public class PrimeNumberModel {
   public init() {
   }
}

【讨论】:

  • 有没有办法改变默认的访问控制?我有一个有趣的案例,它曾经在没有公共修饰符的情况下运行得很好,然后我移动了测试用例,它突然停止工作了。
  • 我认为这是不可能的,至少对于当前版本的 swift。
  • 谢谢。我发现我的问题是 swift 文件没有使用测试用例构建到测试目标。
  • 是的,这正是我感觉不对的地方——我不应该将类 swift 文件构建到测试用例目标中。不错的博文!谢谢。
  • 如果您有一个使用 Xcode 5 或更高版本创建的项目,并且您选择“公共访问,导入目标模块”方法,请仔细检查您的测试目标的模块名称,因为它可能相同作为主要目标。如果您在测试用例中收到No such module <moduleName> 编译错误,您可能需要检查PRODUCT_MODULE_NAME 的测试目标。很好的答案迪奥戈。
【解决方案3】:

Documentation 中它说 Swift 中没有导入语句。

简单使用:

let primNumber = PrimeNumberModel()

【讨论】:

  • 这行得通,但我必须关闭并重新打开 Xcode 6.0 才能让课程最终出现。尝试清理和构建项目。
  • 这似乎是最新的 XCode 6.3 beta 中的新问题(或问题),因此现在需要导入声明。 Swift 中还有一个 import 语句,用于导入模块。
  • 根据提供的文档,这个带有“无导入语句”的表与“从同一目标导入”的情况有关。如果 XCTests 您使用不同的(测试)目标,请注意文章的“导入外部框架”部分,还有另一个表格:任何语言框架 -> 导入 Swift -> 需要导入“FrameworkName”
  • 如果您在编辑器中看到问题,通常是测试目标没有包含该类。因此,您可能会很好地构建可运行文件,但如果任何一个目标出现问题,它仍然会显示错误。如果您选择了其他目标之一,它不会让您编译。
【解决方案4】:

在您的测试目标中检查 PrimeNumberModel.swift 的目标成员资格。

【讨论】:

  • 请将此添加为评论。
  • 这个人不能,他需要 9 个以上的代表才能这样做(在撰写本文时)。
  • 目标到底是什么?
  • 感谢这对我有用。单击类文件。检查右侧检查器列的第一个选项卡。第二部分是“目标会员”。确保选择了您尝试包含该类的目标/产品。
  • 严格来说,这不是对“我如何导入...”问题的回答,但它确实回答了我带到这里的问题(我忘了向目标添加新文件) .所以对于我和其他将通过“swift unresolved identifier class”的第一个谷歌结果到达这里的其他人来说,这个一个答案(而不是评论)。
【解决方案5】:

在 Objective-C 中,如果你想在另一个文件中使用一个类,你必须导入它:

#import "SomeClass.h"

但是,在 Swift 中,您根本不需要导入。就像已经导入一样使用它。

示例

// This is a file named SomeClass.swift

class SomeClass : NSObject {

}

// This is a different file, named OtherClass.swift

class OtherClass : NSObject {
    let object = SomeClass()
}

如您所见,不需要导入。希望这会有所帮助。

【讨论】:

  • 谢谢!仍然在 Swift 中处理所有这些新东西。
【解决方案6】:

根据 Apple 的说法,您不需要导入同一目标中的 swift 文件。我终于通过将我的 swift 文件添加到我的常规目标和测试目标来让它工作。然后我使用桥接头进行测试,以确保我在常规桥接头中引用的 ObjC 文件可用。现在像魅力一样奔跑。

import XCTest
//Optionally you can import the whole Objc Module by doing #import ModuleName

class HHASettings_Tests: XCTestCase {

override func setUp() {
    let x : SettingsTableViewController = SettingsTableViewController()

    super.setUp()
    // Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDown() {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    super.tearDown()
}

func testExample() {
    // This is an example of a functional test case.
    XCTAssert(true, "Pass")
}

func testPerformanceExample() {
    // This is an example of a performance test case.
    self.measureBlock() {
        // Put the code you want to measure the time of here.
    }
}

}

所以请确保 PrimeNumberModel 具有您的测试目标。或者导入整个模块的 High6 解决方案将起作用

【讨论】:

  • 这仅适用于逻辑/模型类,还是我也可以将它用于应用程序委托?
【解决方案7】:

我能够通过清理我的构建来解决这个问题。

顶部菜单 -> 产品 -> 清洁 或键盘快捷键:Shift+Cmd+K

【讨论】:

    【解决方案8】:

    从 Swift 2.0 开始,最佳做法是:

    @testable import MyApp 行添加到测试文件的顶部,其中“MyApp”是您的应用目标的产品模块名称(可在您的应用目标中查看构建设置)。就是这样。

    (请注意,产品模块名称将与您的应用目标名称相同,除非您的应用目标名称包含空格,空格将替换为下划线。例如,如果我的应用目标名为“Fun Game”我会在我的测试顶部写@testable import Fun_Game。)

    【讨论】:

      【解决方案9】:

      检查您的PrimeNumberModelTests 目标设置。

      如果在 Build Phases/Compile Sources 中看不到 PrimeNumberModel.swift 文件,请添加它。

      【讨论】:

      • 这不是正确的做法,请检查 High6 响应。
      【解决方案10】:

      您需要添加一个例程供编译器引用作为入口点,因此添加一个 main.swift 文件,在这种情况下,它只是创建您的测试文件的一个实例:

      ma​​in.swift

      PrimeNumberModelTests()
      

      然后在命令行编译(我用的是El Capitan和Swift 2.2):

      xcrun -sdk macosx swiftc -emit-executable -o PrimeNumberMain PrimeNumberModel.swift PrimeNumberModelTests.swift main.swift
      

      在这种情况下,你会得到一个警告:initializer的结果是未使用的,但是程序可以编译并且是可执行的:

      ./PrimeNumberMain
      

      CAVEAT:为简单起见,我删除了 import XCTest 和 XCTestCase 类型。

      【讨论】:

        【解决方案11】:

        所以,你需要

        1. 导入要使用的外部模块
        2. 并确保对要使用的类和方法具有正确的访问修饰符。

        在我的例子中,我有一个我想要单元测试的 swift 文件,而单元测试文件也是一个 swift 类。我确保访问修饰符是正确的,但声明

        import stMobile
        

        (假设 stMobile 是我们的目标名称)

        仍然没有工作(我仍然收到“没有这样的模块”错误),我检查了我的目标,它的名字确实是 st​​Mobile。所以,我去 Build Settings,在包装下,找到了 Product Module Name,由于某种原因,它被称为 St_Mobile,所以我改变了我的 import 语句

        import St_Mobile
        

        (即产品模块名称),一切正常。

        所以,总结一下:

        1. 检查您的产品模块名称并在您的单元测试类中使用下面的导入语句

          import myProductModuleName
          
        2. 确保您的访问修饰符正确(类级别和您的方法)。

        【讨论】:

          【解决方案12】:

          Swift 编译器不要求显式导入,而是隐式搜索 .swiftmodule 依赖 Swift 库的文件。

          Xcode 可以为你构建 swift 模块,或者参考railsware blog 获取swiftc 的命令行说明。

          【讨论】:

            【解决方案13】:

            正如@high6 和@erik-p-hansen 在@high6 给出的答案中指出的那样,这可以通过导入 PrimeNumberModel 类所在模块的目标来克服,这可能与您的项目名称相同一个简单的项目。

            在看这个的时候,我在 swiftcast.tv 上看到了 Clayton McIlrath 的文章 Write your first Unit Test in Swift。它讨论了访问修饰符,展示了您遇到的相同问题的示例(但对于 ViewController 而不是模型文件),并展示了如何导入目标并通过在目标中包含目标文件来解决访问修饰符问题,这意味着除非您真的想这样做,否则您不必公开您尝试测试的课程。

            【讨论】:

              猜你喜欢
              • 2017-11-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-03-21
              • 2015-10-27
              • 1970-01-01
              • 2015-02-02
              • 2016-07-25
              相关资源
              最近更新 更多