17

I'm new in swift programming. I need to create pure swift framework and import it in my existing pure swift project. When I try to import swift framework, I'm getting this error message:

"Could not build Objective-C module '<myModule>'"

Framework File Structure

Test.h

 import Foundation

public class Test {
    class func printTest() {
        println("111");
    }
}

Asdf.h

import UIKit
public class Asdf: Test {
    class func echo() {
        println(888);
    }
}

myModule-Swift.h

#ifndef <myModule>_<myModule>_Swift_h
#define <myModule>_<myModule>_Swift_h

#endif

After framework build, i have added framework in my existing project and get this Project Structure and import problem screen

What am I doing wrong? Thanks For Help!

@findall comment answer - I tried to add all framework files to my project root folder and inside project folder, but again got the same error Add Framework files to project root

Add Framework files inside project folder

styopdev
  • 2,604
  • 4
  • 34
  • 55
  • 1
    I want to know how to do perfectly that, too. But, there is a workaround about that. Not only ".framework", also add the project itself of a framework to an use-side project 's hierarchy. After this, all public symbols in the framework can be seen from the use-side. – findall Oct 20 '14 at 13:34
  • I tried to add files (I edited the question), but again get the same error, can you explain more details? – styopdev Oct 20 '14 at 14:16
  • Not files of the framework, try to add a reference to the ".xcodeproj" of the framework through `Project Navigator`. If you want to deploy on a real device, you have to also add ".framework" to `Embedded Binaries`. – findall Oct 21 '14 at 01:27
  • I have added .xcodeproj in my project, but the problem was not solved – styopdev Oct 21 '14 at 07:17
  • Okay, please let me try to explain the things I've done in step by step as an answer. I'm still not good at English, so I hope I won't confuse you. (-_-;) – findall Oct 21 '14 at 08:18

4 Answers4

19

I've done with the following steps.

  1. Create a framework project, for example named "FooKit". (Cocoa Touch Framework to be selected)
  2. Create a ".swift" file and add a public symbol, for example public func foo(), to it.
  3. Create an use-side (app) project. (I've chosen Single View Application)
  4. Open the root directory of "FooKit" by Finder, drag "FooKit.xcodeproj" there and drop it into the app project via Project Navigator.
  5. Add "FooKit" to Target Dependencies in the app's Build Phases setting.
  6. Add "FooKit.framework" to Embedded Binaries in the app's General setting.

Now you can build like this code in the use-side app.

import FooKit

func bar() {
    foo()
}
findall
  • 2,176
  • 2
  • 17
  • 21
  • 10
    It's working for me as well, but I wonder why we can't just drag and drop the compiled framework? What does xcworkspace do behind the scenes to make it work? – Mazyod Feb 27 '15 at 05:52
  • 2
    i have tha same question Mazyod – Christos Chadjikyriacou Aug 12 '15 at 06:52
  • 2
    @findall, this doesn't making sense for me. If we are going to put .xcodepoj file so what is need of Framework? I mean no security of code? – Mohammad Zaid Pathan Sep 22 '15 at 10:29
  • Hi all, I have the same question as you do. I am following the below tutorial for making Framework, and adding the framework https://medium.com/@PyBaig/build-your-own-cocoa-touch-frameworks-in-swift-d4ea3d1f9ca3#.wftv6kglt But when I try to import, it shows "No Such Module" – Saty Oct 21 '15 at 04:51
  • @ZaidPathan... do you still put the .xcodeproject instead of just the frameworks or is there any changes happened recently? – Saty Mar 22 '16 at 08:59
  • @Saty , I didn't see it recently but according to what I know, there is no change yet. – Mohammad Zaid Pathan Mar 22 '16 at 09:46
  • @ZaidPathan... so it means if I will make any code and include it in a framework, then if I will handover this to third-party, I have to give them the total code? is not it? – Saty Mar 22 '16 at 09:47
  • @Saty, In Case of Swift Yes. But In case of Obj-C the compiled .framework or .a file will be shared. – Mohammad Zaid Pathan Mar 22 '16 at 09:49
  • @all...if you wish to provide framework without showing the source code.. please use cocoapod-packager.... to make a framework which works with swift /objective c... .... – Saty Apr 07 '16 at 12:55
  • you can make a cocoapod project make it work with a private repos and then package them using cocoapod-packager!!! – Saty Apr 07 '16 at 12:55
  • This does not work. The import tells me that there is no such framework as the one I added :-( Also, what's the point in adding the xcodeproj? I want a framework. Should be simple, shouldn't it? – qwerty_so Oct 10 '16 at 13:28
  • @Saty [Develop a Swift Framework](https://medium.com/captain-ios-experts/develop-a-swift-framework-1c7fdda27bf1) – Mohammad Zaid Pathan Jan 19 '18 at 07:05
3

In Xcode 7.2 using Swift 2.1 I managed to get past the mentioned error by making sure that the build settings of your pure Swift framework called Foo are as follows:

1) Build Settings->Packaging->Defines Module = Yes

2) Build Settings->Swift Compiler - Code Generation->Install Objective-C Compatibility Header = Yes (if you do not need to import your Swift framework into Objective C set this setting to No)

3) Erase the string value of Build Settings->Swift Compiler - Code Generation->Objective-C Bridging Header

4)Build Settings->Swift Compiler - Code Generation->Objective-C Generated Interface Header Name = Foo-Swift.h (if you do not need to import your Swift framework into Objective C erase this setting as you did in step 3))

5) Make sure that Build Settings->Packaging->Product Name = Foo

6) Add to the public umbrella header of your framework (Foo.h), which you can use to import your Swift code to Objective C, the following line:

#import "Foo-Swift.h"

(but if you do not need to import your Swift code into objective C skip this step)

6) Add the following line to the Swift file where you want to use the module Foo:

import Foo

Important notes:

1) Ensure that your umbrella header Foo.h is set to public in the File Inspector, otherwise this won't work.

2) If you are using your pure Swift framework in Objective C files, ensure that:

  • the Foo-Swift.h header has generated the correct interface by going to Foo.h and then clicking on the top left corner menu of the Xcode code editor and then choosing Includes->Foo-Swift.h (I had to rebuild the Foo framework a few times until Xcode caught-up with the change and then generated the correct interface in Objective C, so you may need to do that as well)

  • your swift classes inherit from NSObject or they won't be available to Objective C code

jvarela
  • 3,744
  • 1
  • 22
  • 43
2

Additionally for @jvarela's answer, in Xcode 9 and swift 4,

To import Swift framework in an Objective C project, you must add

@objc

mark to all of your classes, methods and variables which you want to export into Objective C project .

For example,

@objc public class Foo: NSObject {

    @objc public var fooDescription: String

    @objc public func foo(){

    }

}
yvzzztrk
  • 424
  • 6
  • 13
1

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 Taget -> 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()
    }
}
Alvin George
  • 14,148
  • 92
  • 64
  • 4
    Where is this step In xcode 8.0 : 8.Export the framework : Products -> Select the framework -> Identity and type -> Full Path -> Released Framework. – Sentry.co Jan 15 '17 at 20:37
  • How can I add frameworks based on architecture instead of making fat one. – Satyam Jan 31 '17 at 04:58