Is it possible to alias an import? - swift

In c# when pulling in a library that has a lot of name collisions with existing code, there's a way to alias the import so you don't need to fully clarify the namespace for each use. eg:
using MyCompany.MyLibrary.Model as MMM
then you could do
MMM.MyObject
instead of
MyCompany.MyLibrary.Model.MyObject
With the recent update to swift 3.0, I've found some of my model objects are now colliding with the Foundation types, and I've been forced to prefix things that used to have an NS prefix in the class name with Foundation.classname. It would be great if I could type alias the import of my model library much like the c# example given above. Is this possible in swift 3.0? If not is there another strategy to avoid name collisions that would result in having to write the framework name in front of each type? I'm considering going back to prefixing my class names like we did in obj-c, but I'm trying to explore my options before I do that.

Update 2021 for Swift 5;
No, but you can import all and alias (in separate file), read below for more details.
Generally
You can import a particular entity as well as the entire module:
import struct­ SomeModule.SomeStruct
import class­ SomeModule.SomeClass
import func SomeModule.someFunc
See the full list of "importable" entity types in the import-kind rule of Swift grammar.
Then you can create a typealias:
typealias SMSomeStruct = SomeModule.SomeStruct
And, as of Swift 3, there is no import declaration combined with aliasing.
Considering the Collisions with Foundation Entities
Say, you have a class SomeModule.NumberFormatter.
It is enough to create two typealiases in a separate Swift file (in an importing project) to prevent collisions:
import Foundation
import SomeModule
typealias NumberFormatter = Foundation.NumberFormatter
typealias SMNumberFormatter = SomeModule.NumberFormatter

It's not even with Swift 5 possible to directly alias an import-statement!?
But fortunately, I could workaround it with something like:
import typealias MyModule.MyInnerClass
I mean, if we are the module's developer, simply move the alias into the module, like:
public typealias MyInnerClass = MyClass.MyInnerClass
public class MyClass {
public class MyInnerClass {
// Some cool logic here...
}
}

Related

Namespaces between Swift Packages

I am using two swift packages with SPM. But it appears both are defining a struct with the same name. It compiles, though it seems one struct overrides the other. How can I choose which of the structs I want to use? Is there some namespace for each package?
Thank you..
Let say you have package ‘A’ and ‘B’ and the struct name is ‘SomeModel’
You can simply
import A
import B
let modelA = A.SomeModel(…)
let modelB = B.SomeModel(…)
This is the default behavior/namespacing for different modules/packages in Swift. Though there might be an additional encapsulating/name-spacing within the package. Something like
class SomeClass {
struct SomeModel{}
}
Then you can access it with the additional encapsulation

How can I disambiguate my type from a module type

I am having troubles referring to a symbol from 3rd party module, my code looks something like this:
import Foo // 3rd party module
struct Foo { // my type on my module
//...
}
struct Bar: Foo.ProtocolA { // here swift referes to my struct instead of the module
}
I cannot only use : ProtocolA because that name is already being used in my module.
Is there a way to disambiguate this?
I have seen similar questions but they solve different thing, disambiguating a module type instead of own type.
TIA
You can fix this by importing the submodules from the parent module directly; e.g. in your example that would become something like:
import protocol Foo.ProtocolA
You can specify many types to import, like class enum let/var etc. as well, not only a protocol.
The obvious downside is that the amount of imports can balloon quickly if you need a lot of submodules from the specific parent module.
Personally I usually try to avoid naming collisions altogether, sometimes at the expensive of slightly less descriptive naming while still being understandable. Additionally as far as I know there is no way to alias imports at this time in Swift.

Access class in different file

I'm still a newbie to swift and I can't get a clear answer on a couple things.
So far I've just been using a single file in playgrounds.
If I want to use more files, how can I access data (variables and functions) from classes created there in my main file that controls the view?
From what I understand having multiple files would just be for convenience so I don't have could to write it again.
(Also on the side) what does it mean when a function has private, public or just 'func'?
I'm using swift 3 playgrounds
Thanks
Making things public will make them importable from other modules. Making it private will make it only accessible by methods within its containing scope (encapsulation). For code that lives at the top level, this scope is the entire .swift file it lives in. Without either access modifier (just bare “func”), your thing will default to internal, which means it is accessible from any other code within the same module, but not by code in a different module.
A special case is the fileprivate modifier which restricts access to the .swift file the code lives in. For code that does not live in a class or struct, this does the exact same thing as private. Some Swift designers discourage use of this modifier, and it may be removed in future versions of Swift.
There is a fifth access modifier in Swift, open, which does the exact same thing as public, except it also allows subclassing, and only applies to classes. This one is rarely used, but useful for certain library interfaces.
To import all the public symbols in a module, use
import Module
To import a single public symbol, use
import var Module.variable
import func Module.function
import struct Module.structure
import class Module.class
...

Import one class from a Swift module

Is it possible to import just one class from a Swift module? I used
import struct Foundation.Date
but now, NSString and other Foundation classes/structs are available too, at the top level!
All I really want is the Date class, to avoid polluting the namespace.
This answer is originally made for objective-c but the behaviour is the same: Why does a simple program import <Foundation/Foundation.h> instead of individual header files?
You don't have to worry about that, I think your compiler do this job perfectly ! :)

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.