objective-c - swift社区 - swift转oc工具




如何从Swift中调用Objective-C代码 (9)

在Apple的新Swift语言中,如何调用Objective-C代码?

Apple提到它们可以共存于一个应用程序中,但是这是否意味着可以在技术上重新使用Objective-C中制作的旧类,同时在Swift中构建新类?

推理

Objective-C是一种独立于平台的语言,而Swift是平台依赖的。 因此,在Swift中编写非平台相关的代码(业务逻辑库)不是明智之举。 但是,编写与平台相关的代码(例如,相关接口)将会非常好。 并不是说这将是一个好主意,但它绝对是一种兴趣。


在Swift中使用Objective-C类

**如果您有一个您想使用的现有课程,请执行步骤2 ,然后跳至步骤5 。 (对于某些情况,我必须将一个明确的#import <Foundation/Foundation.h到较旧的Objective-C文件中。)**

第1步:添加Objective-C实现 - .m

.m文件添加到您的类中,并将其命名为CustomObject.m

第2步:添加桥接头

添加.m文件时,您可能会看到如下所示的提示:

点击

如果您没有看到提示,或者意外删除了桥接头,请在项目中添加一个新的.h文件并将其命名为<#YourProjectName#>-Bridging-Header.h您的项目名称<#YourProjectName#>-Bridging-Header.h

在某些情况下,特别是使用Objective-C框架时,不要明确添加Objective-C类,并且Xcode无法找到链接器。 在这种情况下,创建如上所述命名的.h文件,然后确保将其路径链接到目标的项目设置中,如下所示:

注意

最好的做法是使用$(SRCROOT)宏链接项目,这样如果您移动项目或使用远程存储库与其他项目一起工作,它仍然可以工作。 $(SRCROOT)可以被认为是包含你的.xcodeproj文件的目录。 它可能看起来像这样:

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

第3步:添加Objective-C标题 - .h

添加另一个.h文件并将其命名为CustomObject.h

第4步:构建您的Objective-C类

CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

第5步:将类添加到桥接头

YourProject-Bridging-Header.h

#import "CustomObject.h"

第6步:使用你的对象

SomeSwiftFile.swift

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

没有必要明确导入; 这就是桥接头的作用。

在Objective-C中使用Swift类

第1步:创建新的Swift类

.swift文件添加到您的项目中,并将其命名为MySwiftObject.swift

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
    }   
}

第2步:将Swift文件导入ObjC类

SomeRandomClass.m

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

文件: <#YourProjectName#>-Swift.h您的项目<#YourProjectName#>-Swift.h应该已经在您的项目中自动创建,即使您看不到它。

第3步:使用你的班级

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

注意:

CodeCompletion的表现并不像我想要的那么准确。 在我的系统上,使用“cmd + r”运行快速构建似乎有助于Swift找到一些Objective-C代码,反之亦然。

2.如果将.swift文件添加到较旧的项目并出现错误: dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib ,请尝试完全重新启动Xcode 。

3.尽管在Swift 2.0之后,通过使用@objc前缀在Objective-C中最初可能使用纯Swift类,但这不再可能。 请参阅编辑历史以获取原始说明 如果此功能在未来的Swift版本中重新启用,则答案将相应更新。


我还想再补充一点:

我非常感谢@ Logan的回答。 它有助于创建桥接文件和设置。

但是在完成所有这些步骤之后,我仍然没有在Swift中获得Objective-C类。

我使用了cocoapods库并将其集成到我的项目中。 哪个是pod "pop"

因此,如果在Swift中使用Objective-C窗格,则可能有可能无法将类导入到Swift中。

你必须做的简单事情是:

  1. 转到<YOUR-PROJECT>-Bridging-Header文件和
  2. 将语句#import <ObjC_Framework>替换为@import ObjC_Framework

例如:(流行音乐库)

更换

#import <pop/POP.h>

@import pop;

#import不工作时使用clang import #import


双向使用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

现在很好去, 谢谢


文档引用:

任何可作为模块访问的Objective-C框架(或C库)都可以直接导入到Swift中。 这包括所有的Objective-C系统框架(如Foundation,UIKit和SpriteKit)以及随系统提供的通用C库。 例如,要导入Foundation,只需将此导入语句添加到您正在使用的Swift文件的顶部:

import Foundation

该导入使所有Foundation API(包括NSDate,NSURL,NSMutableData及其所有方法,属性和类别)都可以直接在Swift中使用。


任何可作为模块访问的Objective-C框架(或C库)都可以直接导入到Swift中。 这包括所有的Objective-C系统框架(如Foundation,UIKit和SpriteKit)以及随系统提供的通用C库。 例如,要导入Foundation,只需将此导入语句添加到您正在使用的Swift文件的顶部:

import Foundation

该导入使所有Foundation API(包括NSDate,NSURL,NSMutableData及其所有方法,属性和类别)都可以直接在Swift中使用。

我从Apple的文档中了解到了这一点。


你可以阅读不错的帖子Swift&Cocoapods 。 基本上,我们需要创建一个桥接头文件并将所有Objective-C头文件放在那里。 然后我们需要从我们的构建设置中引用它。 之后,我们可以使用Objective-C代码。

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

还可以看看Apple的文档Using Cocoa和Objective-C中的Swift


在创建桥接头后,转到Build Setting =>搜索“Objective-C桥接头”。

在下面你会找到“Objective-C生成的接口标题名称”文件。

在视图控制器中导入该文件。

例子:在我的情况下:“Dauble-Swift.h”


我写了一个简单的Xcode 6项目,演示了如何混合使用C ++,Objective-C和Swift代码:

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

特别是,该示例从Swift中调用Objective-C和C ++函数

关键是创建一个共享头文件Project-Bridging-Header.h,并将Objective-C头文件放在那里。

请下载该项目作为一个完整的例子。


请参阅Apple 在Cocoa和Objective-C中使用Swift的指南。 本指南介绍了如何使用Swift中的Objective-C和C代码,反之亦然,并提供了如何转换项目或在现有项目中混合匹配Objective-C / C和Swift部分的建议。

编译器自动生成调用C函数和Objective-C方法的Swift语法。 从文档中可以看出,这个Objective-C:

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

变成这个Swift代码:

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

Xcode也可以随时进行这种翻译 - 您可以在编辑Swift文件时使用Open Quickly并键入一个Objective-C类名称,并将它带到Swift ified版本的类头部。 (你也可以通过在一个Swift文件中用cmd单击一个API符号来获得这个)。在Objective-C和Swift中都可以看到iOS 8OS X v10.10(Yosemite)开发库中的所有API参考文档形式(例如UIView )。







swift