简体   繁体   English

如何在包括 Swift 在内的 iOS 中创建开发框架?

[英]How Do I Create a Development Framework In iOS Including Swift?

My goal in this was to create an iOS framework that incorporates both Swift and Objective-C that I could use in my development projects.我的目标是创建一个结合了 Swift 和 Objective-C 的 iOS 框架,我可以在我的开发项目中使用它。 The nature of this framework is that the framework itself is undergoing development.这个框架的本质是框架本身正在开发中。 So, it was important that each time I build a project using this framework (I'll call projects using the framework "using" projects for lack of a better term), I wanted to make sure the framework itself was re-built.因此,每次我使用这个框架构建一个项目时(由于缺乏更好的术语,我将使用框架的项目称为“使用”项目),我想确保框架本身被重新构建,这一点很重要。 I wanted this to be a framework because I have a few using apps across which I want to use the same framework code.我希望这是一个框架,因为我有一些使用应用程序,我想在这些应用程序中使用相同的框架代码。 I have struggled with this for a good hunk of today, and wasted a lot of time on something that should have been, in my thoughts at least, easier.为了今天的好身材,我一直在为此苦苦挣扎,并且在至少在我看来应该更容易的事情上浪费了很多时间。 So, I'll share my process.所以,我会分享我的过程。

The first thing to observe (which was certainly not my first observation!) is that you cannot do this using a static library under iOS.首先要观察(这当然不是我的第一次观察!)是你不能在 iOS 下使用静态库来做到这一点。 Xcode will not let you use Swift in a static framework Try it. Xcode 不会让你在静态框架中使用 Swift 试试吧。 Xcode will deny your wishes! Xcode 会拒绝你的愿望!

Here's the process I ended up with.这是我结束的过程。 The two main issues I had to deal with were: (i) making Xcode link to the framework in the using project without errors, and (ii) getting access to the headers of the framework in the using project.我必须处理的两个主要问题是:(i) 使 Xcode 链接到 using 项目中的框架而不会出错,以及 (ii) 访问 using 项目中框架的标头。 In Apple's enlightened view these two issues are separate.在苹果开明的观点中,这两个问题是分开的。 Note the sarcasm.注意讽刺。 ;). ;)

1) Create a Cocoa Touch Framework using Xcode. 1) 使用 Xcode 创建Cocoa Touch Framework I believe this works with Xcode6 and Xcode7.我相信这适用于 Xcode6 和 Xcode7。 Use:用:

File > New > Project > iOS > Framework & Library > Cocoa Touch Framework文件 > 新建 > 项目 > iOS > 框架和库 > Cocoa Touch 框架

I happen to be using Xcode7.我碰巧在使用 Xcode7。 (Do not make a Cocoa Touch Static Library -- like I said above, Xcode will not let you incorporate Swift into static libraries). 不要让一个Cocoa Touch Static Library -就像我上面说的,Xcode中不会让您将斯威夫特成静态库)。

2) With your Swift classes, make sure the members and functions are public . 2) 使用 Swift 类,确保成员和函数是public I've not experimented with this, but it seems that the public attribute is necessary for the members and functions to be visible to users of the framework.我还没有尝试过这个,但似乎公共属性对于框架的用户可见的成员和函数是必要的。

3) Add what ever Swift classes (and Objective-C) you want to your framework. 3) 将您想要的任何 Swift 类(和 Objective-C)添加到您的框架中。

4) Close that framework project. 4) 关闭该框架项目。 (The same project can't be open twice in Xcode, and you need to incorporate the framework into your using project next). (同一个项目不能在 Xcode 中打开两次,接下来需要将框架合并到你的 using 项目中)。

5) Open your using project in Xcode. 5) 在 Xcode 中打开您的 using 项目。 For me this was an existing universal app project.对我来说,这是一个现有的通用应用程序项目。 You may be creating a new using project.您可能正在创建一个新的 using 项目。 In any event, drag the .xcodeproj file of your framework project, in the Finder, into your using project.无论如何,将您的框架项目的 .xcodeproj 文件在 Finder 中拖到您的使用项目中。

6) Inside of your using project, open your framework project. 6) 在您的 using 项目中,打开您的框架项目。 And drag the framework file into Embed Frameworks in Build Phases (the Embed Frameworks section wasn't present in Build Phases when I first started my experiments and I don't know yet what magic caused it to appear!).并拖动框架文件到Embed Frameworks的构建阶段(在Embed Frameworks部分是没有出现在构建阶段,当我第一次开始我的实验,我还不知道是什么魔力导致它出现!)。

在此处输入图片说明

These steps so far should enable you to build and link without actually yet integrating the usage of your library code.到目前为止,这些步骤应该使您能够构建和链接,而无需实际集成库代码的使用。 (I was using https://github.com/RadiusNetworks/swift-framework-example for some of my testing). (我使用https://github.com/RadiusNetworks/swift-framework-example进行一些测试)。

7) Now for the coup de grace: Under Build Settings , search for Framework Search Paths . 7) 现在是绝招:在Build Settings ,搜索Framework Search Paths And add in:并添加:

