Namespaces between Swift Packages - swift

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

Related

How do you create a UTType for System Declared Uniform Type Identifiers for folder?

I see all kinds of examples for using a file or an extension but I am trying to call let imag = NSWorkspace.shared.icon(for: <#T##UTType#>) and I don't see any init method in UUType that takes a identifier e.g. folder.
UTType is declared in the Uniform Type Identifiers framework.
All uou need to do is import UniformTypeIdentifiers and then you'll be able to write things like UTType.folder.

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.

Whats the difference between different types of global declaration

I need some advice on the global declaration of variables (and hopefully functions)
What is the difference between declaring a variable like
import Foundation
var myglobalvariable = ""
and
import Foundation
struct globalvariablestruct
{
static var myglobalvariable = ""
}
and
import Foundation
class globalstructoperation {
struct glovalVariable {
static var myglobalvariable = ""
}
}
Also, I have an API, that is used around 5 times in different view controllers, would it be ok to declare it as a global function?
import Foundation
import Alamofire
func myapicall()
{
//stuff
}
Will Apple reject an app if there are (a lot of) global variables/functions?
What would be the best way to pass variables between several ViewControllers? Also, there are some variables which are used on 90% of the ViewControllers, is it OK if I declare those are global variables?
There are lots of questions in this question. I have tried to answer some of the questions. Maybe it will help you.
Approach 1
var myglobalvariable = ""
You can access these types of variables without any reference. You can
define it in any file and can access it in the current module
anywhere. So you can define it somewhere in the file outside of any
scope. There is no need for static and all global variables are
computed lazily.
Approach 2
struct globalvariablestruct{
static var myglobalvariable = ""
}
You can access these types of variables with struct name or you can say that we need to use struct name to access these varibles.
Approach 3
class globalstructoperation {
struct glovalVariable {
static var myglobalvariable = ""
}
}
You can access these types of variables with struct and class name. Also, It creates a pass by reference variable using a struct.
Also, I have an API, that is used around 5 times in different view controllers, would it be ok to declare it as a global function?
Yes, You can go with a global function or create a singleton class
for the same.
Will Apple reject an app if there are (a lot of) global variables/functions?
No, because of Apple reviewer team only checked the functionality of
our app and app do not violate any Apple policy.
What would be the best way to pass variables between several ViewControllers? Also, there are some variables which are used on 90% of the ViewcControllers, is it OK if I declare those are global variables?
Yes, You can define the n number of global variables in the project
because Apple doesn't care about the internal development methodology.
This is all about one of the object-oriented programming concepts. And here is the question is what is encapsulation?
let pi = 3.14159
The first approach is generally terrible form. If you just have a few variables in your whole project, it can be okay, but what happens when there are many many? Let's think about your project team includes 10 ios developers. What will happen when someone wants to use this global variable. How can he/she find them and understand what they are?
class MathObjects{
static let pi = 3.14159
}
print(MathObjects.pi)
I think, the better way is to encapsulate your global variables into their own class. This keeps everything all in one place and gives you the added benefit of XCodes’ handy autocomplete.

Is it possible to alias an import?

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...
}
}

Is putting your class inside a struct an acceptable way to namespace your class in Swift?

Is putting your class inside a struct an acceptable way to namespace your class in Swift? I did not see any mention of nested struct or struct-class in the programming guide.
struct TestNamespace {
class Test {
}
}
I'd be (even more) happy with namespaces in Swift, because they help organize the code more granularly. If you're experimenting with using struct as a namespace, consider disabling its construction:
struct PseudoNamespace {
private init() {}
//...
}
Using struct has an advantage over using class: structs does not support inheritance and with classes it needs using final modifier.
One significant disadvantage of this emulation is that there is no way no "import" such a namespace (like import PseudoNamespace.*, etc.), because Swift allows importing modules, but not structs.