Làm cách nào để nhập tệp Swift từ tệp Swift khác?


154

Tôi chỉ đơn giản muốn bao gồm lớp Swift của mình từ một tệp khác, như thử nghiệm của nó

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'"    
}

Cả hai tập tin swift đều trong cùng một thư mục.



2
Theo tài liệu apple bạn không cần nhập khi cả hai tệp có cùng mục tiêu. Đáng buồn là các bài kiểm tra có một mục tiêu khác nhau. Một giải pháp khả thi có thể là thực hiện một câu lệnh nhập bằng yourModule / PrimeNumberModel.
Alex Reynold

@ joseph.hainline Tôi đang đối mặt với vấn đề tương tự. Làm thế nào nó sẽ được giải quyết? Tôi đang bị mắc kẹt bây giờ.
Nhà phát triển

Câu trả lời:


131

Tôi đã có cùng một vấn đề, cũng trong XCTestCasecác tệp của tôi , nhưng không phải trong các tệp dự án thông thường.

Để thoát khỏi:

Sử dụng số nhận dạng chưa được giải quyết 'PrimeNumberModel'

Tôi cần đến importmô-đun cơ sở trong tệp thử nghiệm. Trong trường hợp của tôi, mục tiêu của tôi được gọi là 'myproject' và tôi đã thêm import myprojectvà lớp được công nhận.


2
Điều này cần nhiều upvote. Các câu trả lời khuyên bạn chỉ nên thêm tệp .swift vào mục tiêu thử nghiệm không hoàn toàn sai, nhưng đó không phải là cách nó nên được thực hiện
dưới

10
Nhưng phải làm gì với tên dự án của tôi "Liên minh động vật hoang dã", nơi có không gian trong đó?
allenlinli

59
Bắt đầu với Beta 4, bạn cũng cần đảm bảo các cài đặt kiểm soát truy cập của mình là chính xác. Bạn sẽ cần khám phá đặt cả lớp bạn đang kiểm tra và các chức năng bạn đang kiểm tra trong lớp đó là public. Nếu không, XCTestCaselớp con sẽ không thể "nhìn thấy" những gì bạn đang cố kiểm tra. Tôi đã lãng phí một vài giờ vào tối qua :)
Erik P. Hansen

2
Nếu tôi không nhầm, Tên Mô-đun sản phẩm (trong cài đặt xây dựng mục tiêu) không phải luôn giống với tên của mục tiêu và đó là tên mô-đun nên được sử dụng trong importtuyên bố
csch

3
Nếu mục tiêu Swift có một khoảng trắng trong tên của nó, bạn có thể nhập nó bằng cách thay thế khoảng trắng bằng dấu gạch dưới trong câu lệnh nhập. "Lớp Swift của tôi" trở thành "My_Swift_Class".
Cin316

70

CẬP NHẬT Swift 2.x, 3.x, 4.x và 5.x

Bây giờ bạn không cần thêm publiccác phương thức để kiểm tra. Trên các phiên bản mới hơn của Swift, chỉ cần thêm @testabletừ khóa.

PrimeNumberModelTests.swift

import XCTest
@testable import MyProject

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

Và phương pháp nội bộ của bạn có thể giữ Internal

PrimeNumberModel.swift

import Foundation

class PrimeNumberModel {
   init() {
   }
}

Lưu ý rằng các ký hiệu private(và fileprivate) không khả dụng ngay cả khi sử dụng @testable.


Swift 1.x

Có hai khái niệm liên quan từ Swift ở đây (Như Xcode 6 beta 6).

  1. Bạn không cần nhập các lớp Swift, nhưng bạn cần nhập các mô-đun (mục tiêu) bên ngoài
  2. Cấp độ Kiểm soát truy cập mặc định trong Swift làInternal access

Xem xét rằng các bài kiểm tra nằm trên một mục tiêu khác PrimeNumberModelTests.swiftmà bạn cần đến importmục tiêu có chứa lớp mà bạn muốn kiểm tra, nếu mục tiêu của bạn được gọi MyProjectsẽ cần phải thêm import MyProjectvào PrimeNumberModelTests:

PrimeNumberModelTests.swift

import XCTest
import MyProject

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

Nhưng điều này là không đủ để kiểm tra lớp của bạn PrimeNumberModel, vì mức Kiểm soát truy cập mặc định là Internal Access, lớp của bạn sẽ không hiển thị với gói kiểm tra, vì vậy bạn cần phải thực hiện nó Public Accessvà tất cả các phương thức mà bạn muốn kiểm tra:

PrimeNumberModel.swift

import Foundation

public class PrimeNumberModel {
   public init() {
   }
}

Có cách nào để thay đổi Kiểm soát truy cập mặc định không? Tôi đã có một trường hợp hài hước rằng nó được sử dụng để chạy mà không cần sửa đổi công khai chỉ là tốt, sau đó tôi di chuyển các trường hợp thử nghiệm xung quanh, nó đột nhiên ngừng hoạt động nữa.
Metaphox

Tôi nghĩ điều đó là không thể, ít nhất là đối với phiên bản swift hiện tại.
Diogo T

cảm ơn. Và tôi phát hiện ra rằng vấn đề của tôi là tệp swift không được xây dựng cho mục tiêu thử nghiệm với các trường hợp thử nghiệm.
Metaphox

1
vâng, đó chính xác là nơi tôi cảm thấy sai - Tôi không nên xây dựng tệp swift lớp vào mục tiêu trường hợp thử nghiệm. bài đăng blog tốt đẹp! cảm ơn.
Metaphox

1
Nếu bạn có một dự án được tạo bằng Xcode 5 trở lên và bạn đang chọn cách tiếp cận "truy cập công khai, nhập mô-đun đích", hãy kiểm tra kỹ tên mô-đun cho mục tiêu thử nghiệm của bạn vì nó có thể giống với mục tiêu chính. Nếu bạn đang nhận được một No such module <moduleName>lỗi biên dịch trong trường hợp thử nghiệm của mình, bạn có thể muốn kiểm PRODUCT_MODULE_NAMEtra mục tiêu thử nghiệm. Câu trả lời tuyệt vời Diogo.
Chris

48

Trong Tài liệu có ghi rằng không có báo cáo nhập trong Swift.

nhập mô tả hình ảnh ở đây

Đơn giản chỉ cần sử dụng:

let primNumber = PrimeNumberModel()

2
Điều này đã làm việc nhưng tôi đã phải đóng và mở lại Xcode 6.0 để lớp cuối cùng xuất hiện. Hãy thử làm sạch và xây dựng dự án là tốt.
dùng344977

Điều này dường như là mới (hoặc là một vấn đề) trong phiên bản XCode 6.3 beta mới nhất, vì vậy, báo cáo nhập khẩu hiện không cần thiết. Ngoài ra, có một câu lệnh nhập trong Swift, để nhập các mô-đun.
Augunrik

Theo tài liệu được cung cấp, bảng này với "Không có câu lệnh nhập" có liên quan đến trường hợp "Nhập từ cùng một mục tiêu". Trong trường hợp XCTests bạn sử dụng mục tiêu (thử nghiệm) khác nhau, vì vậy hãy quan sát phần "Nhập khung bên ngoài" của bài viết, có một bảng khác: Bất kỳ khung ngôn ngữ nào -> Nhập vào Swift -> nhập "FrameworkName" là cần thiết
Igor Vasilev

Nếu bạn thấy một vấn đề trong trình soạn thảo, thì thường có mục tiêu kiểm tra không bao gồm lớp. Vì vậy, bạn có thể xây dựng mức phạt có thể chạy được của mình, nhưng nếu bất kỳ một trong các mục tiêu đang gặp sự cố, nó vẫn hiển thị lỗi. Nếu bạn đã chọn một trong những mục tiêu khác, nó sẽ không cho phép bạn biên dịch.
Joel Teply

34

Kiểm tra tư cách thành viên mục tiêu của PrimeNumberModel.swift trong mục tiêu thử nghiệm của bạn.


