54

I'm trying to import myFramework into a project. I've added myFramework in Build Phases->Link Binary With Libraries.

Objective-c works:

#import <UIKit/UIKit.h>
#import <myFramework/myFramework.h>

But with in Swift, I get a No such module myFramework error:

import UIKit
import myFramework

According to the Swift documentation:

Importing External Frameworks

You can import external frameworks that have a pure Objective-C codebase, a pure Swift codebase, or a mixed-language codebase. The process for importing an external framework is the same whether the framework is written in a single language or contains files from both languages. When you import an external framework, make sure the Defines Module build setting for the framework you’re importing is set to Yes.

You can import a framework into any Swift file within a different target using the following syntax:

SWIFT

import FrameworkName

You can import a framework into any Objective-C .m file within a different target using the following syntax:

OBJECTIVE-C

@import FrameworkName;

I created myFramework using Xcode 5. Xcode 5 doesn't have a "Defines Module" build setting.

Where is the problem?

phnmnn
  • 12,813
  • 11
  • 47
  • 64
  • In my project I am linking with _Apple's SpriteKit.framework_ as you described and I am able to use all of Sprite Kit's classes by then importing the framework within the swift class using: **import SpriteKit** – q231950 Jun 07 '14 at 08:31
  • Xcode 5 doesn't allow you to ```@import``` non-system frameworks. It's available since Xcode 6. – Shmidt Jun 16 '14 at 16:34
  • What's the right answer that you are following in your code? – Satyam Nov 10 '14 at 10:02
  • this solution worked for me http://stackoverflow.com/a/37328591/1084174 – Sazzad Hissain Khan May 19 '16 at 16:08

9 Answers9

22

If I get you correctly you don't have a separate build target for your framework (you already built it with Xcode 5) and included the framework into your project's build target.

The part of the documentation you're referring to is about frameworks within different targets. Since your framework is in the project's target this part of the documentation doesn't apply here.

In your case you can't do an import of the framework in your Swift file. That's why you get the error message "No such module myFramework". myFramework is no module -- it is part of your project's module (which is by default determined by your product name). As such the classes in your framework should be accessible.

However your framework is written in Objective-C. So what you have to do is to import the Swift facing classes in your bridging-header as described here.

Please note that this has nothing to do with the Swift import of a module. The import directive in the bridging-header file just notifies the compiler to 'translate' Objective-C header files to Swift syntax and makes the public header visible to Swift.

So what should you do now?

  • First import the header files you're interested in in the bridging-header. You only need to import the headers you will interact with in Swift.

  • Try to compile your project in this stage. If Xcode can't find the header files of the framework your problem is probably not related to Swift or Xcode 6 but a problem with including frameworks in general.

  • After that try to instantiate a class you imported in the bridging-header, maybe in your AppDelegate.swift. Xcode auto-completion should offer you the type names.

Hope this helps.

aheze
  • 24,434
  • 8
  • 68
  • 125
mic
  • 907
  • 6
  • 17
  • 2
    I followed the instructions at swift docs. I wanted to import the *JWFolders* code. After doing the swift doc steps, I wrote the import statement to import JWFolders and I got a "No such module 'JWFolders'" error statement. This is the missing step that I required: 1. Click on your project name on the top left nav bar. 2. Click on "Build Phases" 3. Click on "Embedded Frameworks" 4. Click the "+" 5. Find the header file and add it. BUT--> I can only access this "embedded frameworks" drop down if I have previously added a framework. This is a hacky way to do it. What is the correct way? – Nate Uni Jan 09 '15 at 10:56
20

On Swift:

Create Framework:-

  1. Start Xcode -> Create a new Xcode Project -> iOS -> Framework & Library -> Cocoa Touch Framework -> Name the framework(ex. sampleCocoaFramework) -> Create.

  2. Set Target -> General -> Deployment info -> Deployment Target.

  3. Add a public class: File -> New File -> iOS -> Swift File -> Name it (ex. openCocoaClass) -> Create.

  4. Now add some code to the openCocoaClass.swift.

    import Foundation
    
    public class openCocoaClass {
    
        public init() {
    
        }
    
        public var samplePublicVariable = "samplePublicVariable @ openCocoaClass"
    
        public func samplePublicFunction()
        {
            print("samplePublicFunction @ openCocoaClass")
        }          
    

    }

  5. Clean the project : Product -> Clean

  6. Configure the scheme settings : Product -> Scheme -> Edit Scheme -> Run -> Build Configuration -> Release.

  7. Build the framework : Product -> Build.

  8. Export the framework : Products -> Select the framework -> Identity and type -> Full Path -> Released Framework.

