Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Library not loaded error when adding binary Swift dependency #65

Open
katieatpoolcorp opened this issue Dec 11, 2024 · 15 comments
Open

Comments

@katieatpoolcorp
Copy link

Description

I am seeing an issue when attempting to add a .binarytarget swift package dependency to the MAUI slim binding template. In particular, I am attempting to use the Adyen POS Mobile SDK for iOS, with either the swift-only or Objective-C compatible packages.

Thank you sincerely for any suggestions or advice you can provide.

Steps to Reproduce

  • Close Rider/Xcode/Simulator
  • Clone the project https://github.com/CommunityToolkit/Maui.NativeLibraryInterop
  • Open /template/macios/native/NewBinding/NewBinding.xcodeproj in Xcode (16.1 / 16B40)
  • File > Add Package Dependencies
  • Add adyen-pos-mobile-ios, Branch main, add to project NewBinding > Add Package
  • Select "NewBinding" project for AdyenPOSTEST or ADYPOSTEST when prompted > Add Package
  • Build the project in Xcode successfully
  • Open the /template/newBinding.sln solution in Rider, wait for projects to sync / trust and open
  • Edit MauiSample.csproj > remove Mac Catalyst
  • Edit NewBinding.MaciOS.Binding.csproj > remove Mac Catalyst, TargetFrameworks > TargetFramework
  • Build > Rebuild Solution successfully
  • Have iPhone 16 selected, iOS "MauiSample" run configuration selected > Press "Play"
  • Wait on mlaunch / simulator startup
  • MauiSample quit unexpectedly, dyld[1445]: Library not loaded: @rpath/AdyenPOS.framework/AdyenPOS

Link to public reproduction project repository

No response

Environment

  • OS: Mac OS Sonoma 14.5 (build environment) / iOS 18.1 (target environment)
  • .NET MAUI: 8.0.83
  • .NET SDK 8.0.404, runtime 8.0.11
  • Target platforms: iOS
  • Xcode 16.1
  • JetBrains Rider 2024.3
@RobbyMon81
Copy link

One thing to check is the native library reference in the binding project:

<ItemGroup>
    <NativeReference Include="AdyenPOS.framework">
        <Kind>Framework</Kind>
        <SmartLink>False</SmartLink>
        <ForceLoad>True</ForceLoad>
    </NativeReference>
</ItemGroup>

Also, in the MauiSample iOS project:

<PropertyGroup>
    <EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>

You could also add this to the PropertyGroup section in your iOS app project file (MauiSample.csproj), not the binding project:

<MtouchExtraArgs>-gcc_flags "-ObjC -rpath @executable_path/Frameworks"</MtouchExtraArgs>

I hope some part of this helps!

@katieatpoolcorp
Copy link
Author

Thank you so much for your reply and suggestions.

I have tried...

  • NativeReference AdyenPOS.framework added to the binding project
  • With and without MtouchExtraArgs added to the MauiSample project PropertyGroup
  • All with EnableDynamicLoading true added to the MauiSample project

I get a new/different error:

Error  : Xcode project built successfully but did not produce expected output file: 'AdyenPOS.framework;/path/to/template/macios/native/NewBinding/bin/Release/net8.0-ios/NewBindingiOS.xcframework'

I've also tried "AdyenPOS" (which is what shows in the xcode left drawer), "ADYPOSTEST" (what shows in targets when Obj-C compatible library is used), and "ADYPOSTEST.framework".

@RobbyMon81
Copy link

Yw! Seem like the path may be off and may need to be more explicit about the location? The exact path should be in the File Inspector panel on the right when you click on AdyenPOS.framework.

<ItemGroup>
    <NativeReference Include="$(MSBuildThisFileDirectory)..\..\macios\native\NewBinding\AdyenPOS.framework">
        <Kind>Framework</Kind>
        <SmartLink>False</SmartLink>
        <ForceLoad>True</ForceLoad>
        <IsCxx>True</IsCxx>
    </NativeReference>
</ItemGroup>

May also need these in the binding project:

<PropertyGroup>
    <IsBindingProject>true</IsBindingProject>
    <NoBindingEmbedding>true</NoBindingEmbedding>
</PropertyGroup>

@katieatpoolcorp
Copy link
Author

I performed a case-insensitive find | grep operation looking for "Adyen" under my clone of the Maui.NativeLibraryInterop repository, and these are the only results:

