Native Framework Binding

I am trying to use a native framework in Xamarin, but end up with this error when ISImageProcessor is initialized :

System.Exception: Could not create an native instance of the type 'ImageProcessBinding.ISImageProcessor': the native class hasn't been loaded.
It is possible to ignore this condition by setting ObjCRuntime.Class.ThrowOnInitFailure to false.

If I add the Native Framework to my single view project, I then end up with this error when building :

MT0099: Error: 'can't lipo directories'. Please file a bug report with a test case (http://bugzilla.xamarin.com). (Xamarin.CamScanner.Test) Internal

The working Objective C version :

UIImage *image = [UIImage imageNamed: imageName];

ISImageProcessor *imageProcessor = [[ISImageProcessor alloc] init];
[imageProcessor constructResourcesWithAppKey:@constructResourcesWithAppKey subAppkey:nil finishHandler:^(ISOpenSDKStatus status) {
if (status == ISOpenSDKStatusSuccess)
{
NSLog(@ConstructResourceWithAppKey Successful);
}
else
{
NSLog(@Construct Resources With App Key not successful);
}
}];

[imageProcessor detectBorderWithImage:image finishHandler:^(NSArray *borderPointsArray) {
if (borderPointsArray == nil)
{
NSLog(@Error processing image.);
}
else
{
NSLog(@Border Point Array processus successful);
[imageProcessor processImage:image withBorderPoints:borderPointsArray maxSize:1024 enhanceMode:ISImageEnhanceModeBlackAndWhite finishHandler:^(UIImage *resultImage) {
_imageView.image = resultImage;
NSLog(@ImageView Assigned);
}];
}
}];

[imageProcessor destructResources];

The Xamarin version :

        ImageProcessBinding.ISImageProcessor _imageProcessor = new ISImageProcessor();
        UIImage image = FactImage.Image;

        _imageProcessor.ConstructResourcesWithAppKey("", null, (arg0) =>
        {
            if (arg0 == ISOpenSDKStatus.Success)
            {
                _imageProcessor.DetectBorderWithImage(image, (arg1) =>
                {
                    if (arg1 != null)
                    {
                        _imageProcessor.ProcessImage(image, arg1, 1024, ISImageEnhanceMode.BlackAndWhite, (arg2) =>
                        {

                        });
                    }
                });
            }
        });

ApiDefinition.cs :

using System;
using UIKit;
using Foundation;
using ObjCRuntime;
using CoreGraphics;

namespace ImageProcessBinding
{

  [Static]
    partial interface Constants
    {
        // extern NSString *const kOpenSDKCardResultTypeOriginImage;
        [Field("kOpenSDKCardResultTypeOriginImage", "__Internal")]
        NSString kOpenSDKCardResultTypeOriginImage { get; }

        // extern NSString *const kOpenSDKCardResultTypeImage;
        [Field("kOpenSDKCardResultTypeImage", "__Internal")]
        NSString kOpenSDKCardResultTypeImage { get; }

        // extern NSString *const kOpenSDKCardResultTypeHeadImage;
        [Field("kOpenSDKCardResultTypeHeadImage", "__Internal")]
        NSString kOpenSDKCardResultTypeHeadImage { get; }

        // extern NSString *const kOpenSDKCardResultTypeCardName;
        [Field("kOpenSDKCardResultTypeCardName", "__Internal")]
        NSString kOpenSDKCardResultTypeCardName { get; }

        // extern NSString *const kOpenSDKCardResultTypeCardItemInfo;
        [Field("kOpenSDKCardResultTypeCardItemInfo", "__Internal")]
        NSString kOpenSDKCardResultTypeCardItemInfo { get; }

        // extern NSString *const kOpenSDKCardResultTypeCardRotate;
        [Field("kOpenSDKCardResultTypeCardRotate", "__Internal")]
        NSString kOpenSDKCardResultTypeCardRotate { get; }
    }

    // typedef void (^DetectCardFinishHandler)(int, NSArray *);
    delegate void DetectCardFinishHandler(int arg0, NSObject[] arg1);

