如何从另一个Swift文件导入Swift文件?


154

我只是想从另一个文件中加入我的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文件都在同一目录中。



2
根据apple docs,当两个文件具有相同的目标时,您不需要导入。可悲的是测试有不同的目标。一种可能的解决方案是使用yourModule / PrimeNumberModel进行导入语句。
Alex Reynolds

@ joseph.hainline我面临着同样的问题。如何解决?我现在被困住了。
开发人员

Answers:


131

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

摆脱:

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

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


2
这需要更多的支持。建议只在.swift文件添加到测试目标的答案并不完全错,但它不应该做的方式
低于

10
但是如何处理我的项目名称“野生动物联盟”(其中包含空格)?
allenlinli 2014年

59
从Beta 4开始,您还需要确保访问控制设置正确。您需要将要测试的类和要在该类中测试的功能都明确设置为public。否则,XCTestCase子类将无法“看到”您要测试的内容。我在昨晚的这个晚上浪费了几个小时:)
Erik P. Hansen 2014年

2
如果我没记错的话,产品模块名称(在目标构建设置中)并不总是与目标名称相同,而是import语句中应使用的模块名称
csch 2014年

3
如果Swift目标的名称中有空格,则可以通过在import语句中用下划线替换空格来导入它。“我的Swift班级”变为“ My_Swift_Class”。
Cin316

70

更新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() {
   }
}

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


斯威夫特1.x

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

  1. 您无需导入Swift类,但需要导入外部模块(目标)
  2. Swift中的默认访问控制级别为Internal access

考虑到测试在另一个目标上,PrimeNumberModelTests.swift您需要对import包含要测试的类的目标进行测试,如果您的目标被调用,MyProject则需要添加import MyProjectPrimeNumberModelTests

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() {
   }
}

有什么办法可以更改默认的访问控制?我有一个有趣的案例,它过去可以在没有使用公共修饰符的情况下正常运行,然后我移动了测试用例,突然停止了工作。
Metaphox 2014年

我认为这是不可能的,至少对于当前版本的swift。
Diogo T

谢谢。而且我发现我的问题是swift文件没有与测试用例一起构建到测试目标。
Metaphox

1
是的,这正是我感到不对的地方-我不应该将类swift文件构建到测试用例目标中。不错的博客文章!谢谢。
Metaphox 2014年

1
如果您有一个使用Xcode 5或更高版本创建的项目,并且选择了“公共访问,导入目标模块”方法,请仔细检查测试目标的模块名称,因为它可能与主要目标相同。如果您No such module <moduleName>在测试用例中收到编译错误,则可能需要检查PRODUCT_MODULE_NAME测试目标。好的答案Diogo。
克里斯(Chris)

48

文档中,它说在Swift中没有导入语句。

在此处输入图片说明

只需使用:

let primNumber = PrimeNumberModel()

2
这行得通,但是我不得不关闭并重新打开Xcode 6.0才能最终出现该类。也尝试清洁和构建项目。
user3344977

在最新的XCode 6.3 beta中,这似乎是新问题(或问题),因此现在需要import语句。在Swift中也有一个import语句,用于导入模块。
Augunrik

根据提供的文档,带有“没有导入语句”的表与“从同一目标导入”情况有关。如果使用XCTests,则使用不同的(测试)目标,因此请注意本文的“导入外部框架”部分,还有另一个表:任何语言框架->导入Swift->导入“ FrameworkName”
Igor Vasilev

如果您在编辑器中看到问题,则通常是有一个测试目标没有包含该类。因此,您可能会建立可运行的罚款,但是如果任何一个目标出现问题,它仍然会显示错误。如果您选择了其他目标之一,则无法编译。
乔尔·特普利

34

在测试目标中检查PrimeNumberModel.swift的目标成员身份。


1
请将此添加为评论。
4dgaurav 2014年

8
这个人不能,他需要再发表9次(撰写本文时)。
AlbertEngelB 2014年

1
目标到底是什么?
用户

谢谢,这对我有用。单击课程文件。检查右侧检查器列的第一个选项卡。第二部分是“目标成员身份”。确保已选择要尝试包含该类的目标/产品。
Hairgami_Master 2015年

1
严格来说,这并不是对“如何导入...”问题的答案,但确实回答了我带到这里的问题(我忘记了向目标添加新文件)。因此,对我来说,以及其他将遵循第一个Google搜索结果“ swift unresolved identifier class”到达这里的人,这一个答案(而不是评论)。
noamtm 2015年

17

在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中解决所有这些新问题。
费利佩

5

根据Apple的说法,您不需要导入同一目标中的快速文件。通过将快速文件添加到常规目标和测试目标中,最终使它正常工作。然后,我使用桥接头进行测试,以确保我在常规桥接头中引用的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解决方案将起作用


这仅适用于逻辑/模型类,还是可以将其用于应用程序委托?
Nicolas Miari

5

我能够通过清理构建来解决此问题。

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


4

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

将行添加@testable import MyApp到测试文件的顶部,其中“ MyApp”是应用程序目标的产品模块名称(在应用程序目标的构建设置中可见)。而已。

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


1

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

主Swift

PrimeNumberModelTests()

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

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

在这种情况下,您将收到警告:初始化器的结果未使用,但是程序可以编译并可执行:

./PrimeNumberMain

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


1

检查您的PrimeNumberModelTests目标设置。

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


这不是正确的方法,请检查High6响应。
Diogo T 2014年

0

所以,你需要

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

就我而言,我有一个要进行单元测试的swift文件,并且该单元测试文件也是swift类。我确保访问修饰符正确,但是声明

import stMobile

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

仍然不起作用(我仍然收到“没有这样的模块”错误),我检查了目标,它的名称确实是stMobile。因此,我进入包装下的“构建设置”,找到了“产品模块名称”,由于某种原因,它被称为St_Mobile,所以我更改了导入语句

import St_Mobile

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

因此,总结一下:

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

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


0

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

Xcode可以为您构建swift模块,或参考railsware博客以获取有关的命令行说明swiftc


0

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

在查看时,我碰到了Clayton McIlrath在swiftcast.tv上的文章《在Swift中编写您的第一个单元测试》。它讨论了访问修饰符,显示了您遇到的相同问题的一个示例(但对于ViewController而不是模型文件),并展示了如何导入目标并通过在目标中包含目标文件来解决访问修饰符问题,这意味着除非您确实想这样做,否则不必公开您要测试的课程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.