❯ find . | grep -i "adyen"
./template/macios/native/NewBinding/bin/Release/net8.0-ios/NewBindingiOSSimulator.xcarchive/Signatures/AdyenPOSTest.xcframework-ios-simulator.signature
./template/macios/native/NewBinding/bin/Release/net8.0-ios/NewBindingiOS.xcarchive/Signatures/AdyenPOSTest.xcframework-ios.signature

I tried adding the IsCxx element, and the NoBindingEmbedding element as those were not present.
The IsBindingProject was already set to true.
I tried with ADYPOSTEST.framework, ADYPOSTEST, AdyenPOS, AdyenPOS.framework, and all result in the same error:

>Common.macios.targets(122,5): Error  : Xcode project built successfully but did not produce expected output file: '....'

I'd like to note that I am able to use this library and call methods on it if I try this with a simple Xcode/Swift sample, in case that could be relevant.

Again, thank you for your time. :)

@RobbyMon81
Copy link

Of course! Looks like your grep results show that Xcode is actually building an xcframework named "AdyenPOSTest.xcframework" rather than a .framework file. You may trying adjusting the binding to match what's actually being produced.

<ItemGroup>
    <NativeReference Include="AdyenPOSTest.xcframework">
        <Kind>Framework</Kind>
        <SmartLink>False</SmartLink>
        <ForceLoad>True</ForceLoad>
        <IsCxx>True</IsCxx>
    </NativeReference>
</ItemGroup>

There's a possibility you may also have to add this to the PropertyGroup in the binding project's .csproj:

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

@katieatpoolcorp
Copy link
Author

It looks like it still isn't working with the same error message :(

I overwrote the ItemGroup I had with the one you provided tried with either AdyenPOSTest.xcframework, and ADYPOSTest.xcframework. I also tried with the AllowUnsafeBlocks set to true.

Here are the complete contents of my NewBinding.MaciOS.Binding.csproj file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-ios</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
    <IsBindingProject>true</IsBindingProject>
    <NoBindingEmbedding>true</NoBindingEmbedding>

    <!--
      Enable trim analyzers for class libraries.
      To learn more, see: https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming
    -->
    <IsTrimmable>true</IsTrimmable>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

  <ItemGroup>
    <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
    <ObjcBindingCoreSource Include="StructsAndEnums.cs" />
  </ItemGroup>

<ItemGroup>
    <NativeReference Include="AdyenPOSTest.xcframework">
        <Kind>Framework</Kind>
        <SmartLink>False</SmartLink>
        <ForceLoad>True</ForceLoad>
        <IsCxx>True</IsCxx>
    </NativeReference>
</ItemGroup>

  <!-- Reference to Xcode project -->
  <ItemGroup>
    <NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
      <SchemeName>NewBinding</SchemeName>
      <SharpieNamespace>NewBindingMaciOS</SharpieNamespace>
      <SharpieBind>true</SharpieBind>
      <!-- Metadata applicable to @(NativeReference) will be used if set, otherwise the following defaults will be used:
      <Kind>Framework</Kind>
      <SmartLink>true</SmartLink>
      -->
    </NLIXcodeProjectReference>
  </ItemGroup>

  <!-- Reference to NuGet for building bindings -->
  <ItemGroup>
    <PackageReference Include="CommunityToolkit.Maui.NativeLibraryInterop.BuildTasks" Version="0.0.1-pre1" PrivateAssets="all" />
  </ItemGroup>
</Project>

