Is an iOS Framework .NET Binding Library in MAUI Possible?

ChangStar8 1 Reputation point
2022-06-10T21:49:34.377+00:00

I am attempting to update a project from Xamarin.Forms to Maui, that uses a binding project to wrap an iOS .framework library. I am not able to reference my Xamarin iOS Binding library in the Maui App; I need to create a new iOS Binding Library that targets .NET 6 iOS. I have been having trouble referencing the iOS Binding Library from the Maui App.

I have created a minimal Objective-C Framework, and validated it by integrating it into a Xamarin binding project and Xamarin.Forms project, and it works as expected - I am able to call into the Objective-C iOS Framework code from the application C# code.

But, when I try to consume a .NET 6 iOS Binding Library that uses the same Objective-C iOS Framework, I am lost. Visual Studio 17.3.0 preview allows me to create an iOS Binding Library, but it does not allow me to add a Native Framework Reference (the project context UI exists but is a no-op when I click it). So, I have manually modifed the iOSBinding .csproj file to reference the iOS Framework similarly to how the Xamarin binding library (from attached 210383-testmauiframeworkbindingscsproj.txt):

<ItemGroup>  
<NativeReference Include="Native References/TestFramework.framework">  
<Kind>Framework</Kind>  
</NativeReference>  
</ItemGroup>  

This seems to work, in that I can (supposedly) successfully build this iOSBinding project But, I get linker errors when I try to build the Maui App. The Maui App references the iOSBinding project via (from attached 210309-testmauiappcsproj.txt):

<ProjectReference Include="..\TestMauiFrameworkBindings\TestMauiFrameworkBindings.csproj" />  

When I build the Maui App I get the following build errors (from attached 210310-build.log):

--------------

1>C:\Program Files\dotnet\packs\Microsoft.iOS.Windows.Sdk\15.4.303\tools\msbuild\iOS\Xamarin.iOS.Common.After.targets(327,3): warning MT1302: Could not extract the native library 'TestFramework.framework' from '/Users/r_dsdcompb/Library/Caches/Xamarin/mtbs/builds/TestMauiApp/694bb3adfa58e8cc00b59acf89a20a0c002608c09695ad5f70b5d9442fc8a3d7/obj/Debug/net6.0-ios/ios-arm64/linker-cache/TestFramework.framework.zip'. Please ensure the native library was properly embedded in the managed assembly (if the assembly was built using a binding project, the native library must be included in the project, and its Build Action must be 'ObjcBindingNativeLibrary').

...

1>C:\Program Files\dotnet\packs\Microsoft.iOS.Windows.Sdk\15.4.303\tools\msbuild\iOS\Xamarin.iOS.Common.After.targets(327,3): error MT0140: File '/Users/r_dsdcompb/Library/Caches/Xamarin/mtbs/builds/TestMauiApp/694bb3adfa58e8cc00b59acf89a20a0c002608c09695ad5f70b5d9442fc8a3d7/obj/Debug/net6.0-ios/ios-arm64/linker-cache/TestFramework.framework/TestFramework' is not a valid framework.
1>

...

1>C:\Program Files\dotnet\packs\Microsoft.iOS.Windows.Sdk\15.4.303\tools\msbuild\iOS\Xamarin.iOS.Common.After.targets(368,3): error MSB3371: The file "obj\Debug\net6.0-ios\ios-arm64\linked\Link.semaphore" cannot be created. Could not find a part of the path 'C:\Users\R_DSLC\source\FrameworkTest_ForGithub\TestMauiApp\TestMauiApp\obj\Debug\net6.0-ios\ios-arm64\linked\Link.semaphore'.

--------------

I am not sure how to move forward. I'm not able to use the 'ObjcBindingNativeLibrary' Build Action for the framework as it doesn't even show up in VS. If I attempt to make the NativeReference xml element ObjcBindingNativeLibrary, I get a 'access to ... TestFrameworkFolder is denied'. I've attempting disabling linking and many other csproj shenanigans... If I end up circumventing the linker error, I get a runtime error that the .dll is not able to be loaded (it isn't packaged).

Has anyone successfully linked and used an iOS Binding Project that uses a native iOS framework? I'm assuming this is possible but I'm missing some detail in either my binding or app .csproj files.

Thanks for reading!

.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,148 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Nymu5 0 Reputation points
    2024-07-04T08:37:18.74+00:00

    These are the steps I performed and got it working without any issue:

    1. I created the following folder structure:
    App (.NET 8.0, MAUI)
    │   App.csproj
    │   ...
    App.Framework (newly created structure)
    └───FAT
    └───Frameworks
    App.Binding (iOS/MacCatalyst Binding Library)
    │   ApiDefinition.cs
    │   App.Binding.csproj
    │   StructsAndEnums.cs
    
    1. Copied the .framework into the App.Framework/Frameworks AND the App.Framework/FAT directory
    2. Created a FAT framework by using the following command: lipo -create -output FAT/[Name].framework/[Name] Frameworks/[Name].framework/[Name] HINT: As long as the architectures are different, you can add multiple architectures into a FAT framework
    3. Created ApiDefinition.cs and StructsAndEnums.cs by using the following command: sharpie bind --sdk=iphoneos16.2 --output="ApiDefinition" --namespace="App.Binding" --scope="FAT/[Name].framework/Headers/" "FAT/[Name].framework/Headers/[Name].h" NOTE: You might need to fix the path to absolute paths, if your framework contains multiple header files and if you are using Apple frameworks you might need to run this command with elevated permissions (sudo), check the sdk you want to use
    4. Check the generated files in App.Framework/ApiDefinitions/ and move the parts you need to the App.Binding/ApiDefinition.cs and App.Binding/StructsAndEnums.cs
    5. Remove [Verify] attribute after you checked those parts of the definitions
    6. Add the following snippet to your App.Bindings/App.Binding.csproj:
    <ItemGroup>
        <NativeReference Include="..\App.Framework\FAT\[Name].framework">
            <Kind>Framework</Kind>
            <Frameworks>Foundation UIKit [Name]</Frameworks>
            <LinkerFlags>-L "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/" -L "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos" -Wl,-rpath -Wl,@executable_path/Frameworks</LinkerFlags>
        </NativeReference>
    </ItemGroup>
    

    NOTE: You might need to modify the path to the target you are building for and modify the list of the frameworks in use 8. Link the project as ProjectReference in your App.csproj, e. g. without conditions like this:

    <ItemGroup>
        <ProjectReference Include="..\App.Binding\App.Binding.csproj"/>
    </ItemGroup>
    

    NOTE: Some IDEs require you to build the Binding by hand and unload the project in order to get the code completion / lookups working.

    ---

    I hope I did not forget anything and hopefully it will get you started. If you need any further information, just let me know!

    BR, Niko


  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more