2

When I access static property SharedController, the value is null, but the API Definition generated by Objective Sharpie only provides a getter.

BBDeviceController is instantiated, but the SharedController property on it is null. Because it only has a getter, I do not believe I am able to instantiate the property in code. From what I can tell, SharedController is not being initialized in BBDeviceController's constructor. I am unsure if BBDeviceController is a static class or just follows the singleton design pattern, but either way, newing up that class is not the solution.

BBDeviceController.h

@interface BBDeviceController : NSObject {
    NSObject <BBDeviceControllerDelegate>* delegate;

    BOOL debugLogEnabled;
    BOOL detectAudioDevicePlugged;
}

@property (nonatomic, weak) NSObject <BBDeviceControllerDelegate>* delegate;
@property (nonatomic, getter=isDebugLogEnabled, setter=setDebugLogEnabled:) BOOL debugLogEnabled;
@property (nonatomic, getter=isDetectAudioDevicePlugged, setter=setDetectAudioDevicePlugged:) BOOL detectAudioDevicePlugged;

+ (BBDeviceController *)sharedController;

Resulting API Definition (APIDefinition.cs)

[BaseType(typeof(NSObject))]
[Protocol]
interface BBDeviceController
{
    ...
    // +(BBDeviceController *)sharedController;
    [Static]
    [Export("sharedController")]
    BBDeviceController SharedController { get; }
    ...
}

Call from project's view controller

public BBDeviceController bbDeviceController;
public override void ViewDidLoad()
{
    base.ViewDidLoad();
    bbDeviceController = BBDeviceController.SharedController;
    ConnectDevice();
}

private void ConnectDevice()
{
    bbDeviceController.StartBTScan(new string[] { DEVICE_NAME }, 60);
}

From the documentation for the objective C library, you use sharedController like this:

[[BBDeviceController sharedController] setDelegate:self];

When trying to do the C# equivalent, I get an error because SharedController is null. Something else that may be of interest is that the SharedController definition in the resulting API Definitions file was flagged with [Verify(MethodToProperty)], and I manually had to add [Static] in order to access it from code.

rgahan
  • 667
  • 8
  • 17
  • `+ (BBDeviceController *)sharedController;` This is a class method, can not get a instance from it. – Junior Jiang Aug 20 '19 at 03:23
  • @JuniorJiang-MSFT How do I solve this? Do I change something in APIDefinition.cs, or is it an issue with the original library? – rgahan Aug 20 '19 at 13:01

2 Answers2

1

I'm not sure what your exact issue is (it could be it's not linking correctly, it could be the plist settings aren't right, etc) but I have successfully done this with the latest SDK (v3.7.2 as of writing). Here are the steps:

1. Use the following sharpie command to make the bindings:

sharpie bind --output=. --namespace=WisePad2Binding --sdk=iphoneos13.2 --scope=<path-to-sdk>/BBDevice-iOS-SDK-3.7.2/Library <path-to-sdk>/BBDevice-iOS-SDK-3.7.2/Library/BBDeviceController.h

2. Remove the [Verify] tags

I went ahead and changed back all the methods changed to properties that were marked by [Verify] just to leave less up to chance.

3. Add the libraries to your binding project

In the binding product, I didn't use the "Native References" folder (well, I tried initially and it did not work). Apparently the "old" way of making a binding project was to just drag the library onto the project root. When you do this, each library gets a .linkwith.cs attached to it (more on that in a sec). The libraries I added were:

  • libBBDevice-iOS-AudioAndBT-3.7.2.a
  • libBBDevice-iOS-AudioAndBT-3.7.2-simulator.a
  • libBBDeviceOTA-iOS-1.5.4.a
  • libBBDeviceOTA-iOS-1.5.4-simulator.a

Then in each .linkwith.cs file change the assembly attribute to be...

[assembly: LinkWith ("<library-name>.a", SmartLink = true, ForceLoad = true, Frameworks = "AudioToolbox AVFoundation CoreAudio CoreBluetooth CoreGraphics CoreFoundation CoreLocation ExternalAccessory Foundation MediaPlayer MessageUI QuartzCore SystemConfiguration UIKit", LinkerFlags = "-lc++ -lz -ObjC")]

4. Update your plist

Make sure you have all the stuff they list here added to your plist or stuff will not work right.

5. Tips

I couldn't get things to work correctly if I didn't do some (all?) things on the main thread, so I just perform all actions on the main thread. Also, don't set the delegate on the shared controller without calling BBDeviceController.SharedController.ReleaseBBDeviceController() (if you had a delegate previously set on there). My thoughts and prayers go out to anybody else trying to use this SDK with Xamarin.

Community
  • 1
  • 1
tarrball
  • 2,123
  • 3
  • 23
  • 34
0

When I do something like this, it's for a singleton class. https://www.galloway.me.uk/tutorials/singleton-classes/

so your sharedController method, should either allocate your BBDeviceController or get it somewhere. Also, if you can share the library link so we are on the same page.

  • Unfortunately, you have to be authenticated to view the documentation. It's for [BBPOS](https://developer.bbpos.com), but you have to have an account to view anything. – rgahan Aug 21 '19 at 13:32