2014-06-02 20:05:42 8 Comments
In the new Swift language from Apple, how does one call Objective-C code?
Apple mentioned that they could co-exist in one application, but does this mean that one could technically re-use old classes made in Objective-C whilst building new classes in Swift?
The Reasoning
Objective-C is a platform-independent language, whereas Swift is platform-dependent. Writing non-platform-dependent code (business logic libraries) in Swift would thus not be wise. However, writing platform-dependent code in it (interface related for example) would be perfectly fine. Not to say it would be a good idea, however it is definitely an interest.
Related Questions
Sponsored Content
17 Answered Questions
[SOLVED] #pragma mark in Swift?
- 2014-06-03 14:05:56
- Arbitur
- 198636 View
- 858 Score
- 17 Answer
- Tags: swift
13 Answered Questions
[SOLVED] What is a typedef enum in Objective-C?
- 2009-04-01 21:59:43
- Craig
- 412789 View
- 1055 Score
- 13 Answer
- Tags: objective-c enums typedef
9 Answered Questions
[SOLVED] Swift Beta performance: sorting arrays
- 2014-06-07 23:53:45
- Jukka Suomela
- 107243 View
- 879 Score
- 9 Answer
- Tags: swift performance sorting xcode6 compiler-optimization
90 Answered Questions
[SOLVED] How can I make a UITextField move up when the keyboard is present - on starting to edit?
- 2009-07-14 17:06:07
- philfreo
- 600090 View
- 1609 Score
- 90 Answer
- Tags: ios objective-c uiscrollview uitextfield uikeyboard
30 Answered Questions
[SOLVED] Shortcuts in Objective-C to concatenate NSStrings
- 2009-02-04 06:26:19
- typeoneerror
- 751978 View
- 1073 Score
- 30 Answer
- Tags: objective-c nsstring string-concatenation
21 Answered Questions
[SOLVED] How do I check if a string contains another string in Objective-C?
- 2010-05-02 15:34:54
- Jonathan.
- 528684 View
- 1174 Score
- 21 Answer
- Tags: ios objective-c string substring
25 Answered Questions
[SOLVED] How do I sort an NSMutableArray with custom objects in it?
- 2009-04-30 06:10:56
- rustyshelf
- 447798 View
- 1211 Score
- 25 Answer
- Tags: ios objective-c sorting cocoa-touch nsmutablearray
3 Answered Questions
[SOLVED] Importing a Swift protocol in Objective-C class
- 2014-06-06 09:15:58
- Jean Lebrument
- 40405 View
- 95 Score
- 3 Answer
- Tags: objective-c swift
21 Answered Questions
[SOLVED] Why is Swift compile time so slow?
- 2014-08-27 21:57:05
- apouche
- 42631 View
- 195 Score
- 21 Answer
- Tags: compilation swift
4 Answered Questions
[SOLVED] Read-only and non-computed variable properties in Swift
- 2014-06-06 11:51:09
- Zaxonov
- 52622 View
- 115 Score
- 4 Answer
- Tags: objective-c swift properties
15 comments
@Logan 2014-06-03 00:12:17
Using Objective-C Classes in Swift
** If you have an existing class that you'd like to use, perform Step 2 and then skip to Step 5. (For some cases, I had to add an explicit
#import <Foundation/Foundation.h
to an older Objective-C File.) **Step 1: Add Objective-C Implementation -- .m
Add a
.m
file to your class, and name itCustomObject.m
.Step 2: Add Bridging Header
When adding your
.m
file, you'll likely be hit with a prompt that looks like this:Click YES !
If you did not see the prompt, or accidentally deleted your bridging header, add a new
.h
file to your project and name it<#YourProjectName#>-Bridging-Header.h
.In some situations, particularly when working with Objective-C frameworks, you don't add an Objective-C class explicitly and Xcode can't find the linker. In this case, create your
.h
file named as mentioned above, then make sure you link its path in your target's project settings like so:Note
It's best practice to link your project using the
$(SRCROOT)
macro so that if you move your project, or work on it with others using a remote repository, it will still work.$(SRCROOT)
can be thought of as the directory that contains your .xcodeproj file. It might look like this:Step 3: Add Objective-C Header -- .h
Add another
.h
file and name itCustomObject.h
.Step 4: Build your Objective-C Class
In
CustomObject.h
In
CustomObject.m
Step 5: Add Class to Bridging-Header
In
YourProject-Bridging-Header.h
:Step 6: Use your Object
In
SomeSwiftFile.swift
:There is no need to import explicitly; that's what the bridging header is for.
Using Swift Classes in Objective-C
Step 1: Create New Swift Class
Add a
.swift
file to your project, and name itMySwiftObject.swift
.In
MySwiftObject.swift
:Step 2: Import Swift Files to ObjC Class
In
SomeRandomClass.m
:The file:
<#YourProjectName#>-Swift.h
should already be created automatically in your project, even if you can not see it.Step 3: Use your class
Note:
1. CodeCompletion wasn't behaving as accurately as I'd like it to. On my system, running a quick build with "cmd + r" seemed to help Swift find some of the Objective-C code and vice versa.
2. If you add a
.swift
file to an older project and get error:dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, try completely restarting Xcode.3. While it was originally possible to use pure Swift classes in Objective-C by using the
@objc
prefix, after Swift 2.0, this is no longer possible. See edit history for original explanation. If this functionality is reenabled in future Swift versions, the answer will be updated accordingly.@Tomáš Linhart 2014-06-03 11:19:06
It is important you need to annotate methods with @objc or Swift methods won't be visible from Objective-C.
@Logan 2014-06-03 13:41:53
@TomášLinhart -- I didn't find it necessary to do that, is there a specific use case you're referring to?
@Tomáš Linhart 2014-06-03 13:48:57
You are right. You only need to specify it if you don't use Cocoa objects. To be accessible and usable in Objective-C, a Swift class must be a descendant of an Objective-C class or it must be marked @objc.
@Markus Rautopuro 2014-06-03 16:17:45
Where is this <#YourProjectName#>-Swift.h? Is it generated at compile time?
@Logan 2014-06-03 16:22:05
@MarkusRautopuro - I don't know where it is in the directory, but it's generated automatically. The only way that I've been able to actually see it is when I had an error on it and I was able to click through the debugger to the file. Let me know if you find it.
@Markus Rautopuro 2014-06-03 16:23:26
By the way, where did you pull this information from (that <#YourProjectName#>-Swift.h exists)?
@Logan 2014-06-03 16:25:06
@MarkusRautopuro - Got it from here: developer.apple.com/library/prerelease/ios/documentation/Swift/…"
@Stuart M 2014-06-05 07:27:31
See also: WWDC 2014 Session 406: Integrating Swift with Objective-C
@Logan 2014-06-06 15:30:57
@TomášLinhart - I added an example with a pure swift class since this question has become so popular. Thanks for the addition!
@Ravikumar S 2014-06-19 06:27:29
Guys I am new to iOS development. I am using Swift and trying to added XMLRPC libraries to my project. Xcode 6 not giving prompt for generating bridge-header file. Please help me on this
@Logan 2014-06-19 11:18:05
@ravivlb - Look at Step 2. Just add a '.h' w/ appropriate name.
@Ravikumar S 2014-06-19 11:33:43
Thank Logan. issue fixed by creating new project and added bridge header file.
@Caleb 2014-08-04 06:25:24
@Logan The following blog entry is copied from a portion of this post, or vice versa: ios-blog.co.uk/tutorials/…
@Logan 2014-08-04 12:19:23
@Caleb - Thanks for pointing this out! If you look at the bottom of that article, the author attributes this post.
@User 2014-10-07 03:19:30
What if the Objective C library has other Objective C dependencies?
@Logan 2014-10-07 13:11:23
@macdonjo - If those dependencies are included internally within the library, it should be fine as long as they're included in the project. If you need to access those libraries externally, I'm not positive, but I believe that as long as they are imported in the same header, you should be ok.
@user1021430 2014-11-20 21:29:24
If importing a Objective C framework into Swift, make sure to import all frameworks that the Obj C framework depends on into your project (in Build Phases -> Link Binary With Libraries), then add #import's for those to a prefix header file, which must be added to your project in build settings (in the Prefix Header field). This includes frameworks like UIKit and Foundation, even if those are already used from within Swift. This tripped me up for hours, and no one seems to have documented these steps.
@h4labs 2014-12-12 18:40:26
This was critical to add to my Objective C files that I wanted to import into Swift. I missed it and wasted a lot of time: #import <Foundation/Foundation.h>
@AbhimanyuAryan 2015-07-14 22:24:05
@Logan what tool you used to create this GIF?
@Logan 2015-07-14 22:25:01
@androidplusios.design - I get asked that all the time! It's an awesome little app called licecap: cockos.com/licecap
@Andy 2015-08-07 14:44:37
@Logan why did you name it CustomClass.m and CustomClass.h? Couldn't this be named anything? What do I name these files if I want to create more than one?
@Logan 2015-08-07 14:54:02
@AndrewAnthonyGerst in objective-c it's convention to name the files after the name of the class, and there's rarely more than one class per file. So yes, you could name it anything, but I wouldn't recommend it. If you want more than one class, create a new .h and .m for each class.
@lee 2015-09-04 10:24:31
I my case Using Swift Classes in Objective-C. But get the error file not found when import #import "<#ProjectName#>-Swift.h". Please help me resolve this.
@Logan 2015-09-04 13:26:11
@lee - Can you go to your build settings and ensure that your
Product Module Name
is what you expect, the syntax is really#import "ProductModuleName-Swift.h
, it just defaults to project name and most people don't change it.@Sparkxxf 2015-11-21 03:54:29
In SomeSwiftFile.swift: I got this: Expected declaration on "instanceOfCustomObject.someProperty = "Hello World" Why?Thanks.
@Logan 2015-11-21 07:06:36
@Rob - Good catch, would you suggest leaving a comment indicating that it's no longer relevant
>Swift2.0
, or removing it completely.@AmJa 2016-04-27 21:39:36
Thanks @Logan this worked for me but the only thing I Noticed different is that with xcode 7.3 when you add .m or .h files there is no pop up coming for creating the bridging header you have to manually go to Build Settings and do it or may be something is wrong with my project settings :).
@Alper 2018-03-08 11:06:10
Why the hell does the
-Swift.h
file go into the.m
file?@Logan 2018-03-09 19:18:14
@Alper the system will generate a "bridging header" that exposes the accessible swift code to ObjC. This needs to be imported as any other file would be. For example,
import OtherObject.h
to import an ObjC class header. For Swift, we don't import classes individually, but rather need to import all accessible objects@Alper 2018-03-09 20:25:54
But why not put it in the
.h
file?@Logan 2018-03-09 20:46:33
@Alper that question is more about ObjC in general. If you import in the
.h
file, then all subsequent imports of that file will also import the other file. This can be useful if one object always needs another, but it can also lead to circular dependencies where A.h imports B.h imports C.h imports A.h. By putting it in the.m
file, we keep it private to this class and subsequent imports don't also import that file. In Swift here, if we haveObject.{h,m}
and we imported inObject.h
, then every time somebody importedObject.h
in another file, they'd also import all Swift files.@Oleksandr 2018-07-10 17:16:27
Works for 100%. One of the rarest cases. If you want to make this simpler you can: *create Obj.-C file *bridging-header will be generated. Describe all function in the generated file.
@djruss70 2019-01-13 13:12:55
In the section for Using Swift Classes in Objective-C, the Step 3 example shows calling a swift method with a parameter
:someArg
. In Xcode10, the given code gives an error“No visible @interface for 'MySwiftInterface' declares the selector 'someFunction:
. To fix this error, the first parameter name should be incorporated into the method name, like this:NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];
@Logan 2019-01-23 08:46:28
@djruss70 - updated, thanks!
@Tibin Thomas 2019-01-05 11:17:57
Apple has provided official guide in this doc: how-to-call-objective-c-code-from-swift
Here is the relevant part:
To import a set of Objective-C files into Swift code within the same app target, you rely on an Objective-C bridging header file to expose those files to Swift. Xcode offers to create this header when you add a Swift file to an existing Objective-C app, or an Objective-C file to an existing Swift app.
If you accept, Xcode creates the bridging header file along with the file you were creating, and names it by using your product module name followed by "-Bridging-Header.h". Alternatively, you can create a bridging header yourself by choosing File > New > File > [operating system] > Source > Header File
Edit the bridging header to expose your Objective-C code to your Swift code:
Any public Objective-C headers listed in the bridging header are visible to Swift.
@Tibin Thomas 2019-01-05 12:37:41
@WaynePhipps done :)
@ARGeo 2018-06-12 21:43:00
In the Swift 4.2.1 project in Xcode 10.1 you can easily add Objective-C file. Follow the steps below to bridge Objective-C file to Swift project.
Step_01: Create new Xcode project using Swift language:
File
>New
>Project
>objc
.Step_02: In Swift project add new Objective-C file:
File
>New
>File...
>macOS
>Objective-C File
.Step_03: If you add a new Objective-C file into Swift project at very first time, Xcode asks you:
Would you like to configure an Objective-C bridging header
?Step_04: Select the option:
Create Bridging Header
.Step_05: A corresponding file will be generated with a name:
Objc-Bridging-Header.h
.Step_06: Now, you need setup Bridge file path in bridge header. In Project Navigator click on project with name
objc
and then choose:Build Settings
>Objective-C Bridging Header
>Objc-Bridging-Header.h
.Step_07: Drag-and-drop your
Objc-Bridging-Header.h
into that box to generate a file path.Step_08: Open your
Objc-Bridging-Header.h
file and import the Objective-C file which you want to use in your Swift file.Here's a content of
SpecialObjcFile.m
:Step_09: Now in your Swift file, you can use an Objective-C class:
@HSAM 2018-12-07 17:13:21
xcode 9.4 doesn't support swift 4.2
@ARGeo 2018-12-07 17:19:37
I fixed the issue.
@Kampai 2015-09-16 07:00:57
One more thing I would like to add here:
I am very thankful for @Logan's answer. It helps a lot to create a bridge file and setups.
But after doing all these steps I'm still not getting an Objective-C class in Swift.
I used the
cocoapods
library and integrated it into my project. Which ispod "pop"
.So if you are using Objective-C pods in Swift then there may be a chance that you can not able to get or
import
the classes into Swift.The simple thing you have to do is:
<YOUR-PROJECT>-Bridging-Header
file and#import <ObjC_Framework>
to@import ObjC_Framework
For example: (Pop library)
Replace
with
Use
clang import
when#import
is not working.@Honey 2016-12-02 03:44:19
Use clang import when #import is not working. what? Didn't just say we should use @import ?!
@CrazyPro007 2018-05-19 16:27:52
Call ObjectiveC class from swift
@CrazyPro007 2018-05-19 16:30:13
NOTE:- When you create a Objc class in swift project than xcode asks for bridging the class automatically. No worries :)
@Sanjay Mali 2018-04-13 09:39:37
Two way Approach to use objective-c objective-c
1
2
Now good to go Thanks
@Johan Karlsson 2018-12-21 08:48:38
A very sparse answer.
@Nish 2017-06-29 06:38:20
@david72 2016-03-20 17:53:31
Just a note for whoever is trying to add an Objective-C library to Swift: You should add -ObjC in Build Settings -> Linking -> Other Linker Flags.
@Johan Karlsson 2018-12-21 08:48:00
Why? Please add information on what this flag does and why it should be added.
@Avijit Nagare 2015-11-25 08:29:40
After you created a Bridging header, go to Build Setting => Search for "Objective-C Bridging Header".
Just below you will find the ""Objective-C Generated Interface Header Name" file.
Import that file in your view controller.
Example: In my case: "Dauble-Swift.h"
@Yogesh shelke 2015-09-10 12:16:36
Click on the New file menu, and chose file select language Objective. At that time it automatically generates a "Objective-C Bridging Header" file that is used to define some class name.
"Objective-C Bridging Header" under "Swift Compiler - Code Generation".
@derrrick 2015-02-12 19:34:25
Here are step-by-step instructions for using Objective-C code (in this case, a framework provided by a third-party) in a Swift project:
In simple steps:
A prompt appears, and then click on OK... If it does not appear, then we create it manually like in the following... Create one header file from iOS source and give the name ProjectName-Bridging-Header (example: Test-Bridging-Header), and then go to build setting in the Swift compiler code -> Objective-C bridge add Objective-C bridge name ..(Test/Test-Bridging-Header.h). Yeah, that's complete.
Optionally, delete the Objective-C file you added (named "anything" in the GIF image above). You don't need it any more.
Open the bridging header file -- the filename is of the form [YourProject]-Bridging-Header.h. It includes an Xcode-provided comment. Add a line of code for the Objective-C file you want to include, such as a third-party framework. For example, to add Mixpanel to your project, you will need to add the following line of code to the bridging header file:
Now in any Swift file you can use existing Objective-C code, in the Swift syntax (in the case of this example, and you can call Mixpanel SDK methods, etc.). You need to familiarize yourself with how Xcode translates Objective-C to Swift. Apple's guide is a quick read. Or see this answer for an incomplete summary.
Example for Mixpanel:
That's it!
Note: If you remove the bridging header file from your project, be sure to go into Build Settings and remove the value for "Objective-C Bridging Header" under "Swift Compiler - Code Generation".
@Gian Luigi Romita 2014-06-13 10:10:00
I wrote a simple Xcode 6 project that shows how to mix C++, Objective-C and Swift code:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
In particular, the example calls an Objective-C and a C++ function from the Swift.
The key is to create a shared header, Project-Bridging-Header.h, and put the Objective-C headers there.
Please download the project as a complete example.
@Jake Lin 2014-06-04 02:11:55
You can read the nice post Swift & Cocoapods. Basically, we need to create a bridging header file and put all Objective-C headers there. And then we need to reference it from our build settings. After that, we can use the Objective-C code.
Also have a look at Apple's document Using Swift with Cocoa and Objective-C as well.
@rickster 2014-06-02 20:43:51
See Apple's guide to Using Swift with Cocoa and Objective-C. This guide covers how to use Objective-C and C code from Swift and vice versa and has recommendations for how to convert a project or mix and match Objective-C/C and Swift parts in an existing project.
The compiler automatically generates Swift syntax for calling C functions and Objective-C methods. As seen in the documentation, this Objective-C:
turns into this Swift code:
Xcode also does this translation on the fly — you can use Open Quickly while editing a Swift file and type an Objective-C class name, and it'll take you to a Swift-ified version of the class header. (You can also get this by cmd-clicking on an API symbol in a Swift file.) And all the API reference documentation in the iOS 8 and OS X v10.10 (Yosemite) developer libraries is visible in both Objective-C and Swift forms (e.g.
UIView
).@rickster 2014-06-02 20:57:22
What, no Swift syntax highlighting on SO? This language has been out for all of two hours — that's forever in Internet years! ;)
@skywinder 2014-06-04 11:55:07
The direct link to Apple documentation how to integrate Swift in existing project: developer.apple.com/library/prerelease/ios/documentation/Swift/…
@Gergo Erdosi 2014-06-02 20:43:55
Quote from the documentation: