Laerdal / Laerdal.Dfu

Xamarin binding library around @NordicSemiconductor's DFU library.
BSD 3-Clause "New" or "Revised" License
18 stars 18 forks source link

[iOS] Invalid mapping for DFUFirmware constructor #14

Open SuperCorks opened 2 years ago

SuperCorks commented 2 years ago

Describe the bug Hey guys :)

Looks like their might be a slight bug with the constructor new DFUFirmware(NSUrl urlToZipFile). When I try to use this function with any of the nugets >=0.2.17, I get this error:

Foundation.MonoTouchException > Objective-C exception thrown.  Name: NSInvalidArgumentException Reason: -[iOSDFULibrary.DFUFirmware initWithUrlToZipFile:]: unrecognized selector sent to instance 0x283e51220

To Reproduce Steps to reproduce the behavior:

  1. Use the new DFUFirmware(NSUrl urlToZipFile) anywhere in an iOS app with the latest nuget package v1.20.15. Even if the file path doesn't point to a valid DFU file, it doesn't matter. E.g. new DFUFirmware(NSUrl.FromString("file:///var/somefileondevice.zip"));
  2. You should get an Name: NSInvalidArgumentException Reason: -[iOSDFULibrary.DFUFirmware initWithUrlToZipFile:]: unrecognized selector sent to instance error.

Expected behavior The DFUFirmware class instance gets created or throws another error like Invalid DFU file content.

Additional context Note that this works perfectly with v0.2.16-beta0012. I think v0.2.17 included a change to a new version of the Nordic library as stated here.

It took me a while to track down this error to a possible bug in the Laerdal.Dfu library. I had to make sure it wasn't an error in my project configuration.

If you look at the definition of the DFUFirmware constructor in the Xamarin code: image

And the in the ObjectiveC Binding: image

And finally in the actual Nordic library: image

It looks to me like the move from NSUrl to the new Swift construct URL may have broken the binding.

It's just a theory of course. It would be great if you guys could investigate and let me know if you find the issue. I'd love to jump on the v1.20.x version which may be more stable and complete. At the same time, v0.2.16 works for our current needs so there is no rush.

Thanks again for this binding library.

Cheers

spamprom commented 1 year ago

I am getting the same error. I'm really looking forward to the update

spamprom commented 1 year ago

@SuperCorks Do you have any workaround for this error? How can I correctly write the path to the file so that the library can see it?

SuperCorks commented 1 year ago

The workaround is using version 0.2.16 of the nuget package @spamprom

Totonti commented 1 year ago

Hi! I have the same problem with version 1.20.17, I get the same error:

Name_.NSInvalidArgumentException Reason: -[ìOSDFULibrary.DFUFirmware initWithUrlToZipFile:] : unrecognized selector sent to instance 0x280cc99a0 My problem is that I have my Xamarin application for android and for iOS, and in android I need that version since it is ready for Android 12.

I have tried version 0.2.16 and it works on iOS but not on android 12, so it's a pain if I have to keep changing the versions to test or compile.

It's just a call for help, if you can fix the problem, I would appreciate it forever.

If you can't, I'll fix it by changing the versions for each OS.

Anyway, I want you to know that I am very grateful for this package that has saved my life.

Thank you very much

spamprom commented 1 year ago

@Totonti

option 1: I downloaded the source code of 'Laerdal.Dfu' on your mac Made a build without any changes and used the created library - it helped for me

don't use the nuget package, but use own result build

option 2: the current assembly consists of three files for different platforms: ....Nuget\packages\laerdal.dfu\1.20.15\lib

You can use different version libraries for different platforms

Totonti commented 1 year ago

Thank you @spamprom

As you mentioned I have tried having both versions, one on iOS and one on Android and it works.

mpiffari commented 1 year ago

@spamprom @Totonti @SuperCorks Same problem happen to me with this exception:

System.Exception: Could not initialize an instance of the type 'Foundation.NSUrl': the native 'initFileURLWithPath:isDirectory:' method returned nil. It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false. at Foundation.NSObject.InitializeHandle (System.IntPtr handle, System.String initSelector) [0x000d1] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.1.1.28/src/Xamarin.iOS/Foundation/NSObject2.cs:630 at Foundation.NSUrl..ctor (System.String path, System.Boolean isDir) [0x00027] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.1.1.28/src/Xamarin.iOS/Foundation/NSUrl.g.cs:118 at Laerdal.Dfu.DfuInstallation.SetInitiator () [0x00024] in /Users/runner/work/1/s/Laerdal.Dfu/iOS/DfuInstallation.cs:26 at Laerdal.Dfu.DfuInstallation.Start () [0x00013] in /Users/runner/work/1/s/Laerdal.Dfu/iOS/DfuInstallation.cs:101

Happy to follow the discussion and know if some upgrades/fixes available with versions higher than 1.25.2.

baddinosaur-kyle commented 1 year ago

@spamprom we are also seeing this issue but did you say above that it's been fixed when you build the code locally rather than using nuget? We're currently trying to upgrade this package to .NET 6/7 for a MAUI project so would be good to know if that solves it.

@SuperCorks did you ever manage to get it working on more recent versions?

SuperCorks commented 1 year ago

@baddinosaur-kyle I did not, but looking at the code it's a simple change if you feel like doing a pull request :)

baddinosaur-kyle commented 1 year ago

@SuperCorks sorry but fairly new to these binding libraries and not at all a Swift/iOS developer so I don't see the simple code change to fix this? Trying to use the previous version of the Nordic library (that they changed between those releases) seems to break when building against the more recent version of this library (falls over during the carthage build).

Is it just the URL type that needs to change in the APIDefinitions... if you can point out the fix in a little more detail we can definitely sort as part of our attempt to upgrade the entire library to .NET 7. Any help is hugely appreciated!

SuperCorks commented 1 year ago

It's a bit more complicated than just changing the ApiDefinition. The ApiDefinition file is auto-generated by objective-sharpie. You may need to write an Objective-C wrapper function that uses NSUrl as input and converts that into a swift URL before calling the constructor.

If you're not familiar with the process, then maybe don't update the whole Nordic library, just fix this one issue.

I'd love to help more, but I just don't have the time, and it's not a priority at work because version v0.2.16 works for our needs.

We've built a few bindings for other libraries before. I'm attaching two files in a zip that could help you. One is a lessons-learned/how-to document, the other is the sequence of commands we use to build the ApiDefinitions etc. swift-binding.zip

baddinosaur-kyle commented 1 year ago

Thanks so much for providing that -- however, we actually made a breakthrough just before you sent that over. We've now managed to build the existing library targeting net6.0-ios and net6.0-android successfully -- running on a MAUI net6 build. Though for now you do have to 'switch' between those targets depending on where you're building. The Android one doesn't seem to build on Visual Studio for Mac and the iOS one doesn't build when on a Windows PC (paired with Mac)... for now it's not that big a deal. It ended up being fairly straightforward to change over to it -- the key being that you have the Laerdal library build as part of the compilation process -- which grabs the frameworks and does the whole Carthage thing. Other than that, it was just a find/replace and a few other tweaks to get it to behave. I'll get a version sorted for a pull request in the next few weeks once we're happy it's fairly stable.

SuperCorks commented 1 year ago

Amazing thank you! Good job!