I created a Swift framework, just a simple test.
The Swift file (F1.swift) code:
public class F1{
public init(){
print("inited")
}
public func call(){
print("called")
}
}
Then, I built the framework and I imported it into another project.
I tried to use it this way:
import F1
in the viewDidLoad of a UIViewController:
var c = F1()
c.call()
The F1.framework has been dragged under:
General > Embedded Binaries
General > Linked Frameworks and Binaries
and I can also see it under:
Build Phases > Link Library With Binaries
Build Phases > Embed frameworks
The XCode "reaction": no issues with the import statement.
I receive an error exactly where the class is instantiated:
Cannot call value of non-function 'module...'
Am I missing something?
[update] Based on some online resources and some other test, I'm supposing the problem lies in Build settings: eg. Build Active Architecture Only could be involved, but it would be interesting to understand how and why.
Find minimal sample Xcode project here.
Using your posted code gives the expected results here:
inited
called
In your example you've named the single class in your module F1 to the same name as the module, namely F1. Most likely Swift can't differentiate between module namespacing and the actual name of your class in the module, so when you just write F1, Swift possibly infers this to be an explicit namespacing annotation; refering to the namespace F1 (made available by your import of module F1). A namespace can naturally not be treated as a type, which would explain the error message you're prompted with ([emphasis mine])
Cannot call value of non-function 'module...'
You may test this theory by explicitly calling the class F1's initializer of module F1, by including both the module namespace and its (single) class type in the call:
var c = F1.F1()
Related
I have an enum in one of my Swift files called Foo.
One of the Cocoapods called NameA also has the same enum with name Foo (public enum, not inside any class).
This module also has a class with the same name as its framework NameA.
If I try to refer to Foo in NameA module like this:
NameA.Foo
It doesn't work because the compiler thinks I'm referring to the class NameA, but not the module NameA.
The workaround posted here wont work for me either Swift namespace conflict
This seems to be a reported bug in swift:
https://bugs.swift.org/browse/SR-898
Don't import NameA.
Instead, import enum NameA.Foo (notice the keyword "enum", can also be used for "struct" or "class" or "func")
Reference either Foo (your enum) or NameA.Foo (their enum).
If you need to reference NameA in the same file as NameA.Foo:
Create a new file for your "wrapper" type:
import NameA
typealias NameAWrapper = NameA
Reference the class NameA as NameAWrapper in your other files without importing the module directly.
This was inspired by this workaround (which you linked to), but modified slightly based on your situation: https://stackoverflow.com/a/26774102/358806
I ran into a similar issue recently. You won't like the solution I found, but I'll share it anyway. I had to fork the pod I was using and rename it to something new. The new project name no longer conflicted with the class name and I was able to namespace it as MyForkedName.ClassName. This is really an inconvenient way to do it, but in our case it was an older library that hadn't changed in some time (and one we will be removing altogether in the future) so I was willing to settle for now.
If you want to use enum from other module like Cocoapods or some framework you have to use this approach,
suppose I have enum Result defined in my project and same in some other module. You want to use both enum in same file then-
import enum MyFramework.Result
func doSomething(callback: (Result<Data>) -> Void) {
}
func doSomething1(callback: (MyFramework.Result<Data>) -> Void) {
}
I have an iOS application written in Obj-C which has unit tests defined as well. Now, i am adding a new feature where i am using a swift class (S) in an Obj-C class(O). I have the bridging header in place for both the main target and the test target. Till this point everything works really well.
Here's the problem,
If i want to create an unit test class(U) for class O in swift and run it, i get an issue saying bridging header not found. I am assuming this is because O uses S and these details are in the bridging header file and then again i am trying to use both S and O in U resulting the failure. If i add any other Obj-C class which doesn't use S, it works perfectly fine.
Here's what i have already done just make sure you know whats happening,
I have a forward declaration in O.h for class S because i know the O.h file will not support holding the -Swift.h import statement and hence it is in O.m file.
Is this scenario supported?
Class O uses Class S.
Class U can test class O by using class S.
Note: O->Objective-C
S->Swift Class
U->Unit test class in swift.
The answer was simple but not very evident. I had to place the import statements in the bridging header files in the order of the usage. For example: if one class has dependency on the other, then its important that you place the dependency's import statement first and then the calling class' file in the bridging header
Using swift I created a framework Common that contains functions and protocols I use repeatedly to cut down on code reuse.
Common.framework
public protocol CommonProtocol {}
I than created a framework that I want to share with others which includes some classes that extends CommonProtocol and passes CommonProtocol in response to some function calls.
Sharable.framework
public class Sharable : CommonProtocol {
func getCommon() -> CommonProtocol
}
Unfortunately when I attempt to use Sharable.framework in a Project I get there error:
Swift Compiler ErrorUse of undeclared type 'CommonProtocol'
Does anyone know how to make the protocol visible to Modules that use the Sharable.framework?
I am copying the frame Common.framework in the Copy Files step to Destination Frameworks (there was no noticeable change when I made it Shared Frameworks)
If possible I would prefer to only make certain protocols from Common.framework visible through Sharable.framework and I don't want to force my users to import multiple frameworks if I can avoid it.
I tried to include a class called 'name' and I got an error:
Swift Compiler Error: Use of unresolved identifier 'name'
The class exists and doesn't contain any compile errors.
There could be a few possible issues.
One of the classes has a Testing target and other one doesn't. You have to even include all of your classes in the testing target or none of them.
If it's Objective C class, check that the class is in ObjectiveC bridging header file.
If it's NSManagedObject subclass. Add #objc(className) before the class declaration.
If it's part of a different framework, make sure that the class or function is public
I had this one too. You will probably find that your first class is included in your testing module and that "name" isn't. Simply, if you include a class in testing, then every class that it references has to be in testing.
I had this problem too. I was trying to reference Class 1 within the code in Class 2. My problem was that Class 2 had target memberships in A and B, and Class 1 only had Target Memberships in Class A.
You can fix this by opening the Utilities Tab (farthest right button on the top bar of the Xcode window), and make sure that the same boxes are checked for both classes in the Target Membership subsection.
Got problem solved by
Target -> Build Phases -> Compile Sources -> Adding the class file
Add one more to the list.
If it is part of another framework, make certain that the "Build Active Architecture Only" settings are the same.
As the IBDesignable attribute needs the designable class to be in a seperate target I created a second target which worked great in the designer. When I then tried to use the new class in my code I get the error
"Use of unresolved identifier 'CustomMarker'"
I have imported the second target in my main target -- import CustomViews -- and I can cmd+click the target name to see the main .h file that describes the target; where the class is included. The compiler still can't find the class in my code though.
Any thoughts?
I had the same issue. Fixed this by changing access modifier of the class to public.
#IBDesignable public class MyCustomView: UIView {
}
By default classes and methods will be at internal access level. If you want to use that out side of the target, you should mark it as public. Then only it will be the part of public interface(visible to outside of target)
second target must be of type "framework".
you must also link it in build phases like as an external framework. link binary with libraries must have a link to your customViews framework and embed framework must have that link too.
that should be enough.