and here is the MauiSample.csproj file:

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFrameworks>net8.0-android;net8.0-ios</TargetFrameworks>

		<!-- Note for MacCatalyst:
		The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
		When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
		The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
		either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
		<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->

		<OutputType>Exe</OutputType>
		<RootNamespace>MauiSample</RootNamespace>
		<UseMaui>true</UseMaui>
		<SingleProject>true</SingleProject>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>

		<!-- Display name -->
		<ApplicationTitle>MauiSample</ApplicationTitle>

		<!-- App Identifier -->
		<ApplicationId>com.companyname.mauisample</ApplicationId>

		<!-- Versions -->
		<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
		<ApplicationVersion>1</ApplicationVersion>

		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">12.2</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
		<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
    <MtouchExtraArgs>-gcc_flags "-ObjC -rpath @executable_path/Frameworks"</MtouchExtraArgs>
  </PropertyGroup>
  <PropertyGroup>
    <EnableDynamicLoading>true</EnableDynamicLoading>
  </PropertyGroup>
	<ItemGroup>
		<!-- App Icon -->
		<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />

		<!-- Splash Screen -->
		<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

		<!-- Images -->
		<MauiImage Include="Resources\Images\*" />
		<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />

		<!-- Custom Fonts -->
		<MauiFont Include="Resources\Fonts\*" />

		<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
		<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
	</ItemGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
		<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
		<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
	</ItemGroup>

	<!-- Reference to MaciOS Binding project -->
	<ItemGroup Condition="$(TargetFramework.Contains('ios')) Or $(TargetFramework.Contains('maccatalyst'))">
        <ProjectReference Include="..\macios\NewBinding.MaciOS.Binding\NewBinding.MaciOS.Binding.csproj" />
    </ItemGroup>

	<!-- Reference to Android Binding project -->
	<ItemGroup Condition="$(TargetFramework.Contains('android'))">
        <ProjectReference Include="..\android\NewBinding.Android.Binding\NewBinding.Android.Binding.csproj" />
    </ItemGroup>

	<!-- Reference the Android binding dependencies -->
	<!-- Uncomment the code block below and update the AndroidLibrary path to point your dependency .aar -->
	<!-- <ItemGroup Condition="$(TargetFramework.Contains('android'))">
        <AndroidLibrary Include="..\android\native\newbinding\bin\Release\net8.0-android\outputs\deps\{yourDependencyLibrary.aar}">
            <Bind>false</Bind>
            <Visible>false</Visible>
        </AndroidLibrary>
    </ItemGroup> -->
</Project>

@RobbyMon81
Copy link

Hmm...
You have both a NativeReference and an NLIXcodeProjectReference. When using the MAUI Native Library Interop template, the framework should be referenced through the Xcode project rather than directly.

What if you were to remove the NativeReference ItemGroup entirely (the one referencing AdyenPOSTest.xcframework)? Then, modify the NLIXcodeProjectReference to explicitly specify the framework.

<ItemGroup>
    <NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
      <SchemeName>NewBinding</SchemeName>
      <SharpieNamespace>NewBindingMaciOS</SharpieNamespace>
      <SharpieBind>true</SharpieBind>
      <Frameworks>AdyenPOSTest</Frameworks>
      <Kind>Framework</Kind>
      <SmartLink>false</SmartLink>
      <ForceLoad>true</ForceLoad>
    </NLIXcodeProjectReference>
</ItemGroup>

The AdyenPOSTest target should be set as a dependency of theNewBinding target and the framework should be listed under the NewBinding target's "Frameworks, Libraries, and Embedded Content" section.

@katieatpoolcorp
Copy link
Author

I removed the NativeReference ItemGroup.
I tried replacing the ItemGroup containing the NLIXcodeProjectReference with what you supplied above.
I tried this both with and without MtouchExtraArgs in MauiSample.

If I look in the NewBinding target in Xcode under General > Frameworks and Libraries > AdyenPOSTEST is what shows there, is that what you mean?
(it simply shows "AdyenPOS main (8b8c1d5)" in the left drawer of Xcode)

Here's the compiler output leading up to and including the error:

