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

时间:2022-03-11 07:11:59

I simply want to include my Swift class from another file, like its test

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

PrimeNumberModel.swift

PrimeNumberModel.swift

import Foundation

class PrimeNumberModel { }

PrimeNumberModelTests.swift

PrimeNumberModelTests.swift

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

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

Both swift files are in the same directory.

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

13 个解决方案

#1


121  

I had the same problem, also in my XCTestCase files, but not in the regular project files.

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

To get rid of the:

摆脱:

Use of unresolved identifier 'PrimeNumberModel'

使用未解析标识符“PrimeNumberModel”

I needed to import the base module in the test file. In my case, my target is called 'myproject' and I added import myproject and the class was recognised.

我需要在测试文件中导入基本模块。在我的例子中,我的目标是“myproject”,我添加了import myproject,并确认了类。

#2


65  

UPDATE Swift 2.x and 3.x

Now you don't need to add the public to the methods to test then. On Swift 2 it's only necessary to add the @testable keyword.

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

PrimeNumberModelTests.swift

PrimeNumberModelTests.swift

import XCTest
@testable import MyProject

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

And your internal methods can keep Internal

你的内部方法可以保持内部

PrimeNumberModel.swift

PrimeNumberModel.swift

import Foundation

class PrimeNumberModel {
   init() {
   }
}

Note that private (and fileprivate) symbols are not available even with using @testable.

注意,即使使用@testable,也不能使用私有(和fileprivate)符号。


Swift 1.x

There are two relevant concepts from Swift here (As Xcode 6 beta 6).

Swift提供了两个相关概念(如Xcode 6 beta 6)。

  1. You don't need to import Swift classes, but you need to import external modules (targets)
  2. 您不需要导入Swift类,但是需要导入外部模块(目标)
  3. The Default Access Control level in Swift is Internal access
  4. Swift中的默认访问控制级别是内部访问

Considering that tests are on another target on PrimeNumberModelTests.swift you need to import the target that contains the class that you want to test, if your target is called MyProject will need to add import MyProject to the PrimeNumberModelTests:

考虑到测试是在primenumbermodeltest上的另一个目标上进行的。swift您需要导入包含您想要测试的类的目标,如果您的目标被称为MyProject,则需要向PrimeNumberModelTests添加import MyProject:

PrimeNumberModelTests.swift

PrimeNumberModelTests.swift

import XCTest
import MyProject

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

But this is not enough to test your class PrimeNumberModel, since the default Access Control level is Internal Access, your class won't be visible to the test bundle, so you need to make it Public Access and all the methods that you want to test:

但是这还不足以测试你的类PrimeNumberModel,因为默认的访问控制级别是内部访问,你的类对测试包来说是不可见的,所以你需要使它成为公共访问以及所有你想要测试的方法:

PrimeNumberModel.swift

PrimeNumberModel.swift

import Foundation

public class PrimeNumberModel {
   public init() {
   }
}

#3


41  

In the Documentation it says there are no import statements in Swift.

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

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

Simply use:

简单的使用方法:

let primNumber = PrimeNumberModel()

#4


32  

Check target-membership of PrimeNumberModel.swift in your testing target.

检查target-membership PrimeNumberModel。迅速在你的测试目标。

#5


17  

In Objective-C, if you wanted to use a class in another file you had to import it:

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

#import "SomeClass.h"

However, in Swift, you don't have to import at all. Simply use it as if it was already imported.

然而,在Swift中,您根本不需要导入。简单地使用它,就好像它已经被导入了一样。

Example

// This is a file named SomeClass.swift

class SomeClass : NSObject {

}

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

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

As you can see, no import was needed. Hope this helps.

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

#6


5  

According To Apple you don't need an import for swift files in the Same Target. I finally got it working by adding my swift file to both my regular target and test target. Then I used the bridging header for test to make sure my ObjC files that I referenced in my regular bridging header were available. Ran like a charm now.

根据苹果公司的说法,在同一个目标中,你不需要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.
    }
}

}

SO make sure PrimeNumberModel has a target of your test Target. Or High6 solution of importing your whole module will work

