12

I have built two frameworks in swift, let's call them CoreFramework and MyFramework

MyFramework has a dependency to CoreFramework and uses some of CoreFramework's classes, structs and enums in its public methods, like this for example:

public func fetchData() -> CoreStruct

I have set up a podspec for both Frameworks and I can use MyFramework as a pod in my project. In my project I would write something like:

let result = fetchData()

This compiles and Xcode even gives me the right type when I alt+click the variable, but if I want to explicitly specify the type of result like this:

let result: CoreStruct = fetchData()

I get a compiler error and I have to import CoreFramework

What do I have to do, to be able to explicitly use things like CoreStruct in my project, without having to import the underlying framework?

Cœur
  • 37,241
  • 25
  • 195
  • 267
kutschenator
  • 902
  • 10
  • 26
  • I don't know how cocoapod works, but without it, you usually use the 'import' instruction for frameworks as with core dara, foundation and so on. Can you omit this with Cocoapods ? – Jan ATAC Oct 23 '15 at 08:11
  • But even if I would import lets say `CoreData` would i be able to use things like `NSManagedObject` without additional imports in project? I guess not – kutschenator Oct 23 '15 at 08:13
  • not in project scope, you're right. Except if you do it in the main file. – Jan ATAC Oct 23 '15 at 08:21

4 Answers4

5

There is no way in Swift to make importing one module automatically import another. That was a conscious choice on the language designers’ part, and Swift is strict about it.

There is something called an “umbrella framework” which sort of does what you want by letting you create a facade for several subframeworks, but Apple specifically discourages you from creating one.

Barring that, you must ensure that (in your example) fetchData() and CoreStruct are compiled into the same framework, which you could do by:

  • having MyFramework include CoreFramework’s code as a git submodule,
  • having MyFramework use Cocoapods to build CoreFramework within the same workspace (i.e. publish CoreFramework as a pod, and include it in MyFramework without the use_frameworks option in the podfile, so that you get two projects in one workspace compiled into one framework),
  • merging the projects (i.e. just add all the source files from MyFramework and CoreFramework to the same project),

…or anything else that causes the two source trees to be compiled into one framework.

Community
  • 1
  • 1
Paul Cantrell
  • 9,175
  • 2
  • 40
  • 48
  • 1
    Thanks for the answer. Could you elaborate on the "having MyFramework use Cocoapods to build CoreFramework into the same workspace" part? – kutschenator Oct 31 '15 at 23:01
  • 1
    See edits. It’s basically just a fancy way of merging the codebases, only useful if you have reason to publish/use CoreFramework independently of MyFramework. – Paul Cantrell Nov 01 '15 at 00:35
  • 1
    Alright, although I cannot use this in my special case this is still a good and valid answer. Hope it helps some people – kutschenator Nov 02 '15 at 13:13
1

You can expose classes that you need from underlying CoreFramework in MyFramework

public typealias CoreStruct = CoreFramework.CoreStruct
juraj
  • 439
  • 2
  • 9
0

There is another way now to do it (in case anyone is still looking for this). You can do an exported import in MyFramework:

import Foundation 
...
@_exported import CoreFramework

public struct MyFrameworkType {
...
}

A more thorough explanation can be found here: https://davedelong.com/blog/2018/01/19/simplifying-swift-framework-development/

tadelv
  • 114
  • 4
-2

You could do

import struct CoreFramework.CoreStruct

to only import this particular type, see The Swift Programming Language Reference: Import Declarations.

eik
  • 2,104
  • 12
  • 15
  • 1
    But that means I still have to import it. I wanted to avoid any import to `CoreFramework` in the first place – kutschenator Nov 02 '15 at 13:15
  • As you see it the “accepted answer” there is no way to do so, the next best thing is to avoid importing the whole framework, possibly polluting your namespace. – eik Nov 02 '15 at 15:43