我正在尝试创建一个包含 Swift 和 C 代码的静态库,并且仅公开 Swift 接口。所以C代码端理想情况下不应该暴露给外界。我似乎无法找出在不引起警告或错误的情况下执行此操作的正确方法。
为了简化起见,我尝试使用以下文件设置一个最小的 Swift+C 静态库:
测试.swift
class Test {
func test() -> CInt {
return testFromC()
}
}
Run Code Online (Sandbox Code Playgroud)
测试.c
#include "Test.h"
int testFromC(void) {
return 0xdeadbeef;
}
Run Code Online (Sandbox Code Playgroud)
测试.h
int testFromC(void);
Run Code Online (Sandbox Code Playgroud)
我想要的是一个公开 Swift 类的静态库Test,但不公开 C 函数testFromC()。不过,如果别无选择,我可以忍受它被曝光。
我尝试过的是:
添加桥接标头。这几乎可以工作,但是a)很多人说这不被支持或推荐,b)它暴露testFromC()给模块的导入者,c)在某些情况下它会抛出关于隐式导入桥接头的警告(这是事实,但是我想要的是特别不这样做)。
添加模块映射。我不知道该怎么做。网上似乎没有任何示例适合我,如果有人知道如何正确执行此操作,我很乐意看到这三个文件的示例。
添加私有模块映射 - 我认为如果我想避免暴露 C 函数,这就是我想要的,但我在这方面的成功更少。
有谁能够整理出构建这个简单示例的确切步骤吗?
我想利用Swift应用程序在iOS上使用私有框架。我很清楚为什么这不是一个好主意,但是在测试中将很有用,因此App Store的限制不是问题,我已经详尽地研究了替代方案。
我想做的事情与此类似:
dlopen("/Developer/Library/PrivateFrameworks/UIAutomation.framework/UIAutomation".fileSystemRepresentation,RTLD_LOCAL);
let eventsclass = NSClassFromString("UIASyntheticEvents") as? UIASyntheticEvents.Type
eventGenerator = eventsclass!.sharedEventGenerator() as! UIASyntheticEvents
Run Code Online (Sandbox Code Playgroud)
问题是这将导致链接器错误:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_UIASyntheticEvents", referenced from:
type metadata accessor for __ObjC.UIASyntheticEvents in Test.o
Run Code Online (Sandbox Code Playgroud)
如果我直接链接框架而不是使用dlopen(),它将在模拟器上正常工作,但无法为实际设备构建,因为SDK中提供的框架仅用于模拟器,并且不会在设备期间链接建立。
我试图在Objective-C中进行这些调用,以防万一只是类型转换.Type导致问题,但这无济于事。如果我从Swift访问返回的对象,我仍然会遇到相同的错误。
我想我可以在Objective-C中创建一个包装器,将所有的调用直接传递给类,但这似乎是多余的。有没有更优雅的解决方案?
我有一个简单的结果类型:
enum Result<ValueType> {
case success(ValueType)
case failure(Error)
}
Run Code Online (Sandbox Code Playgroud)
我想在结果数组和可选结果数组上创建一个函数,以将所有结果合并为一个。但是,我正在竭尽全力想出一种表达方式。这就是我想做的:
extension Array<Optional<Result<ValueType>>> {
func combined() -> Result<[ValueType]>? {
var values: [ValueType] = []
for result in self {
switch result {
case .success(let value)?:
values.append(value)
case .failure(let error)?:
return .failure(error)
case .none:
return nil
}
}
return .success(values)
}
}
Run Code Online (Sandbox Code Playgroud)
这显然无法编译。但是有没有一种方法可以真正表达这一点?