所以要确保PrimeNumberModel有一个测试目标。或者High6解决方案可以导入整个模块

#7


5  

I was able to solve this problem by cleaning my build.

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

Top menu -> Product -> Clean Or keyboard shortcut: Shift+Cmd+K

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

#8


4  

As of Swift 2.0, best practice is:

关于Swift 2.0,最佳实践是:

Add the line @testable import MyApp to the top of your tests file, where "MyApp" is the Product Module Name of your app target (viewable in your app target's build settings). That's it.

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

(Note that the product module name will be the same as your app target's name unless your app target's name contains spaces, which will be replaced with underscores. For example, if my app target was called "Fun Game" I'd write @testable import Fun_Game at the top of my tests.)

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

#9


1  

You need to add a routine for the compiler to reference as an entry point, so add a main.swift file, which in this case simply creates an instance of your test file:

您需要为编译器添加一个例程作为入口点引用,因此添加一个main。swift文件,在本例中,它只创建测试文件的实例:

main.swift

main.swift

PrimeNumberModelTests()

Then compile on the command line (I am using El Capitan and Swift 2.2):

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

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

In this case, you will get a warning: result of initializer is unused, but the program compiles and is executable:

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

./PrimeNumberMain

CAVEAT: I removed the import XCTest and XCTestCase type for simplicity.

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

#10


1  

Check your PrimeNumberModelTests Target Settings.

检查你的primenumbermodeltest目标设置。

If you can't see PrimeNumberModel.swift file in Build Phases/Compile Sources, add it.

如果你看不到PrimeNumberModel。在构建阶段/编译源中添加swift文件。

#11


0  

So, you need to

所以,你需要

  1. Import external modules you want to use
  2. 导入要使用的外部模块。
  3. And make sure you have the right access modifiers on the class and methods you want to use.
  4. 并确保在要使用的类和方法上有正确的访问修饰符。

In my case I had a swift file I wanted to unit test, and the unit test file was also a swift class. I made sure the access modifiers were correct, but the statement

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

import stMobile

(let's say that stMobile is our target name)

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

still did not work (I was still getting the 'No such module' error), I checked my target, and its name was indeed stMobile. So, I went to Build Settings, under packaging, and found the Product Module Name, and for some reason this was called St_Mobile, so I changed my import statement

仍然没有工作(我仍然得到“没有这样的模块”错误),我检查了我的目标,它的名字确实是stMobile。因此,我在包装下创建了设置,并找到了产品模块的名称,出于某种原因,这被称为St_Mobile,因此我更改了import语句。

import St_Mobile

(which is the Product Module Name), and everything worked.

(这是产品模块名),所有的东西都工作了。

So, to sum up:

所以,总结:

  1. Check your Product Module Name and use the import statement below in you unit test class

    检查产品模块名,并在单元测试类中使用下面的import语句

    import myProductModuleName
    
  2. Make sure your access modifiers are correct (class level and your methods).

    确保访问修饰符是正确的(类级别和方法)。

#12


0  

Instead of requiring explicit imports, the Swift compiler implicitly searches for .swiftmodule files of dependency Swift libraries.

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

Xcode can build swift modules for you, or refer to the railsware blog for command line instructions for swiftc.

Xcode可以为您构建swift模块,或者参考railsware博客获取swiftc的命令行指令。

#13


0  

As @high6 and @erik-p-hansen pointed out in the answer given by @high6, this can be overcome by importing the target for the module where the PrimeNumberModel class is, which is probably the same name as your project in a simple project.

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

While looking at this, I came across the article Write your first Unit Test in Swift on swiftcast.tv by Clayton McIlrath. It discusses access modifiers, shows an example of the same problem you are having (but for a ViewController rather than a model file) and shows how to both import the target and solve the access modifier problem by including the destination file in the target, meaning you don't have to make the class you are trying to test public unless you actually want to do so.

在看这篇文章的时候,我偶然发现了这篇文章,在swiftcast上写了你的第一个单元测试。克莱顿McIlrath电视。它讨论了访问修饰符,显示了一个示例相同的问题你有(但ViewController而不是模型文件)和显示了如何导入目标和解决访问修饰符的问题,包括目标中的目标文件,这意味着你不必公开课你想测试,除非你真的想这样做。

#1


121  

I had the same problem, also in my XCTestCase files, but not in the regular project files.

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

To get rid of the:

摆脱:

Use of unresolved identifier 'PrimeNumberModel'

使用未解析标识符“PrimeNumberModel”

I needed to import the base module in the test file. In my case, my target is called 'myproject' and I added import myproject and the class was recognised.

我需要在测试文件中导入基本模块。在我的例子中,我的目标是“myproject”,我添加了import myproject,并确认了类。

#2


65  

UPDATE Swift 2.x and 3.x

Now you don't need to add the public to the methods to test then. On Swift 2 it's only necessary to add the @testable keyword.

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

PrimeNumberModelTests.swift

PrimeNumberModelTests.swift

import XCTest
@testable import MyProject

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

And your internal methods can keep Internal

你的内部方法可以保持内部

PrimeNumberModel.swift

PrimeNumberModel.swift

import Foundation

class PrimeNumberModel {
   init() {
   }
}

Note that private (and fileprivate) symbols are not available even with using @testable.

注意,即使使用@testable,也不能使用私有(和fileprivate)符号。


Swift 1.x

There are two relevant concepts from Swift here (As Xcode 6 beta 6).

Swift提供了两个相关概念(如Xcode 6 beta 6)。

  1. You don't need to import Swift classes, but you need to import external modules (targets)
  2. 您不需要导入Swift类,但是需要导入外部模块(目标)
  3. The Default Access Control level in Swift is Internal access
  4. Swift中的默认访问控制级别是内部访问

Considering that tests are on another target on PrimeNumberModelTests.swift you need to import the target that contains the class that you want to test, if your target is called MyProject will need to add import MyProject to the PrimeNumberModelTests:

考虑到测试是在primenumbermodeltest上的另一个目标上进行的。swift您需要导入包含您想要测试的类的目标,如果您的目标被称为MyProject,则需要向PrimeNumberModelTests添加import MyProject:

PrimeNumberModelTests.swift

PrimeNumberModelTests.swift

import XCTest
import MyProject

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

But this is not enough to test your class PrimeNumberModel, since the default Access Control level is Internal Access, your class won't be visible to the test bundle, so you need to make it Public Access and all the methods that you want to test:

但是这还不足以测试你的类PrimeNumberModel,因为默认的访问控制级别是内部访问,你的类对测试包来说是不可见的,所以你需要使它成为公共访问以及所有你想要测试的方法:

PrimeNumberModel.swift

PrimeNumberModel.swift

import Foundation

public class PrimeNumberModel {
   public init() {
   }
}

#3


41  

In the Documentation it says there are no import statements in Swift.

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

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

Simply use:

简单的使用方法:

let primNumber = PrimeNumberModel()

#4


32  

Check target-membership of PrimeNumberModel.swift in your testing target.

检查target-membership PrimeNumberModel。迅速在你的测试目标。

#5


17  

In Objective-C, if you wanted to use a class in another file you had to import it:

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

#import "SomeClass.h"

However, in Swift, you don't have to import at all. Simply use it as if it was already imported.

然而,在Swift中,您根本不需要导入。简单地使用它,就好像它已经被导入了一样。

Example

// This is a file named SomeClass.swift

class SomeClass : NSObject {

}

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

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

As you can see, no import was needed. Hope this helps.

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

#6


5  

According To Apple you don't need an import for swift files in the Same Target. I finally got it working by adding my swift file to both my regular target and test target. Then I used the bridging header for test to make sure my ObjC files that I referenced in my regular bridging header were available. Ran like a charm now.

根据苹果公司的说法,在同一个目标中,你不需要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.
    }
}

}