Skipping target "_CompileNativeExecutable" because all output files are up-to-date with respect to the input files.
Target _LinkNativeExecutable:
Tool xcrun execution started with arguments: clang++ -F /Users/38t2/projects/JustAdyenTemplate/template/macios/NewBinding.MaciOS.Binding/bin/Debug/net8.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64_x86_64-simulator -framework NewBinding -F /Users/38t2/projects/JustAdyenTemplate/template/sample -framework AdyenPOSTest -Lobj/Debug/net8.0-ios/iossimulator-arm64/nativelibraries -lSystem.Globalization.Native -lSystem.IO.Compression.Native -lSystem.Native -lSystem.Net.Security.Native -lSystem.Security.Cryptography.Native.Apple -lmono-component-debugger -lmono-component-diagnostics_tracing -lmono-component-hot_reload -lmono-component-marshal-ilgen -lmonosgen-2.0 -lxamarin-dotnet-debug -miphonesimulator-version-min=12.2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator18.1.sdk -arch arm64 /Users/38t2/projects/JustAdyenTemplate/template/sample/obj/Debug/net8.0-ios/iossimulator-arm64/nativelibraries/aot-output/arm64/aot-instances.dll.o /Users/38t2/projects/JustAdyenTemplate/template/sample/obj/Debug/net8.0-ios/iossimulator-arm64/nativelibraries/aot-output/arm64/System.Private.CoreLib.dll.o -L/usr/local/share/dotnet/packs/Microsoft.iOS.Runtime.iossimulator-arm64.net8.0_18.0/18.0.8316/runtimes/iossimulator-arm64/native -lxamarin-dotnet-debug -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lSystem.Globalization.Native -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lSystem.IO.Compression.Native -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lSystem.Native -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lSystem.Net.Security.Native -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lSystem.Security.Cryptography.Native.Apple -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lmono-component-debugger -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lmono-component-diagnostics_tracing -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lmono-component-hot_reload -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lmono-component-marshal-ilgen -L/usr/local/share/dotnet/packs/Microsoft.NETCore.App.Runtime.Mono.iossimulator-arm64/8.0.11/runtimes/iossimulator-arm64/native -lmonosgen-2.0 /usr/local/share/dotnet/packs/Microsoft.iOS.Runtime.iossimulator-arm64.net8.0_18.0/18.0.8316/runtimes/iossimulator-arm64/native/Microsoft.iOS.registrar.a -rpath @executable_path -framework Accelerate -framework Accounts -framework AddressBook -framework AddressBookUI -framework AdSupport -framework ARKit -framework AudioToolbox -framework AuthenticationServices -framework AVFoundation -framework AVKit -framework BusinessChat -framework CallKit -framework CarPlay -framework CFNetwork -framework ClassKit -framework CloudKit -framework Contacts -framework ContactsUI -framework CoreAudioKit -framework CoreBluetooth -framework CoreData -framework CoreFoundation -framework CoreGraphics -framework CoreImage -framework CoreLocation -framework CoreMedia -framework CoreMIDI -framework CoreML -framework CoreMotion -framework CoreSpotlight -framework CoreTelephony -framework CoreText -framework CoreVideo -framework DeviceCheck -framework EventKit -framework EventKitUI -framework ExternalAccessory -framework FileProvider -framework FileProviderUI -framework Foundation -framework GameController -framework GameKit -framework GameplayKit -framework GLKit -framework HealthKit -framework HealthKitUI -framework HomeKit -framework IdentityLookup -framework IdentityLookupUI -framework ImageIO -framework Intents -framework IntentsUI -framework JavaScriptCore -framework LocalAuthentication -framework MapKit -framework MediaAccessibility -framework MediaPlayer -framework MediaToolbox -framework Messages -framework MessageUI -framework Metal -framework MetalKit -framework MetalPerformanceShaders -framework MobileCoreServices -framework ModelIO -framework MultipeerConnectivity -framework NaturalLanguage -framework Network -framework NetworkExtension -framework NotificationCenter -framework OpenGLES -framework PassKit -framework PDFKit -framework Photos -framework PhotosUI -framework PushKit -framework QuartzCore -framework QuickLook -framework ReplayKit -framework SafariServices -framework SceneKit -framework Security -framework Social -framework Speech -framework SpriteKit -framework StoreKit -framework SystemConfiguration -framework Twitter -framework UIKit -framework UserNotifications -framework UserNotificationsUI -framework VideoSubscriberAccount -framework VideoToolbox -framework Vision -framework WatchConnectivity -framework WebKit -weak_framework Accessibility -weak_framework AccessorySetupKit -weak_framework AdServices -weak_framework AppClip -weak_framework AppTrackingTransparency -weak_framework AutomaticAssessmentConfiguration -weak_framework AVRouting -weak_framework BackgroundAssets -weak_framework BackgroundTasks -weak_framework CoreHaptics -weak_framework CoreLocationUI -weak_framework CryptoTokenKit -weak_framework DeviceDiscoveryExtension -weak_framework LinkPresentation -weak_framework MetalPerformanceShadersGraph -weak_framework MetricKit -weak_framework NearbyInteraction -weak_framework OSLog -weak_framework PencilKit -weak_framework PushToTalk -weak_framework QuickLookThumbnailing -weak_framework SafetyKit -weak_framework ScreenTime -weak_framework SensitiveContentAnalysis -weak_framework SensorKit -weak_framework SharedWithYou -weak_framework SharedWithYouCore -weak_framework SoundAnalysis -weak_framework Symbols -weak_framework UniformTypeIdentifiers -weak_framework VisionKit -framework GSS -framework CFNetwork -framework Security -rpath @executable_path/Frameworks /Users/38t2/projects/JustAdyenTemplate/template/sample/obj/Debug/net8.0-ios/iossimulator-arm64/nativelibraries/main.arm64.o -o /Users/38t2/projects/JustAdyenTemplate/template/sample/obj/Debug/net8.0-ios/iossimulator-arm64/nativelibraries/MauiSample -lcompression -lz -liconv -lcompression -lobjc -exported_symbols_list obj/Debug/net8.0-ios/iossimulator-arm64/mtouch-symbols.list -ObjC -rpath @executable_path/Frameworks
        
