Integración de la biblioteca Swift en UE4

Recientemente, surgió el problema de integrar código escrito solo en Swift en un proyecto en UE4. Al mismo tiempo, no se consideró la opción "reescribamos rápidamente todo en Objective C". No pude encontrar una solución prefabricada en ninguna parte, tuve, como suele ser el caso, que cavar tanto en amplitud como en profundidad. El problema se resolvió con éxito y para ayudar a alguien más decidí escribir un tutorial.



Por lo general, si necesita integrar cualquier código específico para la plataforma iOS / macOS, el ensamblaje de la biblioteca se usa como un marco, que debe ser estático. El código en sí está escrito en el Objetivo C. Además, la dependencia está escrita en el script de construcción del proyecto MyProject.Build.cs, por ejemplo, así:



if (Target.Platform == UnrealTargetPlatform.IOS)
{
    string ExtraPath = Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty"));
    PublicAdditionalFrameworks.Add(
        new Framework(
            "MyFramework",
            ExtraPath + "/" + "MyFramework.framework.zip"
        )
    );
}


Para Swift, puede intentar seguir el mismo camino, pero habrá un problema: la dependencia de algunas bibliotecas de idiomas. La advertencia del enlace se verá así:



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'


Después de eso, los errores estándar seguirán que algunos símbolos no se encontraron en los archivos de objeto. Puede intentar encontrar dónde se encuentra cada biblioteca mencionada anteriormente y especificar la ruta a través de la tecla L, pero decidí cambiar al tipo dinámico de Framework, que cargará estas bibliotecas por sí mismo.



, 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"));
        }
    }
}


Y el archivo es MyProject_IOS_UPL.xmlasí:



<?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>


Esta solución es una especie de solución alternativa hasta que haya soporte dinámico normal de Framework en UE4, pero estaba completamente satisfecho con ella.




All Articles