xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.48k stars 514 forks source link

IOS Binding Library - the native class hasn't been loaded. #21302

Closed rolfbjarne closed 1 month ago

rolfbjarne commented 1 month ago

From @adarshchiniwar-smartq on Mon, 23 Sep 2024 19:29:05 GMT

Hi, We are trying to integratre Epson Ios SDK into our .NET MAUI App, I have sucessfully created IOS binding library and using it in .NET maui project, While creating the instance of a class i am getting below error {System.Exception: Could not create an native instance of the type 'EpsonIosFramework.Epos2Printer': the native class hasn't been loaded. It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false. at Foundation.NSObject.InitializeObject(Boolean alloced) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/Foundation/NSObject2.cs:line 382 at Foundation.NSObject..ctor(NSObjectFlag x) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/Foundation/NSObject2.cs:line 221 at EpsonIosFramework.Epos2CommonPrinter..ctor(NSObjectFlag t) at EpsonIosFramework.Epos2Printer..ctor(Int32 printerSeries, Int32 lang) at EpsonMaui.MainPage.ConnectToPrinter() in C:\Users\Adarsh.Chiniwar\source\repos\EpsonMaui\EpsonMaui\MainPage.xaml.cs:line 40} Please help me resolve this issue.

Github repos Maui Project - https://github.com/adarshchiniwar-smartq/EpsonMaui IOS Binding Library - https://github.com/adarshchiniwar-smartq/EpsonIosFramework

Please help us resolve this issue

Thanks, Adarsh

Copied from original issue dotnet/maui#24881

rolfbjarne commented 1 month ago

From @github-actions[bot] on Mon, 23 Sep 2024 19:29:35 GMT

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

rolfbjarne commented 1 month ago

From @drasticactions on Wed, 25 Sep 2024 13:07:53 GMT

Binding questions and issues should go to xamarin-macios, which maintains this tooling.

@rolfbjarne Would you have any advice for this user?

rolfbjarne commented 1 month ago

From @rolfbjarne on Wed, 25 Sep 2024 16:22:00 GMT

@adarshchiniwar-smartq please get an MSBuild binlog that shows the error.

adarshchiniwar-smartq commented 1 month ago

MSBuildReproLogs.zip Hi @rolfbjarne Please find the attached logs, In this i am trying to create instance of the class present in the iosbinding library dll. Ios binding library is created using a .a file.

Used repos : Maui Project - https://github.com/adarshchiniwar-smartq/Native_Maui.git Ios Binding Library - https://github.com/adarshchiniwar-smartq/IosNative.git

Please let me know if any information is required from my end.

Thanks for the help :)

rolfbjarne commented 1 month ago

The problem is that you're building for the iossimulator-arm64 architecture, and the native (.a) library doesn't contain code for that architecture.

The fix is to create an XCFramework bundle (which can contain code for all architectures), and reference that in your binding project instead of the static library (.a file).

Here's Apple's documentation about XCFrameworks: https://developer.apple.com/documentation/xcode/creating-a-multi-platform-binary-framework-bundle

As a temporary workaround, it's possible to force the iossimulator-x64 architecture if you're building from VS, as described here: https://github.com/xamarin/xamarin-macios/wiki/.NET-8-release-notes#default-runtimeidentifiers

Please try that and see if helps.

adarshchiniwar-smartq commented 1 month ago

MSBuildReproLogs.zip

Hi @rolfbjarne,

I have created the ios binding library using xcframework given by epson. SDK link -https://download3.ebz.epson.net/dsc/f/03/00/16/08/00/5093ed8b38118fc06ba68bae76770a6cb3cc56e3/ePOS_SDK_iOS_v2.29.1a.zip Ios Binding Library - https://github.com/adarshchiniwar-smartq/PrinterSDK_xcframework.git Maui App - https://github.com/adarshchiniwar-smartq/Native_Maui.git

i am still facing the same issue.