SO make sure PrimeNumberModel has a target of your test Target. Or High6 solution of importing your whole module will work

所以要确保PrimeNumberModel有一个测试目标。或者High6解决方案可以导入整个模块

#7


5  

I was able to solve this problem by cleaning my build.

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

Top menu -> Product -> Clean Or keyboard shortcut: Shift+Cmd+K

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

#8


4  

As of Swift 2.0, best practice is:

关于Swift 2.0,最佳实践是:

Add the line @testable import MyApp to the top of your tests file, where "MyApp" is the Product Module Name of your app target (viewable in your app target's build settings). That's it.

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

(Note that the product module name will be the same as your app target's name unless your app target's name contains spaces, which will be replaced with underscores. For example, if my app target was called "Fun Game" I'd write @testable import Fun_Game at the top of my tests.)

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

#9


1  

You need to add a routine for the compiler to reference as an entry point, so add a main.swift file, which in this case simply creates an instance of your test file:

您需要为编译器添加一个例程作为入口点引用,因此添加一个main。swift文件,在本例中,它只创建测试文件的实例:

main.swift

main.swift

PrimeNumberModelTests()

Then compile on the command line (I am using El Capitan and Swift 2.2):

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

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

In this case, you will get a warning: result of initializer is unused, but the program compiles and is executable:

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

./PrimeNumberMain

CAVEAT: I removed the import XCTest and XCTestCase type for simplicity.

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

#10


1  

Check your PrimeNumberModelTests Target Settings.

检查你的primenumbermodeltest目标设置。

If you can't see PrimeNumberModel.swift file in Build Phases/Compile Sources, add it.

如果你看不到PrimeNumberModel。在构建阶段/编译源中添加swift文件。

#11


0  

So, you need to

所以,你需要

  1. Import external modules you want to use
  2. 导入要使用的外部模块。
  3. And make sure you have the right access modifiers on the class and methods you want to use.
  4. 并确保在要使用的类和方法上有正确的访问修饰符。

In my case I had a swift file I wanted to unit test, and the unit test file was also a swift class. I made sure the access modifiers were correct, but the statement

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

import stMobile

(let's say that stMobile is our target name)

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

still did not work (I was still getting the 'No such module' error), I checked my target, and its name was indeed stMobile. So, I went to Build Settings, under packaging, and found the Product Module Name, and for some reason this was called St_Mobile, so I changed my import statement

仍然没有工作(我仍然得到“没有这样的模块”错误),我检查了我的目标,它的名字确实是stMobile。因此,我在包装下创建了设置,并找到了产品模块的名称,出于某种原因,这被称为St_Mobile,因此我更改了import语句。

import St_Mobile

(which is the Product Module Name), and everything worked.

(这是产品模块名),所有的东西都工作了。

So, to sum up:

所以,总结:

  1. Check your Product Module Name and use the import statement below in you unit test class

    检查产品模块名,并在单元测试类中使用下面的import语句

    import myProductModuleName
    
  2. Make sure your access modifiers are correct (class level and your methods).

    确保访问修饰符是正确的(类级别和方法)。

#12


0  

Instead of requiring explicit imports, the Swift compiler implicitly searches for .swiftmodule files of dependency Swift libraries.

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

Xcode can build swift modules for you, or refer to the railsware blog for command line instructions for swiftc.

Xcode可以为您构建swift模块,或者参考railsware博客获取swiftc的命令行指令。

#13


0  

As @high6 and @erik-p-hansen pointed out in the answer given by @high6, this can be overcome by importing the target for the module where the PrimeNumberModel class is, which is probably the same name as your project in a simple project.

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

While looking at this, I came across the article Write your first Unit Test in Swift on swiftcast.tv by Clayton McIlrath. It discusses access modifiers, shows an example of the same problem you are having (but for a ViewController rather than a model file) and shows how to both import the target and solve the access modifier problem by including the destination file in the target, meaning you don't have to make the class you are trying to test public unless you actually want to do so.

在看这篇文章的时候,我偶然发现了这篇文章,在swiftcast上写了你的第一个单元测试。克莱顿McIlrath电视。它讨论了访问修饰符,显示了一个示例相同的问题你有(但ViewController而不是模型文件)和显示了如何导入目标和解决访问修饰符的问题,包括目标中的目标文件,这意味着你不必公开课你想测试,除非你真的想这样做。