Search code examples
swiftxamarinxamarin.ios

Xamarin iOS Binding Library with Swift Protocols build fails when ApiDefinition.cs is generated with sharpie


When building an iOS Binding Library project with a Swift Protocol as a parameter for a function, or exposing one as a public field, The type or namespace name 'xxx' could not be found (are you missing a using directive or an assembly reference?) is thrown, even though xxx is defined in ApiDefinition.cs (syntax generated with sharpie)

example:

Swift:

@objc(ScanOperation)
public protocol ScanOperation { 

    @obj(onItemAdded:)
    func onItemAdded(itemObj: ItemData)

}

@objc(ScanAgent)
public class ScanAgent : NSObject {
    
    @objc(Initialize:)
    public func Initialize(scanOperation: ScanOperation) { }
}

Generated sharpie syntax in ApiDefinitions:

[Protocol]
interface ScanOperation
{
    // @required -(void)onItemAdded:(ItemData * _Nonnull)itemObj;
    [Abstract]
    [Export("onItemAdded:")]
    void OnItemAdded(ItemData itemObj);
}


// @interface ScanAgent : NSObject
[BaseType(typeof(NSObject))]
interface ScanAgent
{
    // -(void)Initialize:(id<ScanOperation> _Nonnull)scanOperation;
    [Export("Initialize:")]
    void Initialize(ScanOperation scanOperation);
}

This will not compile, and the above error will appear.


Solution

  • This happens because the generated code creates an interface with an I prefix.

    /obj/(Debug/Release)/iOS/<proj>/ScanOperation.g.cs contains the following:

    public partial interface IScanOperation : INativeObject, IDisposable

    So ScanOperation does not exist in the generated code.

    What needs to be done is to add an empty interface in ApiDefinition.cs and replace the signature of the function/field.

    In the above example:

    interface IScanOperation { }
    
    // @interface ScanAgent : NSObject
    [BaseType(typeof(NSObject))]
    interface ScanAgent
    {
        // -(void)Initialize:(id<ScanOperation> _Nonnull)scanOperation;
        [Export("Initialize:")]
        void Initialize(IScanOperation scanOperation);
    }
    

    More information can be found here under Binding protocols section.