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) {
}
Related
I have imported SwiftyStoreKit as well as FirebaseDatabase. Unfortunately, both pods use a class named "TransactionResult", so I can't use either.
I tried finding the Firebase source files, which is actually not a good idea, but I could not find any possibility to alter the name of their TransactionResult class. The one in SwiftyStoreKit apparently derives from the Apple's StoreKit library, so I doubt that I will be able to rename that either. What can I do in that case? Every time I use Firebase TransactionResult, I receive an "TransactionResult is ambiguous" error.
You can specify which TransactionResult class you are using by prefixing it with the module name, e.g. SwiftyStoreKit.TransactionResult and FirebaseDatabase.TransactionResult.
(the prefix should be whatever the name of the module is when you import it):
import ModuleOne
import ModuleTwo
let v1 = Swift.ClassName
let v2 = ModuleOne.ClassName
let v3 = ModuleTwo.ClassName
Hope this helps!
I have a Controller where I need to import two pods.
import Realm
import ReactiveSwift
Problem is that both have a type named Property.
Now if I use that with importing both pods then it gives me compile time error Cannot specialize a non-generic definition.
For workaround,
I created a separate file and added extension to controller with importing Realm in that only. And kept ReactiveSwift in controller file. This helps me to prevent the error. But is this the best way?
In order for the compiler to be able to decide which Property element you want to use, you have to add the namespace. In this case:
Realm.Property to use the Property element from Realm
ReactiveSwift.Property to use the Property element from ReactiveSwift
So here problem is 'Property' is available in RealmSwift as well and ReactiveSwift as well.
So here if you want to use Realm property as above answer suggest that you
can add Realm.property or ReactiveSwift.Property to access element.
Apart from it you can make typealias as well and also you can divide your code into two files using extension
Upgrading a legacy system of grails. One of the controllers implements Serializable. This is throwing the following error in newer versions of grails:
Invalid duplicate class definition of class com.regional.ScheduleController :
The source contains at least two definitions of the class.
One of the classes is an explicit generated class using the class statement,
the other is a class generated from the script body based on the file name.
Solutions are to change the file name or to change the class name.
The solution mentioned would break (previous) grails convention. Anyone know how to handle this in grails 2.5+?
EDIT
Serializable is not the issue. I tried removing it and got the same error.
I found this explanation from another question:
IN groovy.. class B{} is a class structure and defines a class B.
Scripts are classes too.
Now you may create a B.groovy, with the content "class B{}; def b = new B()".
There would be one class named B, and a script with the very same name.
This is a conflict.
However this does not explain why it runs fine below grails 2.5 and not above it. And I can't find a def conflict like the one mentioned above in that controller.
ANSWER:
One of the imports was what was actually failing- in a way that caused groovy to generate a class definition based on the current file name. When it hit the class definition, there was already an auto generated class name to collide with.
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()
I am learning objective-C and I know we can use extension to add some private members to an interface.
But the book said there should be nothing in the ()
I read the following code snippet
#interface Tree(Private)
- (void)blah:(int)num;
#end
I am wondering why there is Private inside ()
You can put any name in the class category declaration, usually indicating the purpose of that category.
So in your case author of the code wanted to tell that those methods are for internal use of the class itself and are not intented to be called from other classes
The declaration in your example is precisely called a category (not an extension).
You can add as many categories as you like to any given Class (even if you don't have access to the source code). Categories allow you to add new methods to a class, but not new ivars nor properties. [1]
Each category has a name, which is the bit between parenthesis. There should not be two different categories for the same Class with the same name.
When the name is empty, this is called an extension. Extensions have some slight differences with categories: you can add ivars and properties to extensions and you can only use them for Classes for which you have access to the source code. [1]
Usually, extensions (like the example in your book) are declared at the top of the .m file, and are used for declaring methods, ivars and/or properties that are to be used only within that file (usually comprised of a single Class).
P.D.: If you really want to add new properties through categories as opposed to through extensions you can actually do so using associated objects [2][3].
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Defining a property in iOS class extension
http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/
In the case that is considered as a category, but since it's on the .m file, it will have the same effect. You can also see the tips from Xcode:
Being the mid one considered something like Tree(description) and the last one Tree ()
There are two closely related concepts here: class categories and class extensions. Class categories include a name inside the parenthesis and are most commonly used to add methods to existing classes or to organize methods into logical groups. Class extensions extend the internal implementation of the class (i.e. are used to define private properties, methods, etc).
More details can be found on Apple's dev site:
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html