    // typedef void (^RecognizeCardFinishHandler)(NSDictionary *);
    delegate void RecognizeCardFinishHandler(NSDictionary arg0);

    // typedef void (^ConstructResourcesFinishHandler)(ISOpenSDKStatus);
    delegate void ConstructResourcesFinishHandler(ISOpenSDKStatus arg0);

    // typedef void (^DetectImageFinishHandler)(NSArray *);
    delegate void DetectImageFinishHandler(NSObject[] arg0);

    // typedef void (^RecognizeImageFinishHandler)(UIImage *);
    delegate void RecognizeImageFinishHandler(UIImage arg0);

    // @interface ISImageProcessor : NSObject
    [BaseType(typeof(NSObject))]
    interface ISImageProcessor
    {
        // +(ISImageProcessor *)defaultProcessor;
        [Static]
        [Export("defaultProcessor")]
        ISImageProcessor DefaultProcessor { get; }

        // -(void)constructResourcesWithAppKey:(NSString *)appKey subAppkey:(NSString *)subAppKey finishHandler:(ConstructResourcesFinishHandler)finishHandler;
        [Export("constructResourcesWithAppKey:subAppkey:finishHandler:")]
        void ConstructResourcesWithAppKey(string appKey, string subAppKey, ConstructResourcesFinishHandler finishHandler);

        // -(ISOpenSDKStatus)detectBorderWithImage:(UIImage *)image finishHandler:(DetectImageFinishHandler)finishHandler;
        [Export("detectBorderWithImage:finishHandler:")]
        ISOpenSDKStatus DetectBorderWithImage(UIImage image, DetectImageFinishHandler finishHandler);

        // -(ISOpenSDKStatus)processImage:(UIImage *)image withBorderPoints:(NSArray *)borderPoints maxSize:(CGFloat)size enhanceMode:(ISImageEnhanceMode)enhanceMode finishHandler:(RecognizeImageFinishHandler)finishHandler;
        [Export("processImage:withBorderPoints:maxSize:enhanceMode:finishHandler:")]
        ISOpenSDKStatus ProcessImage(UIImage image, NSObject[] borderPoints, nfloat size, ISImageEnhanceMode enhanceMode, RecognizeImageFinishHandler finishHandler);

        // -(void)destructResources;
        [Export("destructResources")]
        void DestructResources();
    }
}

Structs.cs :

using System;
using ObjCRuntime;

namespace ImageProcessBinding
{
    [Native]
    public enum ISOpenSDKStatus : long
    {
        Unauthorized = -1,
        Success,
        Unreachable,
        DeviceIDError,
        AppIDError,
        AppKeyError,
        AuthExpiredError,
        DeviceCappedError,
        DetectCappedError,
        SubAppKeyError,
        UnsupportedAuthError,
        AuthorizeInfoError,
        ConstructResourceError,
        VersionError
    }

    [Native]
    public enum ISOpenPreviewSDKType : long
    {
        BankCardReader = 1 << 0,
        IDReader = 1 << 1,
        DrivingLicense = 1 << 2,
        VehicleLicense = 1 << 3
    }

    [Native]
    public enum ISImageEnhanceMode : long
    {
        Auto = -1,
        Original = 0,
        Normal = 1,
        MagicColor = 2,
        BlackAndWhite = 3,
        Gray = 4,
        None = 5
    }
}

Answers

  • AshleyGazichAshleyGazich USXamarin Team Xamurai

    Were you able to get this resolved? If not, may I ask how the native framework is being added (for example, as a single library file or a folder)?

  • SamuelFournierSamuelFournier USMember

    Thank you for answering, no I haven't found a solution yet. The native references are pointing to the .frameworks files for both the binding library and the single-view project using the binding library.

  • jordohjordoh USMember ✭✭

    I ran in to the same error, and was able to work around it by not including the framework native reference in the binding project, instead including it in the project consuming the binding project.

  • tuyenvtuyenv VNUniversity ✭✭✭

    Is it resolved?

Sign In or Register to comment.