在 Swift 项目中导入框架,Xcode

54

我正在尝试将myFramework导入项目中。在“Build Phases(构建阶段)” -> “Link Binary With Libraries(链接二进制库)”中已添加myFramework

Objective-c可行:

#import <UIKit/UIKit.h>
#import <myFramework/myFramework.h>

但是在Swift中,我遇到了一个No such module myFramework错误:

import UIKit
import myFramework

根据 Swift 文档

Importing External Frameworks

You can import external frameworks that have a pure Objective-C codebase, a pure Swift codebase, or a mixed-language codebase. The process for importing an external framework is the same whether the framework is written in a single language or contains files from both languages. When you import an external framework, make sure the Defines Module build setting for the framework you’re importing is set to Yes.

You can import a framework into any Swift file within a different target using the following syntax:

SWIFT

import FrameworkName

You can import a framework into any Objective-C .m file within a different target using the following syntax:

OBJECTIVE-C

@import FrameworkName;

我使用 Xcode 5 创建了 myFramework,但是 Xcode 5 没有 "Defines Module" 的构建设置。

问题出在哪里?


在我的项目中,我正在按照您的描述与_Apple的SpriteKit.framework_进行链接,并且我能够通过在Swift类中导入框架来使用所有Sprite Kit的类:import SpriteKit - q231950
Xcode 5 不允许你 @import 非系统框架,这个功能从 Xcode 6 开始可用。 - Shmidt
你在代码中遵循的正确答案是什么? - Satyam
这个解决方案对我有用 https://dev59.com/IJbfa4cB1Zd3GeqPzt2P#37328591 - Sazzad Hissain Khan
9个回答

22

如果我理解正确的话,你没有为你的框架单独建立一个构建目标(因为已经使用Xcode 5构建了它),而是将该框架包含在你项目的构建目标中。

你所指的文档部分是关于不同目标内的框架。由于你的框架在项目的目标中,因此该文档部分不适用于此情况。

在你的情况下,你无法在Swift文件中导入框架。这就是为什么你会收到错误消息"No such module myFramework"

myFramework不是模块——它是你项目模块的一部分(默认情况下由你的产品名称确定)。因此,你的框架中的类应该是可访问的。

但是,你的框架是用Objective-C编写的。因此,你需要像这里描述的那样,在你的桥接头文件中导入Swift接口类。

请注意,这与模块的Swift导入无关。桥接头文件中的导入指令只是通知编译器将Objective-C头文件“转换”为Swift语法,并使公共头文件对Swift可见。

那么现在你应该怎么做呢?

  • 首先,在桥接头文件中导入你感兴趣的头文件。你只需要导入你将在Swift中使用的头文件。

  • 尝试在此阶段编译你的项目。如果Xcode找不到框架的头文件,你的问题可能与Swift或Xcode 6无关,而是与通常包含框架的问题有关。

  • 之后,尝试在你的AppDelegate.swift中实例化一个你在桥接头文件中导入的类。Xcode自动完成应该会提供类型名称。

希望这可以帮助你。


2
我按照Swift文档的说明进行操作。我想要导入JWFolders代码。在完成Swift文档中的步骤后,我编写了导入JWFolders的语句,但是出现了“没有这个模块'JWFolders'”的错误提示。这是我需要的缺失步骤:
  1. 点击左上角导航栏上的项目名称。
  2. 点击“Build Phases”。
  3. 点击“Embedded Frameworks”。
  4. 点击“+”。
  5. 找到头文件并添加。
但是-->只有在之前添加过框架的情况下,才能访问此“嵌入式框架”下拉菜单。这是一种hacky的方法。正确的方法是什么?
- Nate Uni

20

关于Swift:

创建框架:

  1. 启动Xcode -> 创建一个新的Xcode项目 -> iOS -> 框架和库 -> Cocoa Touch框架 -> 命名框架(例如sampleCocoaFramework)-> 创建。

  2. 设置目标 -> 通用 -> 部署信息 -> 部署目标。

  3. 添加一个公共类:文件 -> 新建文件 -> iOS -> Swift文件 -> 命名 (例如openCocoaClass) -> 创建。

  4. 现在在openCocoaClass.swift中添加一些代码。

import Foundation

public class openCocoaClass {

    public init() {

    }

    public var samplePublicVariable = "samplePublicVariable @ openCocoaClass"

    public func samplePublicFunction()
    {
        print("samplePublicFunction @ openCocoaClass")
    }          

}

  • 清理项目:Product -> Clean

  • 配置方案设置:Product -> Scheme -> Edit Scheme -> Run -> Build Configuration -> Release。

  • 构建框架:Product -> Build。

  • 导出框架:Products -> 选择框架 -> 身份和类型 -> 完整路径 -> 发布的框架。
  • 将框架添加到项目中:

    1. 开始一个Xcode项目并命名(例如 CocoaFrameworkTest)。

    2. 将sampleCocoaFramework.framework拖放到CocoaFrameworkTest的项目文件夹中。

    3. 目标->常规->嵌入二进制文件->添加其他->选择框架->如有需要复制项目->完成。

    在ViewController上访问框架:-

    import UIKit
    import sampleCocoaFramework
    
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let frameworkObject =  openCocoaClass.init()
            frameworkObject.samplePublicFunction()
            print(frameworkObject.samplePublicVariable)
    
    
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }
    

    1
    这是一个很好的前进方式。我在想,导入另一个Xcode项目中仍在开发中的框架的最佳方法是什么。我不想每次进行更改时都要遵循所有这些步骤。理想情况下,我只需要在同一个Xcode项目中拥有框架和应用程序,这样我甚至不需要在窗口之间切换。 - MrBr
    谢谢。除了第8步(“导出框架:产品->选择框架->身份和类型->完整路径->发布的框架”)之外,一切都很好。我无法执行此步骤,可能是因为我的Xcode版本不同。您能否更新第8步?提前感谢。 - LukeSideWalker
    @MrBr,你解决了吗? - Pramod Shukla

    13
    根据Swift文档,将Objective-C代码导入到同一目标的Swift中:
    1. 在您的Objective-C桥接头文件中,导入每个要向Swift公开的Objective-C头文件。例如:
    2. #import "XYZCustomCell.h"
      #import "XYZCustomView.h"
      #import "XYZCustomViewController.h"
    3. 在构建设置下,确保“Swift编译器 - 代码生成”下的Objective-C桥接头文件构建设置具有路径,该路径必须直接指向文件本身,而不是所在的目录。该路径应相对于项目,类似于在构建设置中指定Info.plist路径的方式。在大多数情况下,您不需要修改此设置。
    4. 在此桥接头文件中列出的任何公共Objective-C头文件都将对Swift可见。无需任何导入语句,Objective-C功能将自动在该目标中的任何Swift文件中提供。使用与系统类相同的Swift语法使用自定义的Objective-C代码。

    let myCell = XYZCustomCell()
    myCell.subtitle = "A custom cell"
    
    此外,请确保“打包”下的“定义模块”构建设置已设置为“是”。

    我在Xcode 5中创建了myFramework,它没有定义模块构建设置。 - phnmnn
    我认为仅仅使用 "#import "XYZCustomCell.h" 等语句是行不通的。你必须提供框架名称,例如 "#import <MyFramework/XYZCustomCell.h>"。请仔细核对你的答案。 - Satyam

    2

    在你的 Objective-C 项目中,你需要一个与你的应用程序同名的公共头文件,例如 FrameworkName.h,并将你希望暴露的所有类添加到其中(这些类应该作为项目属性的公共头文件添加)。 完成后,添加框架并将引用添加到你的公共头文件中,导入 FrameworkName。


    3
    你能否详细说明你的回答?这是一个Swift项目,不是Objective-C项目。 - Juan Boero

    1
    你可以使用以下语法将外部objC框架导入到Swift项目中:

    #import "objCExternalFramework-name/headerfilename.h"


    无法运行,这是哪个版本的Swift?出现“在导入声明中缺少标识符”的错误。 - Juan Boero
    这是错误的。在Swift4中,您不应该用引号封装任何类型的导入语句。 - Matthew Bahr

    0

    0

    好的,现在是Xcode 7.2版本。我观察到的是,Swift导入是大小写敏感的。例如-import uikit将不起作用。您必须将其键入为import UIKit

    仅供参考。


    0

    -1

    只需要按下Command+B就可以了!

    为什么要这样做呢: 通过Cocoapods添加框架将会创建另一个包含所需框架的Pod项目。为了让主项目识别这些框架,必须将两个项目的静态库进行桥接。为此需要构建工作区。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接