Tag: 互操作性

设置Swift和Objective-C互操作性

3.在此处添加要在swift类中使用的Objective-C类的导入头。 将头文件包含在Bridging头文件中后,就无需将其重新导入到任何Swift文件中。 可以在项目中的所有swift文件中访问它。 现在,您选择的Objective-C对象可用于您的快速班!! 做得好!! 使用Swift和Objective-C时要谨记的事情 Swift和Objective-C有一些根本的区别,在使用两种语言进行工作时,需要牢记一些非常重要的事情。 为了使从一种语言到另一种语言的过渡最顺畅,最好记住它们的独特功能。 Swift和Objective-C之间的区别 如果swift类中的方法或变量没有出现在Objective-C文件中,则可能是因为Objective-C不支持确定该方法或变量的特定功能。 以下是在Objective-C中不可用的Swift功能的简短列表:在swift中定义的元组,泛型,任何全局变量,结构,类型别名或枚举,以及顶级swift函数。 解决这个问题的一种方法是创建一个包装器类,该包装器类可以处理这些不可用的功能,并在与Objective-C类进行交谈时被调用。 子类限制 局限性之一是无法从子类快速分类。 Swift对象可以具有Objective-C类的子类,例如NSObject。 但是,快速类不能成为Objective-C类的基础类。 种类 幸运的是,objective-C类型和swift类型彼此之间具有很好的对应性,并且可以跨语言很好地进行翻译。 选装件 可选状态是Objective-C和Swift之间在功能上非常重要的区别。 当您从Objective-C将参数传递给Swift类时,Swift必须知道变量的可选状态。 在Swift中,任何事物都可以保持未定义状态,甚至可能为零。 由于Objective-C不满足此要求,因此传入的参数可能会自动后面跟一个!。 或爆炸符号,或其他更严重的问题和错误可能会发生。 理想情况下,您应该设置某种方式来检查要快速传递的每个变量的可选状态。 将属性传递给swift时,您可以采取的一种初步措施是在Objective-C类文件中从一开始就声明非null或可为null。 @属性(非原子,强,非空)NSString * name; 这使swift文件知道该变量在收到后不会为null。 作为捷径,您还可以指定整个文件为非空或可为空。 在文件的@interface之前添加以下行。 NS_ASSUME_NONNULL_BEGIN 然后在@end之后添加下一行。 NS_ASSUME_NONNULL_END 感谢您的阅读! 有用的链接和来源: 将Swift与Cocoa和Objective-C(Swift 3.1)结合使用:基本设置 描述Swift与Objective-C语言和Cocoa / Cocoa Touch框架的兼容性的各个方面。 developer.apple.com Swift和Objective-C:永远的好朋友? 我们很高兴在我们的SLUG聚会上欢迎Jonathan Blocksom。 经验丰富的行业资深人士,乔纳森(Jonathan)具有真正的… realm.io 将Swift与Cocoa和Objective-C(Swift 3.1)结合使用:与Objective-C API交互 描述Swift与Objective-C语言和Cocoa / Cocoa […]

深入研究Swift和Objective-C之间的互操作性

