في الآونة الأخيرة ، نشأت مشكلة دمج التعليمات البرمجية التي تمت كتابتها فقط في Swift في مشروع على UE4. في الوقت نفسه ، لم يتم النظر في خيار "دعنا نعيد كتابة كل شيء في الهدف ج بسرعة". لم أتمكن من العثور على حل جاهز في أي مكان ، كان لدي ، كما هو الحال غالبًا ، الحفر في كل من الاتساع والعمق. تم حل المهمة بنجاح ومن أجل مساعدة شخص آخر ، قررت كتابة برنامج تعليمي.
عادةً ، إذا كنت بحاجة إلى دمج أي رمز خاص بنظام iOS / macOS الأساسي ، يتم استخدام تجميع المكتبة كإطار عمل ، والذي يجب أن يكون ثابتًا. تمت كتابة الكود نفسه في الهدف ج. علاوة على ذلك ، تتم كتابة التبعية في نص بناء المشروع 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 ، لكنني كنت راضيًا تمامًا عنه.