最近,出现了将仅用Swift编写的代码集成到UE4上的项目中的问题。同时,未考虑选项“让我们快速重写Objective C中的所有内容”。我在任何地方都找不到现成的解决方案,而我经常(经常)要深入研究广度。该任务已成功解决,为了帮助其他人,我决定编写一个教程。
通常,如果您需要集成任何特定于iOS / macOS平台的代码,则将库程序集用作框架,该框架必须是静态的。代码本身是用目标C编写的。此外,依赖项是用项目构建脚本编写的MyProject.Build.cs
,例如,如下所示:
if (Target.Platform == UnrealTargetPlatform.IOS)
{
string ExtraPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty"));
PublicAdditionalFrameworks.Add(
new Framework(
"MyFramework",
ExtraPath + "/" + "MyFramework.framework.zip"
)
);
}
对于Swift,您可以尝试以相同的方式进行操作,但是会出现问题-依赖某些语言库。链接警告将如下所示:
ld: warning: Could not find auto-linked library 'swiftFoundation'
ld: warning: Could not find auto-linked library 'swiftDarwin'
ld: warning: Could not find auto-linked library 'swiftCoreFoundation'
ld: warning: Could not find auto-linked library 'swiftCore'
ld: warning: Could not find auto-linked library 'swiftCoreGraphics'
ld: warning: Could not find auto-linked library 'swiftObjectiveC'
ld: warning: Could not find auto-linked library 'swiftDispatch'
ld: warning: Could not find auto-linked library 'swiftSwiftOnoneSupport'
之后,将出现标准错误,即在目标文件中未找到某些符号。您可以尝试查找上述每个库的位置,并通过L键指定指向它的路径,但是我决定切换到Framework动态类型,该类型将自行加载这些库。
, iOS :
dyld: Library not loaded: @rpath/MyFramework.framework/MyFramework
Referenced from: /private/var/mobile/Containers/Bundle/Application/.../MyApp.app/MyApp
Reason: image not found
, UE4 Framework, . IOS Toolchain , IOSPlugin.
plist
, , :
<iosPListUpdates>
<addElements tag="dict" once="true">
<key>NSCameraUsageDescription</key>
<string>The camera is used for live preview.</string>
</addElements>
</iosPListUpdates>
copyDir
. , , :
<init>
<log text="Copy MyFramwork..."/>
<copyDir src="/.../MyFramework.framework" dst="$S(BuildDir)/Frameworks/MyFramework.framework" />
</init>
, init
. .
MyProject.Build.cs
:
using UnrealBuildTool;
using System.IO;
public class MyProject : ModuleRules
{
public MyProject(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
if (Target.Platform == UnrealTargetPlatform.IOS)
{
string ExtraPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty"));
PublicAdditionalFrameworks.Add(
new Framework(
"MyFramework",
ExtraPath + "/" + "MyFramework.framework.zip"
)
);
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("IOSPlugin", Path.Combine(PluginPath, "MyProject_IOS_UPL.xml"));
}
}
}
文件是MyProject_IOS_UPL.xml
这样的:
<?xml version="1.0" encoding="utf-8"?>
<root>
<init>
<log text="Copy MyFramework..."/>
<copyDir src="/.../MyFramework.framework" dst="$S(BuildDir)/Frameworks/MyFramework.framework" />
</init>
</root>
在UE4中提供正常的动态框架支持之前,此解决方案是一种解决方法,但我对此完全满意。