笑故挽风
2014-06-02 20:05
采纳率: 14.3%
浏览 397
已采纳

如何从 Swift 调用 Objective-C 代码

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.

转载于:https://stackoverflow.com/questions/24002369/how-to-call-objective-c-code-from-swift

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

15条回答 默认 最新

  • 旧行李 2014-06-03 00:12
    已采纳

    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 it CustomObject.m.

    Step 2: Add Bridging Header

    When adding your .m file, you'll likely be hit with a prompt that looks like this:

    Enter image description here

    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:

    Enter image description here

    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:

    $(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
    

    Step 3: Add Objective-C Header -- .h

    Add another .h file and name it CustomObject.h.

    Step 4: Build your Objective-C Class

    In CustomObject.h

    #import <Foundation/Foundation.h>
    
    @interface CustomObject : NSObject
    
    @property (strong, nonatomic) id someProperty;
    
    - (void) someMethod;
    
    @end
    

    In CustomObject.m

    #import "CustomObject.h"
    
    @implementation CustomObject 
    
    - (void) someMethod {
        NSLog(@"SomeMethod Ran");
    }
    
    @end
    

    Step 5: Add Class to Bridging-Header

    In YourProject-Bridging-Header.h:

    #import "CustomObject.h"
    

    Step 6: Use your Object

    In SomeSwiftFile.swift:

    var instanceOfCustomObject: CustomObject = CustomObject()
    instanceOfCustomObject.someProperty = "Hello World"
    println(instanceOfCustomObject.someProperty)
    instanceOfCustomObject.someMethod()
    

    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 it MySwiftObject.swift.

    In MySwiftObject.swift:

    import Foundation
    
    class MySwiftObject : NSObject {
    
        var someProperty: AnyObject = "Some Initializer Val"
    
        init() {}
    
        func someFunction(someArg:AnyObject) -> String {
            var returnVal = "You sent me \(someArg)"
            return returnVal
        }   
    }
    

    Step 2: Import Swift Files to ObjC Class

    In SomeRandomClass.m:

    #import "<#YourProjectName#>-Swift.h"
    

    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

    MySwiftObject * myOb = [MySwiftObject new];
    NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
    myOb.someProperty = @"Hello World";
    NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
    NSString * retString = [myOb someFunction:@"Arg"];
    NSLog(@"RetString: %@", retString);
    

    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.

    点赞 打赏 评论
  • 斗士狗 2014-06-02 20:43

    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:

    UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    

    turns into this Swift code:

    let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)
    

    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).

    点赞 打赏 评论
  • 叼花硬汉 2014-06-02 20:43

    Quote from the documentation:

    Any Objective-C framework (or C library) that’s accessible as a module can be imported directly into Swift. This includes all of the Objective-C system frameworks—such as Foundation, UIKit, and SpriteKit—as well as common C libraries supplied with the system. For example, to import Foundation, simply add this import statement to the top of the Swift file you’re working in:

    import Foundation

    This import makes all of the Foundation APIs—including NSDate, NSURL, NSMutableData, and all of their methods, properties, and categories—directly available in Swift.

    点赞 打赏 评论
  • local-host 2014-06-04 02:11

    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.

    let manager = AFHTTPRequestOperationManager()
    manager.GET(
      "http://example.com/resources.json",
      parameters: nil,
      success: { (operation: AFHTTPRequestOperation!,
                  responseObject: AnyObject!) in
          println("JSON: " + responseObject.description)
      },
      failure: { (operation: AFHTTPRequestOperation!,
                  error: NSError!) in
          println("Error: " + error.localizedDescription)
      })
    

    Also have a look at Apple's document Using Swift with Cocoa and Objective-C as well.

    点赞 打赏 评论
  • 7*4 2014-06-13 10:10

    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.

    点赞 打赏 评论
  • hurriedly% 2015-02-12 19:34

    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:

    1. Add any Objective-C file to your Swift project by choosing File -> New -> New File -> Objective-C File. Upon saving, Xcode will ask if you want to add a bridging header. Choose 'Yes'. Gif: adding empty file to project and generating bridging header http://www.derrrick.com/stackoverflow/1-empty-file.gif

    In simple steps:

    1. 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.

    2. Optionally, delete the Objective-C file you added (named "anything" in the GIF image above). You don't need it any more.

    3. 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:

      #import "Mixpanel.h"
    4. 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:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        Mixpanel.sharedInstanceWithToken("your-token")
        return true
    }
    

    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".

    点赞 打赏 评论
  • derek5. 2015-09-10 12:16

    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".

    点赞 打赏 评论
  • 喵-见缝插针 2015-09-16 07:00

    One more thing I would like to add here:

    I am very thankful to @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 in my project. Which is pod "pop".

    So if 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:

    1. Go to <YOUR-PROJECT>-Bridging-Header file and
    2. Replace the statement #import <ObjC_Framework> to @import ObjC_Framework

    For example: (Pop library)

    Replace

    #import <pop/POP.h>
    

    with

    @import pop;
    

    Use clang import when #import is not working.

    点赞 打赏 评论
  • 7*4 2015-11-25 08:29

    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"

    eEter image description here

    点赞 打赏 评论
  • 衫裤跑路 2016-03-20 17:53

    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.

    点赞 打赏 评论
  • 三生石@ 2016-09-28 07:12

    Any Objective-C framework (or C library) that’s accessible as a module can be imported directly into Swift. This includes all of the Objective-C system frameworks—such as Foundation, UIKit, and SpriteKit—as well as common C libraries supplied with the system. For example, to import Foundation, simply add this import statement to the top of the Swift file you’re working in:

    import Foundation
    

    This import makes all of the Foundation APIs—including NSDate, NSURL, NSMutableData, and all of their methods, properties, and categories—directly available in Swift.

    I have taken this from Apple's documentation.

    点赞 打赏 评论
  • ℡Wang Yan 2017-06-29 06:38
    1. Create a .h file from NewFile -> Source -> header file
    2. Then save the name of file Your_Target_Name-Bridging-Header.h People here gets common mistake by taking their project name but it should be the Project's Target's name if in case both are different, generally they are same.
    3. Then in build settings search for Objective-C Bridging Header flag and put the address of your newly created bridging file, you can do it right click on the file -> show in finder -> drag the file in the text area then the address will be populated.
    4. Using #import Your_Objective-C_file.h
    5. In the swift file you can access the ObjC file but in swift language only.
    点赞 打赏 评论
  • 笑故挽风 2018-04-13 09:39

    Two way Approach to use objective-c objective-c

    1

    1. Create bridge-header.h file in Xcode Project
    2. import .h file in bridge-Header file
    3. Set path of bridge-Header in Build settings. 
    3. Clean the Project 
    

    2

      1. Create objective-c files in project(it automatically set path in Build Settings for you )
      2. import .h file in bridge-Header file
    

    Now good to go Thanks

    点赞 打赏 评论
  • MAO-EYE 2018-05-19 16:27

    enter image description hereI have added the project on github that include small sample to call objective c code from swift.

    Call ObjectiveC class from swift

    点赞 打赏 评论
  • 斗士狗 2018-06-12 21:43

    In the Swift 4.2 project in Xcode 9.4 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?

    enter image description here

    Step_04: Select the option:

    Create Bridging Header.

    Step_05: A corresponding file will be generated with a name:

    Objc-Bridging-Header.h.

    enter image description here

    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.

    enter image description here

    Step_08: Open your Objc-Bridging-Header.h file and import the Objective-C file which you want to use in your Swift file.

    #import "SpecialObjcFile.m"
    

    Here's a content of SpecialObjcFile.m:

    #import <Foundation/Foundation.h>
    
    @interface Person: NSObject {
    @public
        bool busy;
    }
    @property
        bool busy;
    @end
    

    Step_09: Now in your Swift file, you can use an Objective-C class:

    override func viewDidLoad() {
        super.viewDidLoad()
        let myObjcContent = Person()
        print(myObjcContent.busy)
    }
    

    enter image description here enter image description here

    点赞 打赏 评论

相关推荐