1
xin vui lòng thêm điều này như bình luận.
4dgaurav

8
Người này không thể, anh ta cần thêm 9 đại diện để làm như vậy (tại thời điểm viết bài).
AlbertEngelB

1
Cái quái gì là mục tiêu?
Người dùng

Cảm ơn điều này đã làm việc cho tôi. Bấm vào tập tin lớp. Kiểm tra tab đầu tiên của cột thanh tra bên phải. Phần thứ hai là "Thành viên mục tiêu". Đảm bảo mục tiêu / sản phẩm bạn đang cố gắng bao gồm lớp được chọn.
Hairgami_Master

1
Đây không hoàn toàn là một câu trả lời cho câu hỏi "làm thế nào để tôi nhập ...", nhưng nó đã trả lời câu hỏi tôi đã đưa tôi đến đây (tôi quên không thêm một tệp mới vào mục tiêu). Vì vậy, đối với tôi và những người khác sẽ đến đây bằng cách theo dõi kết quả google đầu tiên cho "lớp định danh nhanh chưa được giải quyết", đây một câu trả lời (và không phải là nhận xét).
noamtm

17

Trong Objective-C, nếu bạn muốn sử dụng một lớp trong một tệp khác, bạn phải nhập nó:

#import "SomeClass.h"

Tuy nhiên, trong Swift, bạn hoàn toàn không phải nhập. Đơn giản chỉ cần sử dụng nó như thể nó đã được nhập khẩu.

Thí dụ

// This is a file named SomeClass.swift

class SomeClass : NSObject {

}

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

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

Như bạn có thể thấy, không cần nhập. Hi vọng điêu nay co ich.


Cảm ơn! Vẫn nhận được tất cả những thứ mới này từ Swift.
Felipe

5

Theo Apple, bạn không cần nhập dữ liệu cho các tệp nhanh trong cùng một mục tiêu. Cuối cùng tôi đã làm cho nó hoạt động bằng cách thêm tệp nhanh chóng của mình vào cả mục tiêu thường xuyên và mục tiêu thử nghiệm. Sau đó, tôi đã sử dụng tiêu đề bắc cầu để kiểm tra để đảm bảo các tệp ObjC mà tôi đã tham chiếu trong tiêu đề bắc cầu thông thường có sẵn. Ran như một cơ duyên bây giờ.

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.
    }
}

}

Vì vậy, hãy đảm bảo PrimeNumberModel có mục tiêu là Mục tiêu thử nghiệm của bạn. Hoặc giải pháp High6 nhập toàn bộ mô-đun của bạn sẽ hoạt động


Có phải điều này chỉ hoạt động cho các lớp logic / mô hình hoặc tôi cũng có thể sử dụng nó cho Đại biểu ứng dụng không?
Nicolas Miari

5

Tôi đã có thể giải quyết vấn đề này bằng cách làm sạch bản dựng của tôi.

Menu trên cùng -> Sản phẩm -> Làm sạch Hoặc phím tắt: Shift+ Cmd+K


4

Kể từ Swift 2.0, thực tiễn tốt nhất là:

Thêm dòng @testable import MyAppvào đầu tệp thử nghiệm của bạn, trong đó "MyApp" là Tên Mô-đun sản phẩm của mục tiêu ứng dụng của bạn (có thể xem trong cài đặt bản dựng của mục tiêu ứng dụng của bạn ). Đó là nó.

(Lưu ý rằng tên mô-đun sản phẩm sẽ được giống như tên mục tiêu ứng dụng của bạn trừ khi tên mục tiêu ứng dụng của bạn có chứa khoảng trắng, mà sẽ được thay thế bằng dấu gạch dưới. Ví dụ, nếu mục tiêu ứng dụng của tôi được gọi là "trò chơi vui nhộn" Tôi muốn viết @testable import Fun_Gametại đầu bài kiểm tra của tôi.)


1