Exception - {System.Exception: Could not create an native instance of the type 'PrinterSDK.Epos2Printer': the native class hasn't been loaded. It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false. at Foundation.NSObject.InitializeObject(Boolean alloced) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/Foundation/NSObject2.cs:line 382 at Foundation.NSObject..ctor(NSObjectFlag x) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/Foundation/NSObject2.cs:line 221 at PrinterSDK.Epos2CommonPrinter..ctor(NSObjectFlag t) at PrinterSDK.Epos2Printer..ctor(Int32 printerSeries, Int32 lang) at Native.MainPage.PrintData() in C:\Users\Adarsh.Chiniwar\source\repos\Native\Native\MainPage.xaml.cs:line 45}

Please help me resolve this part as it is very new to us. Note - I am using windows machine paired with mac for building .net maui project and jus Mac for creating the ios binding library dlls. Iam deploying the app to the physical ipad.

Thanks, Adarsh

rolfbjarne commented 1 month ago

If you copy the binding dll around, you also need to copy the *.resources directory next to it, so that it stays next to the binding dll, because that's where the actual native bits are stored.

adarshchiniwar-smartq commented 1 month ago

Hi @rolfbjarne,

I have copied ios binding library .dll and *.resources into .net maui project and reference the dll. But still i am getting the same exception.

image Anything i am missing here? Thanks, Adarsh

rolfbjarne commented 1 month ago

Can you get an MSBuild binlog that shows the error?

adarshchiniwar-smartq commented 1 month ago

MSBuildReproLogs.zip Hi @rolfbjarne ,

Please find the attached logs.

Thanks, Adarsh

rolfbjarne commented 1 month ago

I see that you're using Hot Restart (i.e. not building on a remote Mac), and also that the framework in question contains static libraries.

Unfortunately Hot Restart isn't compatible with static libraries, so you won't be able to use this static library unless you build on a remote Mac.

Can you try that and see if it works then? If not, please provide an updated binlog.

adarshchiniwar-smartq commented 1 month ago

Hi @rolfbjarne,

I have setup the code in Mac OS, when I try to run the app, it is throwing the below error, Please help me with this/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk.net8.0_18.0/18.0.8303/targets/Xamarin.Shared.Sdk.targets(3,3): Error: clang++ exited with code 1: Undefined symbols for architecture x86_64: "_xmlCheckVersion", referenced from: _GetXmlDoc in libepos2.a[x86_64]187 "_xmlDocGetRootElement", referenced from: _XbrpGetDeviceId in libepos2.a[x86_64]187 _XbrpParseResponseData in libepos2.a[x86_64]187 _XbrpParseStatusResponseData in libepos2.a[x86_64]187 "_xmlFreeDoc", referenced from: _XbrpGetDeviceId in libepos2.a[x86_64]187 _XbrpGetDeviceId in libepos2.a[x86_64]187 _XbrpGetDeviceId in libepos2.a[x86_64]187 _XbrpParseResponseData in libepos2.a[x86_64]187 _XbrpParseStatusResponseData in libepos2.a[x86_64]187 "_xmlReadMemory", referenced from: _GetXmlDoc in libepos2.a[x86_64]187 ld: symbol(s) not found for architecture x86_64 clang++: error: linker command failed with exit code 1 (use -v to see invocation) (Native)

Thanks, Adarsh

adarshchiniwar-smartq commented 1 month ago
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-ios</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>
    <IsBindingProject>true</IsBindingProject>
  </PropertyGroup>

  <ItemGroup>
    <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
    <ObjcBindingCoreSource Include="StructsAndEnums.cs" />
  </ItemGroup>
  <ItemGroup>
    <Compile Update="libepos2.xcframework\ios-arm64_x86_64-simulator\libepos2.linkwith.cs">
      <DependentUpon>libepos2.a</DependentUpon>
    </Compile>
    <Compile Update="libepos2.xcframework\ios-arm64\libepos2.linkwith.cs">
      <DependentUpon>libepos2.a</DependentUpon>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <NativeReference Include="libepos2.xcframework">
      <Kind>Static</Kind>
      <SmartLink>False</SmartLink>
      <ForceLoad>True</ForceLoad>
    </NativeReference>
  </ItemGroup>
</Project>

this is the .csproj of iOS binding library

rolfbjarne commented 1 month ago

Can you get an MSBuild binlog that shows the error?

adarshchiniwar-smartq commented 1 month ago

17.0.zip

Hi,

Please find the attached diagnostic logs.

Thanks, Adarsh

rolfbjarne commented 1 month ago

There are no binlogs in that zip file; did you upload the wrong file (you need to do the same thing you did in your previous comment here: https://github.com/xamarin/xamarin-macios/issues/21302#issuecomment-2376825035)?

adarshchiniwar-smartq commented 1 month ago

Hi @rolfbjarne ,

I found out that native library was internally using libxml2.2.dylib and I have added the file in native reference, the static library requires ExternalAccessory.framework and CoreBluetooth.framework Please let me know how can I get these files, I checked in Xcode's framework folder these dosent have proper framework files instead they have .tbd file.

<?xml version="1.0" encoding="UTF-8"?>
<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0-ios</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>true</ImplicitUsings>
        <IsBindingProject>true</IsBindingProject>
        <MtouchExtraArgs>--gcc_flags "-L/Users/adarshchiniwar/Downloads/PrinterSDK_xcframework/PrinterSDK -lxml2.2"</MtouchExtraArgs>
    </PropertyGroup>
    <ItemGroup>
        <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
        <ObjcBindingCoreSource Include="StructsAndEnums.cs" />
    </ItemGroup>
    <ItemGroup>
        <Compile Update="libepos2.xcframework\ios-arm64_x86_64-simulator\libepos2.linkwith.cs">
            <DependentUpon>libepos2.a</DependentUpon>
        </Compile>
        <Compile Update="libepos2.xcframework\ios-arm64\libepos2.linkwith.cs">
            <DependentUpon>libepos2.a</DependentUpon>
        </Compile>
    </ItemGroup>
    <ItemGroup>
        <NativeReference Include="libepos2.xcframework">
            <Kind>Static</Kind>
            <SmartLink>False</SmartLink>
            <ForceLoad>True</ForceLoad>
            <LinkerFlags>-lxml2</LinkerFlags>
        </NativeReference>
        <NativeReference Include="libxml2.2.dylib">
            <Kind>Dynamic</Kind>
            <SmartLink>False</SmartLink>
            <ForceLoad>True</ForceLoad>
        </NativeReference>
    </ItemGroup>

</Project>

please let me know how can get both of these frameworks into my iosbinding library? also, is there any different process to generate MSbuild binlogs in Mac machine.

Thanks, Adarsh

rolfbjarne commented 1 month ago

To link with additional system frameworks, you add them in the Frameworks metadata in the NativeReference item:

<NativeReference Include="libepos2.xcframework">
    <Kind>Static</Kind>
    <SmartLink>False</SmartLink>
    <ForceLoad>True</ForceLoad>
    <LinkerFlags>-lxml2</LinkerFlags>
    <Frameworks>ExternalAccessory CoreBluetooth</Frameworks>
</NativeReference>

To get a binlog on macOS, you have to build from the command line:

dotnet build /bl:msbuild.binlog /path/to/myproject.csproj

adarshchiniwar-smartq commented 1 month ago

Bindlogs.zip

Hi @rolfbjarne ,

IOS Binding Library - Maui Project -

As suggested I have generated the bin logs but it failed and got some error in terminal. I have attached the Binlog file. I have added the frameworks as you suggested in iOS binding library and referred the dll and added the resource file in .net maui project.

    public partial class MainPage : ContentPage
    {
        int count = 0;

        public MainPage()
        {
            InitializeComponent();
        }

        private void OnCounterClicked(object sender, EventArgs e)
        {
            count++;

            if (count == 1)
                CounterBtn.Text = $"Clicked {count} time";
            else
                CounterBtn.Text = $"Clicked {count} times";

            SemanticScreenReader.Announce(CounterBtn.Text);
            try
            {
                // Ensure the code only runs on supported platforms
//#if __IOS__
//                Task.Run(() => PrintData()); 
//#endif
                PrintData();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        Epos2DeviceInfo deviceInfo;
        Epos2FilterOption filterOption;
        private void PrintData()
        {

            try
            {
                Epos2Printer Epos2Printer = new Epos2Printer(10, 0);
                deviceInfo = new Epos2DeviceInfo();
                filterOption = new Epos2FilterOption();
                filterOption.DeviceType = 1;
                int rea = Epos2Discovery.Start(filterOption, new Epos2DiscoveryDelegateImplementation());

            }
            catch (Exception ex)
            {
            }

        }
    }

    //Implement the Epos2DiscoveryDelegate interface
    public class Epos2DiscoveryDelegateImplementation : Epos2DiscoveryDelegate
    {
        public override void OnDiscovery(Epos2DeviceInfo deviceInfo)
        {
            // Handle discovery event
        }
    }

when I try to execute int rea = Epos2Discovery.Start(filterOption, new Epos2DiscoveryDelegateImplementation()); application just stops without throwing exception. Please help me with this

adarshchiniwar-smartq commented 1 month ago

To the Start Function mentioned above has highlighted redline with the error saying The type 'NSObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'Microsoft.iOS, Version=18.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065'.

In these repos the reference is already given Ios Binding Library - https://github.com/adarshchiniwar-smartq/PrinterSDK_xcframework.git Maui App - https://github.com/adarshchiniwar-smartq/Native_Maui.git

Is this beacause of the error the application is crashing.

Please help me with this, we have been stuck very badly.

Thanks, Adarsh

adarshchiniwar-smartq commented 1 month ago

These are the device logs crash reports - got it after executing int rea = Epos2Discovery.Start(filterOption, new Epos2DiscoveryDelegateImplementation());

Resolved pending breakpoint at 'MainPage.xaml.cs:74,1' to void Native.Epos2DiscoveryDelegateImplementation.OnDiscovery (PrinterSDK.Epos2DeviceInfo deviceInfo) [0x00000]. 2024-10-03 14:12:15.347 Native[5291:1751641] IAPAppRegisterClient: capabilities 0x8020 2024-10-03 14:12:15.347 Native[5291:1751641] IAPAppRegisterClient: eaClientRegisterediapd 0 -> 1 2024-10-03 14:12:15.347 Native[5291:1751641] IAPAppRegisterClient: eaClientRegisterediap2d 0 -> 1 2024-10-03 14:12:15.347 Native[5291:1751641] IAPDHasLaunched: kIAPAvailableNotification iapdAvailableState 100 -> 0 2024-10-03 14:12:15.347 Native[5291:1751641] IAPAppRegisterClient: eaiapdHasClientID 0, IAPDHasLaunched 0 2024-10-03 14:12:15.348 Native[5291:1751641] IAP2DHasLaunched: kIAP2AvailableNotification iap2dAvailableState 100 -> 0 2024-10-03 14:12:15.348 Native[5291:1751641] IAPAppRegisterClient: eaiap2dHasClientID 0, IAP2DHasLaunched 0 2024-10-03 14:12:15.348 Native[5291:1751641] IAPAppRegisterClient: registerWasSuccessful 0 2024-10-03 14:12:15.348 Native[5291:1751641] [#ExternalAccessory] -[EAAccessoryManager _initFromSingletonCreationMethod] initializing (0x3046a8060) with uuid 6240AD77-BDAF-4CE0-82F0-6268C7A3E7DB 2024-10-03 14:12:15.348 Native[5291:1751641] [#ExternalAccessory] -[EAAccessoryManager _initFromSingletonCreationMethod] isRunningOnMac 2024-10-03 14:12:15.351 Native[5291:1751641] [#ExternalAccessory] initialConnectedAccessories count 1 2024-10-03 14:12:15.351 Native[5291:1751641] [#VehicleInfoStatus] For TM-P80_002681 - 45276624 (transport 2), Found initialVehicleInfoDictionary { } 2024-10-03 14:12:15.351 Native[5291:1751641] [#ExternalAccessory] eaAccessory CoreAccessoryPrimaryUUID = 22EB84F3-AACA-49FC-AFF1-8B2D09908C36 2024-10-03 14:12:15.351 Native[5291:1751641] [#ExternalAccessory] _connectedAccessories (1) 2024-10-03 14:12:15.351 Native[5291:1751641] [#ExternalAccessory] Done attaching initialConnectedAccessories 2024-10-03 14:12:15.351 Native[5291:1751641] IAPAppConnectedAccessories: __eaClientHasCheckedForConnectedAccessories 0 -> 1 2024-10-03 14:12:15.352 Native[5291:1751641] IAPAppConnectedAccessories: IAPDHasLaunched 0, IAP2DHasLaunched 0

================================================================= Native Crash Reporting

Got a SIGABRT while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application.

================================================================= Native stacktrace:

0x1060b4a00 - /private/var/containers/Bundle/Application/FADCB367-46D6-46C3-8FC1-F0BB8471BFB5/Native.app/Native : AppleCryptoNative_X509ImportCollection
0x10609f8ec - /private/var/containers/Bundle/Application/FADCB367-46D6-46C3-8FC1-F0BB8471BFB5/Native.app/Native : AppleCryptoNative_X509ImportCollection
0x1061d8a80 - /private/var/containers/Bundle/Application/FADCB367-46D6-46C3-8FC1-F0BB8471BFB5/Native.app/Native : AppleCryptoNative_X509ImportCollection
0x1060b41f0 - /private/var/containers/Bundle/Application/FADCB367-46D6-46C3-8FC1-F0BB8471BFB5/Native.app/Native : AppleCryptoNative_X509ImportCollection
0x1ffe73e9c - /usr/lib/system/libsystem_platform.dylib : <redacted>
0x1ec17bc84 - /usr/lib/system/libsystem_kernel.dylib : <redacted>
0x1ec17bcb8 - /usr/lib/system/libsystem_kernel.dylib : 
0x1c473e324 - /System/Library/PrivateFrameworks/TCC.framework/TCC : <redacted>
0x1c4738ba0 - /System/Library/PrivateFrameworks/TCC.framework/TCC : <redacted>
0x1c473da4c - /System/Library/PrivateFrameworks/TCC.framework/TCC : <redacted>
0x1fff8cf30 - /usr/lib/system/libxpc.dylib : <redacted>
0x1fff7f6e0 - /usr/lib/system/libxpc.dylib : <redacted>
0x1ab3fee54 - /usr/lib/system/libdispatch.dylib : <redacted>
0x1ab41c740 - /usr/lib/system/libdispatch.dylib : <redacted>
0x1ab4119f0 - /usr/lib/system/libdispatch.dylib : <redacted>
0x1ab4112d8 - /usr/lib/system/libdispatch.dylib : <redacted>
0x1fff2d96c - /usr/lib/system/libsystem_pthread.dylib : _pthread_wqthread
0x1fff2a0cc - /usr/lib/system/libsystem_pthread.dylib : start_wqthread

================================================================= Basic Fault Address Reporting

Memory around native instruction pointer (0x1ec15c064):0x1ec15c054 ff 0f 5f d6 c0 03 5f d6 30 41 80 d2 01 10 00 d4 ......0A...... 0x1ec15c064 03 01 00 54 7f 23 03 d5 fd 7b bf a9 fd 03 00 91 ...T.#...{...... 0x1ec15c074 cc cc ff 97 bf 03 00 91 fd 7b c1 a8 ff 0f 5f d6 .........{..... 0x1ec15c084 c0 03 5f d6 90 32 80 d2 01 10 00 d4 03 01 00 54 ....2.........T

rolfbjarne commented 1 month ago

System/Library/PrivateFrameworks/TCC.framework/TCC

This line in the stacktrace means you're missing a privacy purpose message in your Info.plist.

Since you're using CoreBluetooth, I'm guessing you need to add the NSBluetoothAlwaysUsageDescription key: https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothalwaysusagedescription?language=objc

adarshchiniwar-smartq commented 1 month ago

Thanks a lot, i have added that using visual studio for mac but for some reason the string was not proper when checked in text editor. i have added using xcode and the solution's working like a charm.

Thanks a lot for the help! Please close the issue.

rolfbjarne commented 1 month ago

That's great, I'm happy to hear you were able to figure it out!