---
title: Swift Imports
teaser: 'How to be a Swift importer (and possibly exporter).

  '
tags: swift,ios
author: Patrick Montalto
published_on: 2017-10-11
---

If you’ve been developing applications in Swift for any length of time,
you’ve grown accustomed to often having one or more lines of text at the top of
your file. No, I’m not talking about the Xcode generated commented-out metadata
when you make a new Swift file (if you’re like me and don’t particularly care
for it either, [we’ve got you covered](https://thoughtbot.com/blog/creating-custom-xcode-templates))
— I’m talking about our friend the *import declaration.*

![](https://images.thoughtbot.com/blog-vellum-image-uploads/0JCzPqn7SWiCM2bymlPV_Group.png)

Let’s take a look at Swift import declarations.

We’ve all seen this many times:

```swift
import UIKit
```

But this also works:

```swift
import UIKit.UITableViewController

let tvc = UITableViewController()
let vc = UIViewController()
let label = UILabel()
```

And this...almost works:

```swift
import class UIKit.UITableViewController

let tvc = UITableViewController()
let vc = UIViewController() // Error
let label = UILabel() // Error
```

## Why?

In these contexts, `UITableVIewController` in our import statement are actually
referring to two different things. Let’s look at the Swift documentation.

    import [module]
    import [module].[submodule]
    import [import kind] [module].[symbol name]

In our first example we’re just importing the `UIKit`  module as usual — no
funny business going on there. In our second example, we’re actually importing
the entire `UITableViewController` *submodule*, whereas in our last example
we’re explicitly importing only a *class* that has the *symbol name*
of `UITableViewController`.

If we inspect the submodule `UITableViewController` we see it imports the
entire umbrella header for  `UIKit`:

```swift
import Foundation
import UIKit
import _SwiftUIKitOverlayShims

//
//  UITableViewController.h
//  UIKit
//
//  Copyright (c) 2008-2017 Apple Inc. All rights reserved.
//

// Creates a table view with the correct dimensions and autoresizing, setting the datasource and delegate to self.
// In -viewWillAppear:, it reloads the table's data if it's empty. Otherwise, it deselects all rows (with or without animation) if clearsSelectionOnViewWillAppear is YES.
// In -viewDidAppear:, it flashes the table's scroll indicators.
// Implements -setEditing:animated: to toggle the editing state of the table.

@available(iOS 2.0, *)
open class UITableViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
...
```

Hence why when we do not specify the *import kind* while importing
`UITableViewController`, we’re actually still just importing the entirety
of `UIKit`.

Note that there are multiple permissible import kinds available:

    typealias | struct | class | enum | protocol | let | var | func

## When?

Although there are limited cases when you may explicitly need to specify the
import kind and symbol name, it does help remove excessive symbols you may not
need in the particular file you’re working in. As far as performance and binary
size goes, any unused symbols are already optimized out of the final binary by
the Swift compiler. If there’s no reference to it at compile time then it’s
removed, meaning that importing a framework but not using particular parts
of it shouldn’t have any negative implications.

Besides decluttering Xcode’s code completion, there is one scenario where it
does offer a distinct advantage: modules which both define a particular type
of the same name.

Consider two frameworks, `FrameworkA` and `FrameworkB`. For the sake of
simplicity, they both implement a struct called `Foo`, but have different
behavior. What happens if we import both frameworks?

```swift
import FrameworkA
import FrameworkB

func example() {
  let myFoo = Foo(baz: 3) // Using FrameworkA's implementation
  let myFooAgain = Foo(bar: "test") // Using FrameworkB's implementation

  myFoo.doThingFromFrameworkA()
  myFooAgain.doThingFromFrameworkB()
}
```

Both local variables are of type `Foo`, but come from different modules. This
could be confusing…particularly if we didn’t intend on using FrameworkA’s
implementation of `Foo`. What can we do if we only wanted to use a different
part of the framework?

```swift
import struct FrameworkA.ThingA
import FrameworkB

func example2() {
  let myFoo = Foo(baz: 3) // Error: Now FrameworkA's definition of Foo is not in scope
  let myFooAgain = Foo(bar: "test") // Still Using FrameworkB's implementation

  let thing = ThingA() // But we still have access to ThingA from FrameworkA!
  myFooAgain.doThingFromFrameworkB()
}
```

Now there’s no longer two `Foos` in scope, and we’re explicitly only importing
what we intend to use from `FrameworkA`. Nice!

## Export an import?

Before we conclude our spotlight on Swift import declarations, browsing the
Swift documentation led me to an interesting declaration attribute that’s
currently not officially released: `@_exported`

According to [the docs](http://the-swift-programming-language.readthedocs.io/en/latest/md/Attributes/),
applying this attribute to an import declaration exports the import module,
submodule, or declaration from the current module. For example, consider if
`FrameworkA` had the import declaration `@_exported import FrameworkC`. In
our application we could then only  `import FrameworkA` and still be able
to access `FrameworkC` thanks to the `@_exported` attribute.

But considering that it’s a private Swift attribute (as denoted by that pesky
underscore 😒 ), we’re *probably* best off not using it for the time being.
