Module / Namespace in Swift

Namespacing

Namespacing is implicit in swift, all classes (etc) are implicitly scoped by the module (Xcode target) they are in. no class prefixes needed – Chris Lattner

Framework namespace

The framework name is the namespace.

When importing a framework types can be accessed implicitly or explicitly.

Fun with namespaces
Consider:

A framework FrameworkA that defines a public type Thing.

An app MyApp that imports FrameworkA.

1
2
3
4
import FrameworkA
var a : FrameworkA.Thing?
var t : Thing?

The two variables have the same type.

1
2
3
4
5
6
7
import FrameworkA
public class Thing { }
var a : FrameworkA.Thing?
var t : Thing?
var t2 : MyApp.Thing?

What is the type of t?

Namespace conflict

What if MyApp also imports a FrameworkB that also defines a public type Thing?

1
2
3
4
import FrameworkA
import FrameworkB
var a : Thing?

We get a nice error.

1
2
3
4
5
6
7
8
9
'Thing' is ambiguous for type lookup in this context
let t1 : Thing? = nil
^~~~~
FrameworkA.Thing:1:7: note: found this candidate
class Thing
^
FrameworkB.Thing:1:7: note: found this candidate
class Thing
^

Solution: use fully qualified names.

1
2
3
4
5
6
7
8
import FrameworkA
import FrameworkB
public class Thing { }
var a : FrameworkA.Thing?
var t : Thing?
var b : FrameworkB.Thing?

t is of type MyApp.Thing.

Namespace shenanigans
What if FrameworkB also defines a public type named…
FrameworkA
?

right

1
2
3
4
5
6
import FrameworkA
import FrameworkB
var a : FrameworkA.Thing?
var b : FrameworkB.Thing?
We get a misleading error: 'Thing' is not a member type of 'FrameworkA'

Workaround: define a typealias somewhere else in MyApp.

1
2
3
import FrameworkA
typealias ThingA = Thing

Then:

1
2
3
4
5
import FrameworkA
import FrameworkB
var a : ThingA?
var b : FrameworkB.Thing?

Best practices

Limit the scope* of types whenever possible.

Even more so for public types.

Don’t define a type named like the framework (Haneke oops!).

REF::