Bạn cần thêm một thói quen để trình biên dịch tham chiếu làm điểm vào, vì vậy hãy thêm tệp main.swift, trong trường hợp này chỉ cần tạo một phiên bản của tệp thử nghiệm của bạn:

chính

PrimeNumberModelTests()

Sau đó biên dịch trên dòng lệnh (Tôi đang sử dụng El Capitan và Swift 2.2):

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

Trong trường hợp này, bạn sẽ nhận được cảnh báo: kết quả của trình khởi tạo không được sử dụng , nhưng chương trình biên dịch và có thể thực thi được:

./PrimeNumberMain

CAVEAT: Tôi đã loại bỏ kiểu nhập XCTest và XCTestCase để đơn giản.


1

Kiểm tra PrimeNumberModelTestsCài đặt mục tiêu của bạn .

Nếu bạn không thể thấy PrimeNumberModel.swifttệp trong Build Phases/Compile Sources, hãy thêm nó.


Đây không phải là cách đúng đắn để làm điều đó, hãy kiểm tra phản hồi High6.
Diogo T

0

Vì vậy, bạn cần phải

  1. Nhập các mô-đun bên ngoài bạn muốn sử dụng
  2. Và hãy chắc chắn rằng bạn có các công cụ sửa đổi truy cập phù hợp trên lớp và các phương thức bạn muốn sử dụng.

Trong trường hợp của tôi, tôi đã có một tệp nhanh chóng tôi muốn kiểm tra đơn vị, và tệp kiểm tra đơn vị cũng là một lớp nhanh chóng. Tôi chắc chắn rằng các sửa đổi truy cập là chính xác, nhưng tuyên bố

import stMobile

(giả sử stMobile là tên mục tiêu của chúng tôi)

vẫn không hoạt động (tôi vẫn nhận được lỗi 'Không có mô-đun như vậy'), tôi đã kiểm tra mục tiêu của mình và tên của nó thực sự là stMobile. Vì vậy, tôi đã đi đến Cài đặt bản dựng, trong bao bì và tìm thấy Tên mô-đun sản phẩm và vì một số lý do, nó được gọi là St_Mobile, vì vậy tôi đã thay đổi câu lệnh nhập khẩu của mình

import St_Mobile

(đó là Tên Mô-đun Sản phẩm ) và mọi thứ đều hoạt động.

Vì vậy, để tổng hợp:

  1. Kiểm tra Tên mô-đun sản phẩm của bạn và sử dụng câu lệnh nhập bên dưới trong lớp kiểm tra đơn vị của bạn

    import myProductModuleName
  2. Hãy chắc chắn rằng công cụ sửa đổi truy cập của bạn là chính xác (cấp độ lớp và phương thức của bạn).


0

Thay vì yêu cầu nhập rõ ràng, trình biên dịch Swift ngầm tìm kiếm .swiftmodulecác tệp của thư viện Swift phụ thuộc.

Xcode có thể xây dựng các mô-đun swift cho bạn hoặc tham khảo blog railsware để biết hướng dẫn về dòng lệnh cho swiftc.


0

Như @ high6 và @ erik-p-hansen đã chỉ ra trong câu trả lời được đưa ra bởi @ high6, điều này có thể khắc phục bằng cách nhập mục tiêu cho mô-đun có lớp PrimeNumberModel, có lẽ cùng tên với dự án của bạn trong một dự án đơn giản .

Trong khi xem xét điều này, tôi đã xem qua bài viết Viết bài kiểm tra đơn vị đầu tiên của bạn trong Swift trên swiftcast.tv của Clayton McIlrath. Nó thảo luận về các công cụ sửa đổi truy cập, hiển thị một ví dụ về cùng một vấn đề bạn đang gặp phải (nhưng đối với ViewContoder chứ không phải tệp mô hình) và chỉ ra cách nhập mục tiêu và giải quyết vấn đề sửa đổi truy cập bằng cách đưa tệp đích vào mục tiêu, nghĩa là bạn không phải làm cho lớp bạn đang cố kiểm tra công khai trừ khi bạn thực sự muốn làm như vậy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.