Tool xcrun execution finished (exit code = 1).
        
ld: warning: duplicate -rpath '@executable_path/Frameworks' ignored
ld: warning: ignoring duplicate libraries: '-lSystem.Globalization.Native', '-lSystem.IO.Compression.Native', '-lSystem.Native', '-lSystem.Net.Security.Native', '-lSystem.Security.Cryptography.Native.Apple', '-lcompression', '-lmono-component-debugger', '-lmono-component-diagnostics_tracing', '-lmono-component-hot_reload', '-lmono-component-marshal-ilgen', '-lmonosgen-2.0', '-lxamarin-dotnet-debug'
ld: framework 'AdyenPOSTest' not found
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

1>Xamarin.Shared.Sdk.targets(1648,3): Error  : clang++ exited with code 1:
ld: framework 'AdyenPOSTest' not found
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

And here are the current .csproj files, NewBinding.MaciOS.Binding.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-ios</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
    <IsBindingProject>true</IsBindingProject>
    <NoBindingEmbedding>true</NoBindingEmbedding>

    <!--
      Enable trim analyzers for class libraries.
      To learn more, see: https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming
    -->
    <IsTrimmable>true</IsTrimmable>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

  <ItemGroup>
    <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
    <ObjcBindingCoreSource Include="StructsAndEnums.cs" />
  </ItemGroup>


  <!-- Reference to Xcode project -->
  <ItemGroup>
    <NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
      <SchemeName>NewBinding</SchemeName>
      <SharpieNamespace>NewBindingMaciOS</SharpieNamespace>
      <SharpieBind>true</SharpieBind>
      <Frameworks>AdyenPOSTest</Frameworks>
      <Kind>Framework</Kind>
      <SmartLink>false</SmartLink>
      <ForceLoad>true</ForceLoad>
    </NLIXcodeProjectReference>
  </ItemGroup>
  <!-- Reference to NuGet for building bindings -->
  <ItemGroup>
    <PackageReference Include="CommunityToolkit.Maui.NativeLibraryInterop.BuildTasks" Version="0.0.1-pre1" PrivateAssets="all" />
  </ItemGroup>
</Project>

and MauiSample.csproj

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFrameworks>net8.0-android;net8.0-ios</TargetFrameworks>

		<!-- Note for MacCatalyst:
		The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
		When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
		The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
		either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
		<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->

		<OutputType>Exe</OutputType>
		<RootNamespace>MauiSample</RootNamespace>
		<UseMaui>true</UseMaui>
		<SingleProject>true</SingleProject>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>

		<!-- Display name -->
		<ApplicationTitle>MauiSample</ApplicationTitle>

		<!-- App Identifier -->
		<ApplicationId>com.companyname.mauisample</ApplicationId>

		<!-- Versions -->
		<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
		<ApplicationVersion>1</ApplicationVersion>

		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">12.2</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
		<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
		<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
    <MtouchExtraArgs>-gcc_flags "-ObjC -rpath @executable_path/Frameworks"</MtouchExtraArgs>
  </PropertyGroup>
  <PropertyGroup>
    <EnableDynamicLoading>true</EnableDynamicLoading>
  </PropertyGroup>
	<ItemGroup>
		<!-- App Icon -->
		<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />

		<!-- Splash Screen -->
		<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />

		<!-- Images -->
		<MauiImage Include="Resources\Images\*" />
		<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />

		<!-- Custom Fonts -->
		<MauiFont Include="Resources\Fonts\*" />

		<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
		<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
	</ItemGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
		<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
		<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
	</ItemGroup>

	<!-- Reference to MaciOS Binding project -->
	<ItemGroup Condition="$(TargetFramework.Contains('ios')) Or $(TargetFramework.Contains('maccatalyst'))">
        <ProjectReference Include="..\macios\NewBinding.MaciOS.Binding\NewBinding.MaciOS.Binding.csproj" />
    </ItemGroup>

	<!-- Reference to Android Binding project -->
	<ItemGroup Condition="$(TargetFramework.Contains('android'))">
        <ProjectReference Include="..\android\NewBinding.Android.Binding\NewBinding.Android.Binding.csproj" />
    </ItemGroup>

	<!-- Reference the Android binding dependencies -->
	<!-- Uncomment the code block below and update the AndroidLibrary path to point your dependency .aar -->
	<!-- <ItemGroup Condition="$(TargetFramework.Contains('android'))">
        <AndroidLibrary Include="..\android\native\newbinding\bin\Release\net8.0-android\outputs\deps\{yourDependencyLibrary.aar}">
            <Bind>false</Bind>
            <Visible>false</Visible>
        </AndroidLibrary>
    </ItemGroup> -->
