I'm trying to use classes and reference them within each other. Unfortunately I can't seem to figure it out how. What I try to do is:
Create a module exporting classes in different files. One of the classes has a method which returns another class.
Import the module in another class and make use of the classes from the module.
What I tried (simplified example):
Item.ps1
class Item {
}
ItemList.ps1
. '.\Item.ps1'
class ItemList {
[Item] function Items () {
// It goes wrong here. Visual studio code mentions type Item cannot be found.
}
}
Utilities.psm1
. '.\Item.ps1'
. '.\ItemList.ps1'
// I'm not sure if this is the right way to export the classes via the module
Foo.ps1
using module '.\Utilities.psm1'
class Foo {
[ItemList] function CreateItemList() {
// It goes wrong here. Visual studio code mentions type ItemList cannot be found.
}
}
I would really appreciate if some could help me figure this out!
Update
It looks like it can't be done. Here the following is mentioned:
In this release, you can't use a type literal (for example, [MyClass]) outside the script/module file in which the class is defined.
For example, I have two files called file1.swift and file2.swift.
file1.swift:
import UIKit
class A: B {
}
file2.swift:
import UIKit
class C: A{
}
I am reading that public class can not subclassed outside of module. Here I have subclass C. I am trying to understand what does module mean here. I imported to same module UIKit for both file. So the both files are of same module? So that I can subclassed. Or both files have different module even I import the same UIKit?
Can anybody explain what is module?
Source:
Classes with public access, or any more restrictive access level, can be subclassed only within the module where they’re defined.
Class members with public access, or any more restrictive access level, can be overridden by subclasses only within the module where they’re defined.
A module is a single unit of code distribution—a framework or application that is built and shipped as a single unit and that can be imported by another module with Swift’s import keyword.
Each build target (such as an app bundle or framework) in Xcode is treated as a separate module in Swift. If you group together aspects of your app’s code as a stand-alone framework—perhaps to encapsulate and reuse that code across multiple applications—then everything you define within that framework will be part of a separate module when it’s imported and used within an app, or when it’s used within another framework.
As the docs indicate, the module is an application or a framework (library). If you create a project with classes A and B, they are part of the same module. Any other class in the same project can inherit from those classes. If you however import that project to another project, classes from that another project won't be able to subclass A nor B. For that you would have to add open indicator before their declarations.
Basically, if you work on a single app then you are working in one single module and unless declared as private or fileprivate, the classes can subclass each other.
EDIT
Let us have following class in module (project) Module1:
class A {
}
Since this class is not open, it can be subclassed only within the same module. That means that following class:
class B: A {
}
Can be written only in the same project, in Module1.
If you add Module1 as a dependency to project Module2, and try to do this:
import Module1
class C: A {
}
It will not compile. That's because class A is not open (in other words it has access public or less) and it does not belong to the same module as C. A belongs to Module1, C belongs to Module2.
Note
import keyword imports a dependency module to your current module. If you write import UIKit in your project, you are telling the compiler that you want to use module UIKit in your module. import does not define current module. Current module is the current project.
Adding import UIKit at the beginning of the file does not change nor define to which module the file belongs. It just tells the compiler that in that file you want to use code from UIKit module.
Swift module(.swiftmodule)
History:
[#include -> #import] -> [Precompiled Headers .pch] -> [#import Module(ObjC);] -> import Module(Swift)
There are two type of Module - folder and file
.swiftmodule folder. Folder contains all .swiftmodule files for architectures and other meta information like:
.swiftmodule file. It is binary file format which contains Abstract Syntax Tree(AST) or Swift Intermediate Language(SIL) of framework's public API.
.swiftdoc - attached docs which can be revived by consumer
.swiftinterface - Module stability
[.swiftinterface or Swift Module Interfaces] is a next step of improving closed source compatibility
When you Jump to Definition of imported module actually you reviewing public interface of .modulemap
Binary(library, framework) can contains several modules, each module can contains a kind of submodule(from Objective-C world) thought.
import struct SomeModule.SomeStruct
These modules can have dependencies between each others.
Module is a set of source files which solves the same problem that is why they can be grouped under the same model name.
Module helps to group sources to reuse them
Module helps Xcode to minimize build time(open source)(If module was not changed it should not been recompiled)
Also Module is a kind of scope which can help compiler to figure out which exactly class to use. If two modules use the same name you get
Ambiguous use of 'foo()'
It can be solved by:
import ModuleName1
import ModuleName2
func someFunc() {
ModuleName1.SomeClass.foo()
ModuleName2.SomeClass.foo()
}
I simply want to include my Swift class from another file, like its test
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'"
}
Both swift files are in the same directory.
I had the same problem, also in my XCTestCase files, but not in the regular project files.
To get rid of the:
Use of unresolved identifier '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.
UPDATE Swift 2.x, 3.x, 4.x and 5.x
Now you don't need to add the public to the methods to test then.
On newer versions of Swift it's only necessary to add the #testable keyword.
PrimeNumberModelTests.swift
import XCTest
#testable import MyProject
class PrimeNumberModelTests: XCTestCase {
let testObject = PrimeNumberModel()
}
And your internal methods can keep Internal
PrimeNumberModel.swift
import Foundation
class PrimeNumberModel {
init() {
}
}
Note that private (and fileprivate) symbols are not available even with using #testable.
Swift 1.x
There are two relevant concepts from Swift here (As Xcode 6 beta 6).
You don't need to import Swift classes, but you need to import external modules (targets)
The Default Access Control level in Swift is Internal access
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:
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.swift
import Foundation
public class PrimeNumberModel {
public init() {
}
}
In the Documentation it says there are no import statements in Swift.
Simply use:
let primNumber = PrimeNumberModel()
Check target-membership of PrimeNumberModel.swift in your testing target.
In Objective-C, if you wanted to use a class in another file you had to import it:
#import "SomeClass.h"
However, in Swift, you don't have to import at all. Simply use it as if it was already imported.
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.
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.
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
I was able to solve this problem by cleaning my build.
Top menu -> Product -> Clean
Or keyboard shortcut: Shift+Cmd+K
As of Swift 2.0, best practice is:
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.
(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.)
Check your PrimeNumberModelTests Target Settings.
If you can't see PrimeNumberModel.swift file in Build Phases/Compile Sources, add it.
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
PrimeNumberModelTests()
Then compile on the command line (I am using El Capitan and 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.
So, you need to
Import external modules you want to use
And make sure you have the right access modifiers on the class and methods you want to use.
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
import stMobile
(let's say that stMobile is our target name)
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
import St_Mobile
(which is the Product Module Name), and everything worked.
So, to sum up:
Check your Product Module Name and use the import statement below in you unit test class
import myProductModuleName
Make sure your access modifiers are correct (class level and your methods).
Instead of requiring explicit imports, the Swift compiler implicitly searches for .swiftmodule files of dependency Swift libraries.
Xcode can build swift modules for you, or refer to the railsware blog for command line instructions for swiftc.
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.
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.
I'm writing a dart file:
import 'something.dart'
part of my_lib;
class A{
//...
}
I have tried this with the import and part of directives reversed and it still won't work, can you not have a class file as part of a library and have imports?
All your imports should go in the file that defines the library.
Library:
library my_lib;
import 'something.dart';
part 'a.dart';
class MyLib {
//...
}
a.dart
part of my_lib;
class A {
//...
}
Since a.dart is part of my_lib it will have access to any files that my_lib imports.
The Pixel Elephanr's answer is correct, but I suggest the alternative syntax for the part-of directive:
my_file.dart
(the library main file):
//This now is optional:
//library my_lib;
import 'something.dart';
part 'a.dart';
class MyLib {
//...
}
a.dart
(part of the same library; so in it you can reference the elements imported in my_file.dart)
//Instead of this (whitout quotes, and referencing the library name):
//part of my_lib;
//use this (whit quotes, and referencing the library file path):
part of 'my_file.dart'
class A {
//...
}
In the Doc you can found both the syntax, but only using the part-of's syntax with quotes (pointing to the file path), you can omit the library directive in the library main file; or, if the library directive is still needed for other reasons (to put doc and annotations to library level), at least you won't be forced to keep in sync the library name in multiple files, which is boring in case of refactoring.
If you are facing this in IntelliJ IDEA or Android Studio while moving the files via drag and drop, then switch to 'Project Source' in project pane at left and then move(drag and drop). When I faced this problem while working with flutter, this worked for me.
I added the Facebook sdk code to my project then I got this error because I already had a json library, so I deleted the Facebook json library from my computer and from the project but I still get this error. I search the whole project for "#interface SBJsonBase" and I only get one result. How can it say it's a duplicate when I only have one interface? Is it including the file twice? Does the search not always find everything?
May be this helps? Delete your derived data and do a clean project, then try to build again
I had a simular problem. It was a small search, but I could solve it without creating a new project etc...
The thing was I had a Class B that was importing Class A.
Then I had a class that imported Class B and also Class A.
When I did this, these problems occured.
Eg. A SOAP webservice Class imports all the Entities that are passed over the web.
Class goToSchoolWebservice.
import "person.h"
import "school.h"
...
Then I had a Singleton class used for caching that had the Logged in Person and also a ref to the webservice class.
import "person.h"
import "goToSchoolWebservice.h"
--> this is where is went wrong!!
So watch out for these circular references. ITs not so easy to detect them!
if your using #include instead of import then use this technique to minimize duplicates: at the begining of your interface (actually right before it) do check for a definition and if not defined then define it and proceed to define your interface. here is an example:
#ifndef __NetworkOptionsViewController__H // check if this has every been imported before
#define __NetworkOptionsViewController__H
#import "blahblah.h"
#interface NetworkOptionsViewController : UITableViewController
{
NSMutableArray* somevariable1;
int somevariable2;
}
#end
#endif
-- for me personally, i got this error though because the file path to my class was wrong. I checked file inspector and my class file was not defined in Classes folder even though the IDE said it was. I deleted them and copied them over again.
For those that still get this error, despite following header import conventions: I got this error from importing a header that had been deleted from the project. The missing header was instead found in an old backup of my project in dropbox (That I made before doing some destructive stuff in Git), and that file caused the circular import.
I solved a similar problem by moving all the imports to the prefix header file.