当您开始一个新的iOS项目时,毫无疑问,您应该完全使用Swift编写它。 Swift已经接管了Objective-C多年了。 https://www.tiobe.com/tiobe-index/使用Swift强大的编译器,我们可以更安全,更快速地构建软件。 但是在现实世界中,我们可能会在Objective-C中面临许多过时的代码。 由于Swift / Objective-C具有出色的互操作性,因此我们可以维护包含它们的项目。 有关如何设置它们的信息,请查看https://medium.com/ios-os-x-development/swift-and-objective-c-interoperability-2add8e6d6887。 处理旧的ObjC的最常见策略是在Swift中编写任何新功能,并修改Objective-C文件以使用它们。 空性抬头 Swift是一种全新的语言,尽管它与Objective-C兼容。 Swift为我们介绍了一些基本类型,例如Date , Data , String。 并且它们可以自动桥接到Objective-C中的对象,即NSDate,NSData,NSString。 但是,由于Swift引入了optional / non-optional ,当Swift代码转换为Objective-C时,事情会有些棘手。 这是一个例子。 我们定义一些Swift函数,并通过添加关键字@objc使它们在Objective-C中可用 @objc func testString(_ string:String){print(string)} @objc func testData(_ data:Data){print(data)} @ objc func testDate(_ date:Date){print(date)} 在Objective-C中,我们会得到。 -(void)testString:(NSString * _Nonnull)string;-(void)testData:(NSData * _Nonnull)data;-(void)testDate:(NSDate * _Nonnull)date; 因为在Objective-C中没有可选/非可选 ,所以我们有_Nonnull。 有关Objective-C中的可空性的更多信息,请参阅 Apple的博客 )。 如果我们使用nil调用此函数,则只会收到警告。 如果我们不将nil显式地传递给这些函数(例如下面的代码),我们可能也不会意识到那些警告。 这些函数中传递的对象不能为nil,因为在Swift中将这些函数的参数定义为非可选的,因此Swift运行时将尝试从nil创建对象。 这是非常危险的,结果也令人惊讶。 [self testString:nil]; […]

Objective-C和Swift —友好

有时候,对于Swift开发,仍然需要Objective-C。 例如,使用我在Swift,Speculid中内置的一个这样的应用程序,我需要引入Objective-C代码。随着2.0版中C ++库的引入,Objective-C成为必需。 幸运的是,有一些方法可以使Objective-C和Swift以友好的方式一起工作。 Speculid是使用最新版本的Xcode构建的完全开源的应用程序。 它可以自动将PNG和SVG文件转换为完整的图像集和应用程序图标的过程。 在第一个版本中,它需要安装Inkscape和ImageMagick以便于将图像从SVG或PNG转换为PDF或PNG。 这在安装和使用上都变得麻烦。 对于2.0版,我希望通过删除任何先决条件步骤和预先存在的依赖关系,使安装和集成过程尽可能地容易。 这意味着将所有必需的依赖项打包在应用程序包中。 在这种情况下,我们使用两个C ++库Cairo和libRSVG 。 开罗是整个开源社区中使用的领先2D库,而libRSVG用于读取SVG内容。 有了这两个库,接下来的挑战就变成了将它们集成到Swift代码中。 到目前为止,Swift无法直接与C ++交互。 因此,我们需要一个中介,并且这些中介可以是C或Objective-C的代码。 尽管C具有一些简单性,但在这种情况下,我选择了Objective-C。 我不仅拥有Objective-C的经验,而且Objective-C与Apple生态系统具有强大的集成。 尽管C的简单性。在我使用Objective-C时,我想将大部分代码保留在Swift中。 Objective-C仅在需要时用于与C ++库接口。 Swift将与用户交互,管理作业等……Objective-C将调用C ++库来构建实际的图形。 Swift代码将完全不了解实际用于读取,操作和写入结果文件的代码。 这是该过程的简要概述: Main —实例化并运行NSApplication SpeculidApplication —查找有问题的文件并使用Codable解析文件 查找源图形文件(PNG或SVG) 解析资产目录文件 解析规范文件中的规范 创建要传递给Objective-C代码的规范 在Objective-C中 ,使用传递给C ++函数的规范来写出目标图形文件(PNG或PDF) 有两种方法可以使我们的Objective-C和Swift代码协同工作。 一种是确保API使用兼容的类型。 Objective-C不使用Swift Structs。 这使类成为在Swift和Objective-C框架之间传递复杂数据的唯一方法。 但是,为了使接口彼此不可知,我们可以在Objective-C API中创建协议,这些协议可以向Swift表示所需的内容。 在我们的Objective-C框架中,Swift提供了两种方法。 调用Cairo库并采用ImageSpecificationProtocol和ImageHandle对象的主要方法: @interface CairoInterface:NSObject +(BOOL)exportImage:(id )sourceHandle withSpecification:(id )规范错误:(NSError **)错误; @结束 […]