</Project>

also in case this helps, the AdyenPOS Package Dependency has a Package.swift file in it.
This file defines a "package" variable that has name "AdyenPOS" and has an array of products, ie library with name "AdyenPOSTEST" with targets ["AdyenPOSTEST"]
The Package(...) also has targets array with 4 .binaryTarget(...)'s, for example "AdyenPOSTEST" with a url that goes to a zip file, and a checksum.

@RobbyMon81
Copy link

That linker error may help.

Can you make sure the framework is properly embedded? In Xcode, select the NewBinding target. Should be under General > Frameworks, Libraries, and Embedded Content. Make sure AdyenPOSTEST is set to "Embed & Sign".

Then modify here to be the same as from Package.swift:

<ItemGroup>
    <NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
      <SchemeName>NewBinding</SchemeName>
      <SharpieNamespace>NewBindingMaciOS</SharpieNamespace>
      <SharpieBind>true</SharpieBind>
      <Frameworks>AdyenPOSTEST</Frameworks>
      <Kind>XCFramework</Kind>
      <SmartLink>false</SmartLink>
      <ForceLoad>true</ForceLoad>
    </NLIXcodeProjectReference>
</ItemGroup>

You could also try adding this to MauiSample.csproj inside the first PropertyGroup:

<RuntimeIdentifier Condition="$(TargetFramework.Contains('ios'))">iossimulator-arm64</RuntimeIdentifier>

@katieatpoolcorp
Copy link
Author

Image This is what it looks like in Xcode, I can't seem to find "Embedded Content". I googled and found suggestions that maybe a build phase is missing, but it seems I have the build phase that would be needed. Here is what those look like: Image

Please, do you know if there is something else I've overlooked? :)

@katieatpoolcorp
Copy link
Author

Also if I replace the the ItemGroup with NLIXcodeProjectReference in NewBinding...csproj with the block you provided, I get this new error:

2>NewBindingiOS.xcframework: Error  : Unknown native reference type for 'XCFramework'.

If I add the RuntimeIdentifier to first property group in MauiSample.csproj I get the same error...

@RobbyMon81
Copy link

How about this?

In Xcode, add the framework embedding and then select the NewBinding target in the left panel.
Click the + under "Frameworks and Libraries" section (should be in the General tab, but if not visible, try clicking the + shown in the Build Phases tab for Link Binary With Libraries)
Find AdyenPOSTEST in the list and make sure its status is set to "Required"

Change the binding project (NewBinding.MaciOS.Binding.csproj) to this:

<ItemGroup>
    <NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
      <SchemeName>NewBinding</SchemeName>
      <SharpieNamespace>NewBindingMaciOS</SharpieNamespace>
      <SharpieBind>true</SharpieBind>
      <Frameworks>AdyenPOSTEST</Frameworks>
      <Kind>Framework</Kind>
      <SmartLink>false</SmartLink>
      <ForceLoad>true</ForceLoad>
      <NativeReferences>AdyenPOSTEST.framework</NativeReferences>
    </NLIXcodeProjectReference>
</ItemGroup>

Then add these to the binding project's PropertyGroup:

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProcessEnums>true</ProcessEnums>
<CompileBinding>true</CompileBinding>

The key seem like making sure the framework is properly linked in Xcode first, since that may be the root of the linking problems.

@katieatpoolcorp
Copy link
Author

Yes, under Link Binary With Libraries, AdyenPOSTEST is marked required.
I have replaced the ItemGroup with NLIXcodeProjectReference as described and added the AllowUnsafeBlocks, ProcessEnums and CompileBindings tags all within the binding csproj.