${TARGET_BUILD_DIR}/YourFrameworkName.framework

(It seems you do not have to have this marked as recursive). (似乎您不必将此标记为递归)。

8) In your Swift code files using the framework, you need to add an import at the top of each file: 8) 在你使用框架的 Swift 代码文件中,你需要在每个文件的顶部添加一个导入:

import YourFrameworkName

You should now be able build and link using your new library!您现在应该可以使用新库构建和链接了!

9) One more gotcha: Make sure your Deployment Target for your framework matches your destination project. 9) 还有一个问题:确保您的框架的Deployment Target与您的目标项目相匹配。 Eg, if your using project builds for iOS7, make sure your framework builds for iOS7 or earlier.例如,如果您的使用项目是为 iOS7 构建的,请确保您的框架是为 iOS7 或更早版本构建的。

10) Second gotcha (10/23/15): I just learned that it is necessary for my framework to have "App-Swift.h" (the name I use for this) as the Objective-C Generated Interface Header name in Build Settings. 10)第二个问题(10/23/15):我刚刚了解到我的框架必须有“App-Swift.h”(我为此使用的名称)作为构建中的Objective-C Generated Interface Header名称设置。 When I took this (Objective-C Generated Interface Header) out (trying to fix another issue), I get serveral interesting issues coming up in App-Swift.h.当我把这个(Objective-C Generated Interface Header)拿出来(试图解决另一个问题)时,我在 App-Swift.h 中遇到了几个有趣的问题。 These issues look something like: "Cannot find interface declaration for NSObject"?这些问题类似于: “找不到 NSObject 的接口声明”?

11) Third gotcha (10/29/15): When I tried to upload my first app to iTunes Connect that makes use of this Framework, I got an uploading error. 11) 第三个问题 (10/29/15):当我尝试将我的第一个应用程序上传到使用此框架的 iTunes Connect 时,出现上传错误。 The error read:错误如下:

ERROR ITMS-90206: "Invalid Bundle. The bundle at 'Your.app/Frameworks/YourFramework.framework' contains disallowed file 'Frameworks'."错误 ITMS-90206:“无效的捆绑包。‘Your.app/Frameworks/YourFramework.framework’中的捆绑包包含不允许的文件‘Frameworks’。”

Various SO and other posts have run into this kind of error, and the trick for me was, for the Framework target, in Build Settings, to set "Embedded Content Contains Swift Code" to NO.各种 SO 和其他帖子都遇到了这种错误,对我来说,诀窍是,对于 Framework 目标,在 Build Settings 中,将“Embedded Content Contains Swift Code”设置为 NO。 (My app Build Settings had this flag set to NO already). (我的应用程序构建设置已将此标志设置为 NO)。

An example project with most of these steps completed is on https://github.com/crspybits/CocoaTouchFramework.git完成大部分步骤的示例项目位于https://github.com/crspybits/CocoaTouchFramework.git

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

Xcode version 10.2.1 Xcode 版本 10.2.1

Create Swift framework创建 Swift 框架

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 files .swift添加文件.swift

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

Build library - ⌘ 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 [About] folder with: Modules [关于]文件夹包含:
    • module.modulemap
    • <product_name>.swiftmodule
      • .swiftdoc
      • .swiftmodule
  • Headers folder with: Headers文件夹:
    • files from Headers section.来自Headers部分的文件。 There are public interfaces/definitions有公共接口/定义
    • <product_name>-Swift.h - Xcode-generated header file [About] <product_name>-Swift.h - Xcode 生成的头文件[关于]

Swift consumer with Swift framework使用 Swift 框架的 Swift 消费者

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

Embed dynamic binary (or not embed || link a static binary) [Link vs Embed] [Library not loaded] Embed dynamic binary (或不嵌入 || 链接静态二进制文件) [链接与嵌入] [库未加载]

//Xcode 11
Project editor -> select a target -> General -> Frameworks, Libraries, and Embedded Content -> path to `<product_name>.framework` -> Embed

//pre Xcode 11
Project editor -> select a target -> General -> Embedded Binaries -> path to `<product_name>.framework`

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更多例子在这里

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

Xcode version 10.2.1 Xcode版本10.2.1

Create a Swift framework 创建一个Swift框架

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 files .swift 添加文件.swift

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

Build library - ⌘ Command + B or Product -> Build 构建库 - ⌘命令 + 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 [关于] [自定义modulemap]此文件是自动生成的,因为Build Settings -> Defines Module -> YES
    • <product_name>.swiftmodule folder with <product_name>.swiftmodule文件夹
      • .swiftdoc - docs .swiftdoc - docs
      • .swiftmodule - public interface/definitions .swiftmodule - 公共接口/定义
  • Headers folder with: Headers文件夹:
    • files from Headers section. 来自Headers部分的文件。 There are public interfaces/definitions 有公共接口/定义
    • <product_name>-Swift.h - Xcode-generated header file [About] <product_name>-Swift.h - Xcode生成的头文件[关于]

Using Swift framework 使用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 [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