Swift package manager (spm) protocols, are not recognised in the project - swift

I just converted a git repository to Swift Package Manager (spm), all good, it compiles and I can import it in the project.
What is not good is that the project doesn't compile, is not seeing the protocol. My lib is a single generic class and i'm supposed to create an enum that implements the protocol then use the enum as a generic of the class.
enum LocalPreferences: String, RCPreferencesProtocol {
I get: Use of undeclared type RCPreferencesProtocol
Then I get further errors when trying to use the enum but i think this are only because the enum had an error:
private let localPreferences = RCPreferences<LocalPreferences>()
I get: Cannot specialize a non-generic definition
Anybody had this problem and fixed it?
Here is reference to the library is the lib for reference.

I made a stupid mistake, didn't declared the protocol and class public in the package. Strange though that the unit tests of the package passed instead giving the same error.

Related

method must be declared internal because its parameter uses an internal type

I have a public function using a public protocol as the type of its parameter and I got the error method must be declared internal because its parameter uses an internal type. The function and the protocol are in different Swift packages(targets) under same project.
Function in Swift package A:
import B
public func func1(routeDelegate: RouteDelegate)
protocol in Swift package B:
public protocol RouteDelegate {
func route(routeTerm: String?) -> String
}
I have added these 2 packages as each other's dependency in Package
I've been stuck here for a few hours. Any idea why the public protocol would be recognized as an internal type for parameter? Thanks!
Update: I tried to move both function and protocol in to same Swift package, and I no longer get the error. So it seems to me that while protocol is marked public, accessing it from same Swift package still makes it public, but accessing it from another Swift package would change it to be internal. Why?

How to declare and init nested enum with reserved keyword as type name in Swift?

I'm having a hard time to figure out how to declare a certain nested enum and calling one of it's automatic constructors. This enum i'm trying to declare is supposed to have a reserved keyword as type name.
Here is a simplified example of what i'm trying to do:
import Foundation
public class Foo {}
public extension Foo {
enum `Type`: Int {
case bar
}
}
var type: Foo.`Type`
type = Foo.`Type`(rawValue: 0)
This doesn't compile in Swift 5.2 with error
error: type 'Foo.Type' has no member 'init'
I'm pretty sure it is just a matter of getting the syntax right but i just can't figure it out. Anyone can please explain how to do it or is it just impossible all together?
There is no way to do this specific thing you want to do. That's why nobody uses nested types named Type, even though we all want to—the language already provides this type, and you don't get to override it with your own. We all use the Objective-C style naming of just smashing the word Type right up there without a proper delimiter.
FooType is what you've got to work with.

Swift namespace conflict

Consider:
A Swift framework called FrameworkA that defines the type Thing.
A Swift framework called FrameworkB that also defines the type Thing and the type FrameworkA.
An app that imports both frameworks in the same Swift file.
How do I reference FrameworkA.Thing in said file? The following line fails with Thing is not a member of FrameworkA.
let t : FrameworkA.Thing? = nil
This appears to be a Swift bug. As a workaround, you can create a new Swift file in the app that imports only FrameworkA and defines a typealias for Thing:
import FrameworkA
typealias ThingA = Thing
Then in the file that needs to import both frameworks, you use ThingA instead of FrameworkA.Thing.

class SomeClass in package x cannot be accessed in com.a.y.x

I'm attempting to un-Spring IoC several Java classes and load them directly in some Scala code. Naturally I'm finding that there are name space conflicts between a package like
com.a.x.SomeClass
and
com.a.y.x.SomeClass
I've tried using the import name space resolvers like
import com.a.y.x.{ SomeClass => YYYSomeClass }
import com.a.x{ SomeClass => XXXSomeClass }
That cleans up the imports, but referring to those classes later in the classes show the error as hovers in the Typesafe ScalaIDE, and after clean compilations.
When I compile from the gradle scala plugin, or via the Typesafe ScalaIDE with scala 2.10.2 or 2.10.3, I get the following type of un-useful error messages:
class SomeClass in package x cannot be accessed in com.a.y.x
The problem occurs if I try to use a class from com.a.y.x that doesn't have a name space conflict. If I try some of the scalac flags, I've also been able to get a Warning out that's slightly different ( during the typer stage ):
class SomeClass in package x cannot be accessed in y.this.x
I'd really like to know if there's a way to expand the first package reference. I'm having trouble setting up an Eclipse project to debug the scalac compiler and I haven't found a scalac flag that adds useful information to the error.
The error occurs when I either try to ctx.getBean("someClass").asInstanceOf[XXXSomeClass] or new XXXSomeClass.
The this reference from the warning makes me think there's some object confusion going on. I don't think it's classpath issue in the larger project I'm working on because removing one jar removes the ability to resolve imports, however I can't reproduce it with simple example classes in a separate project.
A little more information on the java classes - the different, conflicting java packages are in separate jars that were compiled by a 1.6 flavor of Java. They are top level, public classes although two are singletons with private constructors and corresponding public static getInstance() methods.
It really is an access error. I think this is just a poor error message. The java was compiled separately and accessed from jar files. I hadn't paid enough attention to the package private nature of the classes I wanted to instantiate( I had seen "public" in front of some of them and not carefully checked all of them ). The name space collisions were a red-herring in this case and actually don't affect the output of the error message.
In some cases, there are public interfaces I can use instead with a little bit of Spring-glue to instantiate the objects and load them into the Scala class.
The scalac error message would have been more helpful if it had the form:
class SomeClass in package com.a.y.x cannot be accessed in totally.unrelated
where the first package reference is the Java class's package and the trailing package is the package of the Scala class trying to instantiate the Java class.
To recap - the Java class was like:
package com.a.y.x.SomeClass
class SomeClass extends SomeOtherClass implements SomeInterface
and needs to be like:
package com.a.y.x.SomeClass
public class SomeClass extends SomeOtherClass implements SomeInterface
to not get these access errors.
Since I have more control of the Scala here, on a whim I tried changing the package of a Scala class from totally.unrelated to com.a.x.y which then compiles cleanly. As you might guess, that merely defers the error to a run time error -> java.lang.IllegalAccessError. However, the IllegalAccessError from the Java has the description/package order that I think should happen in the compilation error from scalac:
...java.lang.IllegalAccessError: tried to access class com.a.y.x.SomeClass from class s.Trouble$delayedInit$body

How do I access Java enums from Scala?

My java class is as follows
public class Test {
protected enum TestEnum {A, B, C};
public Test(TestEnum te) {
}
}
here is my Scala
class ScalaEnum(myEnum: TestEnum) extends Test(myEnum) {
}
I receive the following error message
class TestEnum in object Test cannot be accessed in object Test Access to protected class TestEnum not permitted because enclosing class class ScalaEnum in package XXX is not a subclass of object Test in package YYY where target is defined
As #Alex and #Jean-Phillipe said, this has not much to do with the fact that you're trying to access an enum and more to do with the fact that inner-class enums are implicitly static: see this answer, for example.
That means that you're running up against this limitation. Changing TestEnum to be public works around the problem for me with Scala 2.9.1.
Having said all that, despite Martin's vehement objections to removing the limitation, your code works as expected with Scala 2.10.
It sounds like the enum class is implicitly static, because Scala calls it "object Test". Try qualifying it in the constructor (e.g. Test.TestEnum), and if that doesn't work, relaxing the visibility to package access might.