Adding Framework to Project:-

  1. Start a Xcode project and name it (ex. CocoaFrameworkTest).

  2. Drag and drop the sampleCocoaFramework.framework to the CocoaFrameworkTest's project folder.

  3. Target -> General -> Embed Binaries -> Add Other -> Select Framework -> Copy Items if needed -> Done.

Accessing Framework on ViewController:-

import UIKit
import sampleCocoaFramework


class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let frameworkObject =  openCocoaClass.init()
        frameworkObject.samplePublicFunction()
        print(frameworkObject.samplePublicVariable)


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
Alex Zavatone
  • 4,106
  • 36
  • 54
Alvin George
  • 14,148
  • 92
  • 64
  • 1
    This was a great way to move forward. I'm wondering what's the best way to import a framework that is still under development in another Xcode project. I don't want to follow all of these steps each time I make a change. Ideally I would just have the framework and the app in the same Xcode project so that I don't even have to switch between windows. – MrBr Mar 13 '18 at 15:48
  • Thanks. Everything is fine except your step 8 ("Export the framework : Products -> Select the framework -> Identity and type -> Full Path -> Released Framework") I can't do. Maybe because of other Xcode version. Could you please update that step 8. Thanks in advance. – LukeSideWalker Jan 30 '21 at 13:21
  • @MrBr did you get the solution. – Pramod Shukla Mar 05 '22 at 11:09
13

According to the Swift documentation

To import Objective-C code into Swift from the same target

  1. In your Objective-C bridging header file, import every Objective-C header you want to expose to Swift. For example:

    #import "XYZCustomCell.h"

    #import "XYZCustomView.h"

    #import "XYZCustomViewController.h"

  2. Under Build Settings, make sure the Objective-C Bridging Header build setting under Swift Compiler - Code Generation has a path to the header. The path must be directly to the file itself, not the directory that it’s in. The path should be relative to your project, similar to the way your Info.plist path is specified in Build Settings. In most cases, you should not need to modify this setting.

Any public Objective-C headers listed in this bridging header file will be visible to Swift. The Objective-C functionality will be available in any Swift file within that target automatically, without any import statements. Use your custom Objective-C code with the same Swift syntax you use with system classes.

let myCell = XYZCustomCell()
myCell.subtitle = "A custom cell"

Also, make sure the "Defines Module" build setting under "Packaging" is set to "Yes."

sudo make install
  • 5,629
  • 3
  • 36
  • 48
Tomer Even
  • 4,820
  • 2
  • 30
  • 36
  • I create myFramework in xcode 5, he dont have Defines Module build setting – phnmnn Jun 05 '14 at 14:21
  • I don't think just #import "XYZCustomCell.h" etc will work. You have to provide the framework name as in example "#import ". Please cross check your answer. – Satyam Nov 10 '14 at 10:03
2

you need in your objective c project a public header with the same name of you app, in you case FrameworkName.h and add all the classes that you want to expose (those classes should be added as public header in the project properties) Once you do that, you add the framework and add the reference to your public header import FrameworkName

1

You can import external objC framework into swift project using below syntax:

#import "objCExternalFramework-name/headerfilename.h"

SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
V V
  • 774
  • 1
  • 9
  • 29
0

Okay, it's Xcode 7.2 now. And what I observed is, swift import is case sensitive. Example - import uikit will not work. You'll have to type it as import UIKit.

just my two cents.

Sukhi
  • 13,261
  • 7
  • 36
  • 53
0

Latest XCode provides option to embed framework into other projects. This link (https://stackoverflow.com/a/37328591/1084174) worked well for me.

Community
  • 1
  • 1
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
0

Defines Module(DEFINES_MODULE)[About] generates .modulemap[About] for using Modular Framework from Objective-C(@import) or Swift(import)

[Mixing Objective-C and Swift] uses different approaches

same target - Bridging-Header.h
different targets - .modulemap

Step by step example is here [Swift consumer -> Objective-C dynamic framework]

yoAlex5
  • 29,217
  • 8
  • 193
  • 205
-1

Just command+B would help!

The why: Adding the framework through Cocoapods will create another pod project with the required frameworks in it. For the main project to identify the frameworks, the static libraries of both the projects have to be bridged. Building the workspace is needed for that to happen.

MAhipal Singh
  • 4,745
  • 1
  • 42
  • 57
Vasanth
  • 24
  • 8