简体   繁体   English

将 Objective-C 框架连接到 Swift iOS 8 应用程序(解析框架)

[英]Connect Objective-C framework to Swift iOS 8 app (Parse framework)

I am trying to use an Objective-C framework with the Swift programming language for iOS 8 development.我正在尝试使用带有 Swift 编程语言的 Objective-C 框架进行 iOS 8 开发。 This is a specific case of an import but the general problem is:这是导入的特定情况,但一般问题是:

How do you import an Objective-C framework into swift and get the import recognized?你如何将一个 Objective-C 框架导入 swift 并让导入被识别?

I am trying to integrate the Parse framework into a swift application using the iOS 8 and Xcode 6 betas.我正在尝试使用 iOS 8 和 Xcode 6 beta 将 Parse 框架集成到一个 swift 应用程序中。

Here is the technique for Parse framework integration in Objective-C:以下是 Objective-C 中 Parse 框架集成的技术:

https://www.parse.com/apps/quickstart#social/mobile/ios/native/existing https://www.parse.com/apps/quickstart#social/mobile/ios/native/existing

I have downloaded the Parse framework as a compressed archive, extracted it, and imported it into Xcode 6 without any problems.我已将 Parse 框架下载为压缩档案,将其解压缩并将其导入 Xcode 6,没有任何问题。 Within my application it appears as a properly formatted framework under the name Parse.framework.在我的应用程序中,它显示为名称为 Parse.framework 的格式正确的框架。

My current thought process is to modify the AppDelegate.swift file in the root directory of my project.我目前的思路是修改项目根目录下的AppDelegate.swift文件。 Here is the current file without modifications (automatically generated by Xcode upon swift project creation):这是未经修改的当前文件(由 Xcode 在 swift 项目创建时自动生成):

https://gist.github.com/fconcklin/e8ef7d8b056105a04161 https://gist.github.com/fconcklin/e8ef7d8b056105a04161

I have tried to import parse by adding the line import Parse below the line import UIKit .我试图通过在import UIKit行下方添加import Parse行来导入 parse 。 However, Xcode issues a warning that there is no such module found and the build fails.但是,Xcode 会发出警告,指出找不到此类模块并且构建失败。

I also tried creating a file ${PROJ_NAME_HERE}-Bridging-Header.h that contains the Objective-C import of Parse using import <Parse/Parse.h> .我还尝试使用import <Parse/Parse.h>创建一个文件${PROJ_NAME_HERE}-Bridging-Header.h ,其中包含 Parse 的 Objective-C 导入。 This line doesn't throw an error but appears to ultimately make no difference.该行不会引发错误,但似乎最终没有任何区别。

After further research I found the solution and realized that I was just confused.经过进一步研究,我找到了解决方案,并意识到我只是感到困惑。

The correct approach is as follows:正确的做法如下:

  • Import your Objective C framework by dragging and dropping the framework into an Xcode 6 Swift project.通过将框架拖放到 Xcode 6 Swift 项目中来导入您的 Objective C 框架。

  • Create a new Objective C file in your project (File->New->File [Objective C for iOS]).在您的项目中创建一个新的 Objective C 文件(File->New->File [Objective C for iOS])。

  • Accept the prompt (agree) to create a bridging header file between Objective C and Swift.接受提示(同意)以在 Objective C 和 Swift 之间创建桥接头文件。

  • Delete your newly created Objective C file but retain the bridging header file ${YOURPROJ}-Bridging-Header.h .删除您新创建的 Objective C 文件,但保留桥接头文件${YOURPROJ}-Bridging-Header.h

  • In the Bridging header file, import your framework using the standard Objective C import syntax (eg #import <Parse/Parse.h> ).在 Bridging 头文件中,使用标准的Objective C导入语法(例如#import <Parse/Parse.h> )导入您的框架。

  • This relinquishes the need to perform an import Parse statement in your AppDelegate.swift file.这不再需要在AppDelegate.swift文件中执行import Parse语句。 You can now write code that utilizes whatever framework as long as it is imported using the bridging header.您现在可以编写使用任何框架的代码,只要它是使用桥接头导入的。 It is available throughout your project's Swift files.它在您项目的 Swift 文件中都可用。

Now, if you would like to test Parse integration in your project, you can type Parse.现在,如果您想在您的项目中测试 Parse 集成,您可以输入Parse. and use code completion to browse the framework and see that the code completion is indicative of a successful import.并使用代码完成浏览框架并查看代码完成表示导入成功。

However, there is another caveat here that needs to be addressed when using a Bridging Header file.但是,在使用桥接头文件时,这里还有一个需要注意的问题。 All dependencies of the framework need to be specified in the Bridging Header file as well.框架的所有依赖项也需要在桥接头文件中指定。 In the case of integrating Parse framework into a Swift application your Bridging Header file will look like this:如果将 Parse 框架集成到 Swift 应用程序中,您的桥接头文件将如下所示:

 #import <Foundation/Foundation.h>

 // Parse Dependencies
 #import <AudioToolbox/AudioToolbox.h>
 #import <CFNetwork/CFNetwork.h>
 #import <CoreGraphics/CoreGraphics.h>
 #import <CoreLocation/CoreLocation.h>
 #import <MobileCoreServices/MobileCoreServices.h>
 #import <QuartzCore/QuartzCore.h>
 #import <Security/Security.h>
 #import <StoreKit/StoreKit.h>
 #import <SystemConfiguration/SystemConfiguration.h>

 // Import parse framework
 #import <Parse/Parse.h>

Hope this helps.希望这可以帮助。

A "Fool Proof" way of adding a bridging header is as follows:添加桥接头的“傻瓜证明”方式如下:

If you have a Swift project, add a new Objective-C File to your project and Xcode will prompt if you want to configure your project with a bridging header.如果你有一个Swift项目,在你的项目中添加一个新的Objective-C 文件,Xcode 会提示你是否想用桥接头配置你的项目。 Press yes.按是。

If you have a Objective-C project, add a new Swift File to it and you will get the same prompt.如果您有一个Objective-C项目,向其中添加一个新的Swift 文件,您将得到相同的提示。 Press yes.按是。

After you get the bridging header, you can delete the file you just added if you want to.获得桥接头后,您可以根据需要删除刚刚添加的文件。

To add Parse framework to the Swift project: Add this libaries to the Swift Project.将 Parse 框架添加到 Swift 项目: 将此库添加到 Swift 项目。

在此处输入图片说明

Paste this frameworks from ParseSDK to your project:将此框架从 ParseSDK 粘贴到您的项目中:

在此处输入图片说明

Add a ProjectName-Bridging-Header.h ( https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html ) ( https://stackoverflow.com/a/24272431/1847511 ) file with such content.添加 ProjectName-Bridging-Header.h ( https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/MixandMatch.html ) ( https://stackoverflow.com/a/24272431/1847511 ) 具有此类内容的文件。

在此处输入图片说明

Add path to tie bridging header:添加连接桥接头的路径:

在此处输入图片说明

Add the TestCode:添加测试代码:

在此处输入图片说明

Run the app.运行应用程序。

The answer for my problem was different.我的问题的答案是不同的。 I had the Framework Search Paths in my project's Build Settings set to recursive when they should have been non-recursive .在项目的 Build Settings中将Framework Search Paths设置为recursive不是 recursive

In my case, my target has its Framework Search Paths set to $(inherited) , which means to inherit the setting from my project.就我而言,我的目标将其框架搜索路径设置为$(inherited) ,这意味着从我的项目继承设置。

My project's Framework Search Paths only had one path, $PROJECT_DIR/../External/** (with the two asteriks meaning "search this folder recursively". My Parse.framework file was located in the base level of the External folder.我的项目的框架搜索路径只有一个路径, $PROJECT_DIR/../External/** (两个星号表示“递归搜索此文件夹”。我的Parse.framework文件位于外部文件夹的基本级别。

Changing the path from recursive to non-recursive fixed things for me.为我改变从递归非递归固定事物的路径。 Very strange...很奇怪...

New Parse framework version need some update.新的 Parse 框架版本需要一些更新。

Such as You should insert libsqlite3.0.dylib in Library Binary With Libraries and update header file with #import and #import比如你应该在Library Binary With Libraries 中插入libsqlite3.0.dylib 并用#import 和#import 更新头文件

Using Objective-C Classes in Swift在 Swift 中使用 Objective-C 类

If you are going to import code within an App Target (Mixing Swift and Objective-C in one project) you should use bridging header file to expose Objective-C code to Swift code.如果您要在 App Target 中导入代码(在一个项目中混合 Swift 和 Objective-C),您应该使用bridging header文件将 Objective-C 代码暴露给 Swift 代码。 [Mixing Swift and Objective-C code in a project] [在一个项目中混合使用 Swift 和 Objective-C 代码]

In this post I will describe how to import Objective-C framework to Swift code在这篇文章中,我将描述如何将 Objective-C 框架导入 Swift 代码

Swift consumer -> Objective-C dynamic framework Swift 消费者 -> Objective-C 动态框架

Xcode version 10.2.1 Xcode 版本 10.2.1

Create Objective-C framework创建 Objective-C 框架

Create a framework project or create a framework target创建框架项目或创建框架目标

File -> New -> Project... -> Cocoa Touch Framework
//or
Project editor -> Add a Target -> Cocoa Touch Framework

Two files will be generated:将生成两个文件:

  1. Info.plist - Build Settings -> Info.plist File Info.plist - Build Settings -> Info.plist File
  2. <product_name>.h - Build Phases -> Headers . <product_name>.h - Build Phases -> Headers It is umbrella header file which will be open for consumer [About]为消费者开放的伞头文件[关于]

Add all .h files to this umbrella file(<product_name>.h)将所有.h文件添加到这个伞文件中(<product_name>.h)

#import "header_1.h"
#import "header_2.h"

Add Implementation files .m添加实现文件.m

Select `.m` file -> Select File Inspectors Tab -> Target Membership -> Select the target
//or
Project editor -> select a target -> Build Phases -> Compile Sources -> add files

Add Headers files .h that were listed in <product_name>.h in public zone ( header_1.h , header_2.h ) [can not do it] [public target membership]添加在公共区域的<product_name>.h中列出的头文件.h ( header_1.h , header_2.h ) [不能这样做] [公共目标成员资格]

Select `.h` file -> Select File Inspectors Tab -> Target Membership -> Select the target and make it **public**
//or
Project editor -> select a target -> Build Phases -> Headers -> add files to the **public** zone

Build the framework - ⌘ Command + B or Product -> Build构建框架 - ⌘ Command + BProduct -> Build

Note: Be sure that you build the framework for the same process architecture as the client code.注意:确保为与客户端代码相同的流程架构构建框架。

Find generated output [Build location]查找生成的输出[构建位置]

Products group -> <product_name>.framework -> Show in Finder

The framework includes该框架包括

  • Info.plist
  • Modules folder with: Modules文件夹:
  • module.modulemap [About] [Custom modulemap] This file was autogenerated because Build Settings -> Defines Module -> YES module.modulemap [About] [Custom modulemap]这个文件是自动生成的,因为Build Settings -> Defines Module -> YES
  • Headers folder with: Headers文件夹:
  • files from Headers section.来自Headers部分的文件。 There are public interfaces/definitions有公共接口/定义

Swift consumer with Objective-C framework带有 Objective-C 框架的 Swift 消费者

Drag and drop the binary into the Xcode project [About] Drag and drop二进制文件Drag and drop到Xcode项目中【关于】

Embed binaries [Library not loaded] [Link vs Embed] Embed binaries [库未加载] [链接与嵌入]

Project editor -> select a target -> General -> Embedded Binaries -> path to `<product_name>.framework` file

I will automatically add the framework to:我会自动将框架添加到:

  1. Project editor -> select a target -> General -> Linked Frameworks and Libraries
  2. Project editor -> select a target -> Build Phases -> Embed Frameworks
  3. Project editor -> select a target -> Build Phases -> Link Binary With Libraries

Add Framework Search paths(FRAMEWORK_SEARCH_PATHS) [Module not found] [Recursive path]添加Framework Search paths(FRAMEWORK_SEARCH_PATHS) [未找到模块] [递归路径]

Project editor -> select a target -> Build Settings -> Search Paths -> Framework Search paths -> add path to the parent of `<product_name>.framework` file

Import module to the Swift client code [module_name]将模块导入 Swift 客户端代码[module_name]

import module_name

More examples here更多例子在这里

Using Objective-C Classes in Swift 在Swift中使用Objective-C类

If you are going to import code within an App Target (Mixing Swift and Objective-C in one project) you should use bridging header file to expose Objective-C code to Swift code. 如果要在App Target中导入代码(在一个项目中混合Swift和Objective-C),您应该使用bridging header文件将Objective-C代码暴露给Swift代码。 [Mixing Swift and Objective-C code in a project] [在项目中混合使用Swift和Objective-C代码]

In this post I will describe how to import Objective-C framework to Swift code 在这篇文章中,我将描述如何将Objective-C框架导入Swift代码

Swift consumer -> Objective-C dynamic framework Swift consumer - > Objective-C动态框架

Xcode version 10.2.1 Xcode版本10.2.1

Create an Objective-C framework 创建Objective-C框架

Create a framework project or create a framework target 创建框架项目或创建框架目标

File -> New -> Project... -> Cocoa Touch Framework
//or
Project editor -> Add a Target -> Cocoa Touch Framework

Two files will be generated: 将生成两个文件:

  1. Info.plist - Build Settings -> Info.plist File Info.plist - Build Settings -> Info.plist File
  2. <product_name>.h - Build Phases -> Headers . <product_name>.h - Build Phases -> Headers It is umbrella header file [About] 它是伞头文件[关于]

Add all .h files to umbrella file that will be open for consumer 将所有.h文件添加到将为消费者开放的伞文件中

#import "header_1.h"
#import "header_2.h"

Add Implementation files .m 添加实施文件.m

Select `.m` file -> Select File Inspectors Tab -> Target Membership -> Select the target
//or
Project editor -> select a target -> Build Phases -> Compile Sources -> add files

Add Headers files .h that were listed in <product_name>.h ( header_1.h , header_2.h ) [can not do it] [public target membership] 添加<product_name>.hheader_1.hheader_2.h )中列出的Headers文件.h [无法执行] [公共目标成员资格]

Select `.h` file -> Select File Inspectors Tab -> Target Membership -> Select the target and make it **public**
//or
Project editor -> select a target -> Build Phases -> Headers -> add files to the **public** zone

Build the framework - ⌘ Command + B or Product -> Build 构建框架 - ⌘Command + BProduct -> Build

Note: Be sure that you build the framework for the same process architecture as the client code. 注意:确保为与客户端代码相同的流程体系结构构建框架。

Find generated output [Build location] 查找生成的输出[构建位置]

Products group -> <product_name>.framework -> Show in Finder

The framework includes 该框架包括

  • Info.plist
  • Modules folder with: Modules文件夹:
  • Headers folder with: Headers文件夹:
    • files from Headers section. 来自Headers部分的文件。 There are public interfaces/definitions 有公共接口/定义

Using Objective-C framework 使用Objective-C框架

Drag and drop the binary into the Xcode project [About] Drag and drop二进制文件Drag and drop到Xcode项目中[关于]

Embed binaries [Library not loaded] [Link vs Embed] Embed binaries [未加载库] [链接与嵌入]

Project editor -> select a target -> General -> Embedded Binaries -> path to `<product_name>.framework` file

I will automatically add the framework to: 我会自动将框架添加到:

  1. Project editor -> select a target -> General -> Linked Frameworks and Libraries
  2. Project editor -> select a target -> Build Phases -> Embed Frameworks
  3. Project editor -> select a target -> Build Phases -> Link Binary With Libraries

Add Framework Search paths [Module not found] [Recursive path] 添加Framework Search paths [找不到模块] [递归路径]

Project editor -> select a target -> Build Settings -> Search Paths -> Framework Search paths -> add path to the parent of `<product_name>.framework` file

Import module to the Swift client code [module_name] 将模块导入Swift客户端代码[module_name]

import module_name

More examples here 这里有更多例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM