基于iOS Swift的动态框架中的Objective C类 [英] Objective C classes within an iOS Swift-based dynamic framework

查看:283
本文介绍了基于iOS Swift的动态框架中的Objective C类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用Swift编写的iOS dyanmic框架。我还有一堆用Objective C编写的类,我将在我的Swift类中使用(一些是公共的,一些是私有的)。 但是,我希望Objective C类不会暴露给使用我的框架的项目

I've got an iOS dyanmic framework written in Swift. I've also got a bunch of classes written in Objective C that I would to use within my Swift classes (some are public, some are private). However, I would like the Objective C classes to not be exposed to projects using my framework.

伞形标题

根据我的理解,我应该在我的伞头文件中使用 #import header.h 导入,通常是 FrameworkName.h ,然后确保我希望包含在我的Swift类中的所有Objective C头文件都标记为Public,在Build Phases - > Headers下。

From what I understand, I should import using #import header.h in my umbrella header file, which is usually FrameworkName.h, and then make sure all the Objective C header files that I wish to include in my Swift classes are to marked as "Public", under Build Phases -> Headers.

然而,这样做会自动使用我的框架将项目暴露给框架使用的所有私有Objective C类。

Doing this, however, automatically exposes the project using my framework to all the private Objective C classes that the framework uses.

模块映射(单独的模块)

因此,我研究了使用模块映射,记录了这里。我查看过其他用户的帖子,例如这个,以及这个Github回购

Because of this, I've looked into using module mapping, which is documented here. I've looked at posts by other users such as this and this, as well as this Github repo.

我成功完成了以下工作:

I successfully got the following working:

//SharedClasses/module.modulemap
module SharedClasses {
}

//SharedClasses/module.private.modulemap
module SharedClasses.Private {
    header "header.h"
    export *
}

问题是在我的项目中(导入了这个框架),这个:

The problem is that in my project (that has this framework imported), this:

import Framework
import Framework.SharedClasses

是允许,随后暴露隐藏的Objective C类。也许这就是模块的工作原理?有没有办法让他们真正私密?

is allowed, and subsequently the "hidden" Objective C classes are exposed. Perhaps this is just how modules work? Is there a way to make them truly private?

模块映射(使用框架私有模块)

另外,我尝试在框架的根目录下创建一个 module.private.modulemap 文件,其中包含以下内容:

Also, I've tried creating a module.private.modulemap file at the root of my framework with the following contents:

explicit module Framework.Private {
    header "header.h"
    export *
}

然后将其链接到MODULEMAP_PRIVATE_FILE下的目标构建设置。但是,当我在我的框架的Swift类中执行 import Framework.Private 时,会抛出编译器错误:

and then linking it my target's build settings under MODULEMAP_PRIVATE_FILE. However, when I do import Framework.Private in my framework's Swift classes a compiler error is thrown:

否这样的模块'Framework.Private'

"No such module 'Framework.Private'

我不明白为什么会出现这个错误。

I don't understand why this error is occurring.

模块映射(带私有标题)

我注意到在 Clang docs ,提到私有说明符:

I noticed that in the Clang docs, a private specifier is mentioned:


包含私有说明符的标题可能不包含在模块本身之外。

A header with the private specifier may not be included from outside the module itself.

我的理解是因为我的框架中的所有Swift类都已经是模块 Framework 的一部分,如果我创建一个带有以下内容的module.modulemap文件:

My understanding is that since all the Swift classes in my framework are already part of the module Framework, if I create a module.modulemap file with the following:

framework module Framework {
    umbrella header "Framework.h"

    private header "header.h"

    export *
    module * { export * }
}

然后一切都应该正常工作! Objective C头只能在模块中访问(即框架的Swift类),并且不会暴露给使用框架的任何项目。很酷,但它不起作用......编译器只是不识别Objective C类。没有抛出其他错误,但是你不能使用标题,所以就像你没有首先包含标题一样。
为什么?什么是当时的私人说明者?

then everything should be working! The Objective C headers are only accessible within the module (i.e. the framework's Swift classes), and aren't exposed to any project using the framework. Cool, but it doesn't work...the compiler just doesn't recognise the Objective C classes. No other errors are thrown, but you can't use the headers, so it's like you didn't include the headers in the first place. WHY? And what is the private specifier for then?

Soo,重申我原来的问题:

Soo, reiterating my original question:

有没有办法在iOS动态框架中导入用于Swift类的Objective C标头,同时保持它们是私有的,并且不能使用所述框架从任何项目访问?

感谢您的阅读,对不起这篇长篇文章感到抱歉。这是一个漫长的一天(和晚上)...

Thanks for reading, and sorry for the long post. It's been a long day (and night)...

推荐答案

你可以从此链接

只需创建文件夹(例如PrivateA)with module.modulemap其中包含您需要在Swift类中使用的所有对象头。
例如

Just create Folder (e.g.PrivateA) with module.modulemap where include all object headers you need to use in your Swift class. e.g.

module $(ModuleName)Private {
    header "header.h"
    export *
}

在Swift中,
你可以使用: import $(ModuleName)Private

因此,默认模块在使用 import $(ModuleName)时会排除这些标题)

so, default module exclude these headers when using import $(ModuleName).

从我的实验中,测试项目也可以 import $(ModuleName)Private ,但没有找到任何有用的代码。

From my experiment, test project can also import $(ModuleName)Private, but not found any useful code.

无论如何都要尝试这种方式。

Try this way anyway.

这篇关于基于iOS Swift的动态框架中的Objective C类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