I am getting this error:

Tool xcrun execution finished (exit code = 1).
        
ld: warning: duplicate -rpath '@executable_path/Frameworks' ignored
ld: warning: ignoring duplicate libraries: '-lSystem.Globalization.Native', '-lSystem.IO.Compression.Native', '-lSystem.Native', '-lSystem.Net.Security.Native', '-lSystem.Security.Cryptography.Native.Apple', '-lcompression', '-lmono-component-debugger', '-lmono-component-diagnostics_tracing', '-lmono-component-hot_reload', '-lmono-component-marshal-ilgen', '-lmonosgen-2.0', '-lxamarin-dotnet-debug'
ld: framework 'AdyenPOSTEST' not found
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

1>Xamarin.Shared.Sdk.targets(1648,3): Error  : clang++ exited with code 1:
ld: framework 'AdyenPOSTEST' not found
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

@RobbyMon81
Copy link

The linker still can't find it. You could try finding it like this from a Terminal window in the project root:

find . -name "AdyenPOSTEST.framework"
find . -name "*.xcframework"

Update NLIXcodeProjectReference to include the full path:

<ItemGroup>
    <NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
      <SchemeName>NewBinding</SchemeName>
      <SharpieNamespace>NewBindingMaciOS</SharpieNamespace>
      <SharpieBind>true</SharpieBind>
      <Frameworks>AdyenPOSTEST</Frameworks>
      <Kind>Framework</Kind>
      <SmartLink>false</SmartLink>
      <ForceLoad>true</ForceLoad>
      <NativeReferences>$(MSBuildThisFileDirectory)../native/NewBinding/AdyenPOSTEST.framework</NativeReferences>
      <FrameworkPath>$(MSBuildThisFileDirectory)../native/NewBinding</FrameworkPath>
    </NLIXcodeProjectReference>
</ItemGroup>

And in MauiSample.csproj add:

<PropertyGroup Condition="$(TargetFramework.Contains('ios'))">
    <MtouchExtraArgs>-gcc_flags "-F$(MSBuildThisFileDirectory)../macios/native/NewBinding -ObjC -rpath @executable_path/Frameworks"</MtouchExtraArgs>
</PropertyGroup>

If you open the Package.swift file what does the binaryTarget declaration looks like for AdyenPOSTEST?

@katieatpoolcorp
Copy link
Author

katieatpoolcorp commented Dec 16, 2024

The first find turns up no results.
The second find turns up the following:

./template/sample/bin/Debug/net8.0-ios/iossimulator-arm64/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework
./template/macios/native/NewBinding/bin/Release/net8.0-ios/NewBindingiOS.xcframework
./template/macios/NewBinding.MaciOS.Binding/bin/Debug/net8.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework

In the package.swift it looks like the following, I have truncated the actual zip file locations and checksums.

import PackageDescription

let package = Package(
    name: "AdyenPOS",
    products: [
        .library(name: "AdyenPOSTEST", targets: ["AdyenPOSTEST"]),
        .library(name: "ADYPOSTEST", targets: ["ADYPOSTEST", "AdyenPOSTEST"]),
        .library(name: "AdyenPOSLIVE", targets: ["AdyenPOSLIVE"]),
        .library(name: "ADYPOSLIVE", targets: ["ADYPOSLIVE", "AdyenPOSLIVE"])
    ],
    dependencies: [],
    targets: [
        .binaryTarget(
            name: "AdyenPOSTEST",
            url: "/path/to/asset.zip",
            checksum: "checksum"
        ),
        .binaryTarget(
            name: "ADYPOSTEST",
            url: "/path/to/asset.zip",
            checksum: "checksum"
        ),
        .binaryTarget(
            name: "AdyenPOSLIVE",
            url: "/path/to/asset.zip",
            checksum: "checksum"
        ),
        .binaryTarget(
            name: "ADYPOSLIVE",
            url: "/path/to/asset.zip",
            checksum: "checksum"
        )
    ]
)

I assume I need proper locations on disk before I can make the csproj changes selected. Also my intent is to do my best to respond throughout the rest of the day but I will be out starting tomorrow until the 26th, so if you don't hear from me until then after today, I expect to follow up after that. :) Thanks again for all your continued help.

EDIT: PS the /path/to/asset.zip are all https / web links, they are not locations on disk, in case that helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants