Xamarin.iOS绑定库/本机框架

出于某种原因,我需要在我的Xamarin.iOS应用程序中使用此本机框架,问题来了,我不知道如何正确地进行绑定。


所以我理解正确,这个框架也使用另一个框架 ,我有点困惑,我究竟需要做什么?


问题:

  1. 我是否需要实现静态库(这可能与本机框架有关 ),因为它在Xamarin的官方文档中显示?
  2. 我是否可以为使用其他框架的本机框架进行绑定,或者我需要单独实现它们?
  3. 也许我应该将所有这些原生框架重新编写成C#版本?!? (但是这里出现了另一个问题,框架使用ObjC并且很难在C#中为我重现)
  4. 实现目标的最佳方法是什么?(可能没有描述,你可以告诉我更多)。

任何建议? 谢谢!

好的,最后我制作了一个静态库 ,但出了点问题,我现在无法在模拟器上使用它。 🙁

我将逐步解释如何创建一个静态库:

  • 我从这个存储库中获取了所有源文件。
  • Xcode IDE中,我制作了静态库项目 ,之后我将所有源文件从存储库复制到我的项目中。

  • 通过Carthage我已经下载了这个框架 (正如我已经解释过的,源文件使用这个框架),我还在Build Phases中添加了新类别 – > Copy Files (我选择了框架)到我的静态库中 。 并成功构建(在部署目标 10.2上)

    图

  • 接下来,我已经制作了MakeFile并成功生成了四个Fat Binary .a库,没有任何问题。

Xcrun命令显示:

xcrun -sdk iphoneos lipo -info libOSMapKitAdapter.a Architectures in the fat file: libOSMapKitAdapter.a are: i386 armv7 x86_64 arm64 
  • 然后我在Xamarin中创建了Binding Library项目,并添加了Fat Binary Static Library作为Native Reference (我将在下面显示我的.csproj文件)并且我也将相同的框架(我已经复制到项目路径中)放在里面静态库 (也许它是多余的?)


    此外,我已经制作了一个名为OSTransformation.framework.linkwith.cs的附加文件,代码如下:

LinkWith

  • 通过Objective Sharpie我已经生成了ApiDefinition.csStructs.cs 。 命令:

    sharpie bind --output=OSMapKitAdapter --namespace=OSMapKitAdapter --sdk=iphoneos10.2 /MyPath/OSMapKitAdapter/OSMapKitAdapter/*.h

结果是:

 Parsing 5 header files... Binding... [write] ApiDefinitions.cs [write] StructsAndEnums.cs Binding Analysis: Automated binding is complete, but there are a few APIs which have been flagged with [ Verify] attributes. While the entire binding should be audited for best API design practices, look more closely at APIs with the following Verify attribute hints: ConstantsInterfaceAssociation (1 instance): There's no foolproof way to determine with which Objective-C interface an extern variable declaration may be associated. Instances of these are bound as [Field] properties in a partial interface into a nearby concrete interface to produce a more intuitive API, possibly eliminating the 'Constants' interface altogether. PlatformInvoke (4 instances): In general P/Invoke bindings are not as correct or complete as Objective-C bindings ( at least currently). You may need to fix up the library name (it defaults to '__ Internal') and return/parameter types manually to conform to C calling conventionsfor the target platform. You may find you don't even want to expose the C API in your binding, but if you do, you'll probably also want to relocate the definition to a more appropriate class and expose a stronger type-safe wrapper. For P/Invoke guidance, see http://www.mono-project.com/docs/advanced/pinvoke/. Once you have verified a Verify attribute, you should remove it from the binding source code. The presence of Verify attributes intentionally cause build failures. For more information about the Verify attribute hints above, consult the Objective Sharpie documentation by running 'sharpie docs' or visiting the following URL: http://xmn.io/sharpie-docs Submitting usage data to Xamarin... Submitted - thank you for helping to improve Objective Sharpie! Done. 

生成的ApiDefinition.cs代码如下所示:

 [Static] [Verify (ConstantsInterfaceAssociation)] partial interface Constants { // extern double OSMapKitAdapterVersionNumber; [Field ("OSMapKitAdapterVersionNumber", "__Internal")] double OSMapKitAdapterVersionNumber { get; } // extern const unsigned char [] OSMapKitAdapterVersionString; [Field ("OSMapKitAdapterVersionString", "__Internal")] byte[] OSMapKitAdapterVersionString { get; } } // @interface OSTileOverlay : MKTileOverlay [BaseType (typeof(MKTileOverlay))] interface OSTileOverlay { // @property (assign, nonatomic) BOOL clipOverlay; [Export ("clipOverlay")] bool ClipOverlay { get; set; } // -(instancetype _Nonnull)initWithAPIKey:(NSString * _Nonnull)apiKey product:(OSMapProduct)product __attribute__((objc_designated_initializer)); [Export ("initWithAPIKey:product:")] [DesignatedInitializer] IntPtr Constructor (string apiKey, OSMapProduct product); } // @interface OSMapViewRegionRestriction : NSObject [BaseType (typeof(NSObject))] interface OSMapViewRegionRestriction { // @property (readonly, nonatomic) MKCoordinateRegion initialRegion; [Export ("initialRegion")] MKCoordinateRegion InitialRegion { get; } // -(void)updateMapViewRegionIfRequired:(MKMapView * _Nonnull)mapView; [Export ("updateMapViewRegionIfRequired:")] void UpdateMapViewRegionIfRequired (MKMapView mapView); } // @interface OSMapKitAdapter : NSObject [BaseType (typeof(NSObject))] interface OSMapKitAdapter { } 

Structs.cs

 [Native] public enum OSMapProduct : nint { Road, Outdoor, Light, Night } static class CFunctions { // extern NSString * NSStringFromOSMapProduct (OSMapProduct product); [DllImport ("__Internal")] [Verify (PlatformInvoke)] static extern NSString NSStringFromOSMapProduct (OSMapProduct product); // extern CLLocationCoordinate2D OSUpperLeftCorner (); [DllImport ("__Internal")] [Verify (PlatformInvoke)] static extern CLLocationCoordinate2D OSUpperLeftCorner (); // extern CLLocationCoordinate2D OSLowerRightCorner (); [DllImport ("__Internal")] [Verify (PlatformInvoke)] static extern CLLocationCoordinate2D OSLowerRightCorner (); // extern MKMapRect OSMapRectForUK (); [DllImport ("__Internal")] [Verify (PlatformInvoke)] static extern MKMapRect OSMapRectForUK (); } 

好了,现在我收到了编译错误,正如它在Xamarin绑定的官方教程中所示 ,我需要使用[Verify] Attribute检查Fields ,在解决问题之后需要删除这个Attribute ,同时添加Protocol属性等。

新版ApiDefinition.cs

  [Static] //[Verify(ConstantsInterfaceAssociation)] partial interface Constants { // extern double OSMapKitAdapterVersionNumber; [Field("OSMapKitAdapterVersionNumber", "__Internal")] double OSMapKitAdapterVersionNumber { get; } // extern const unsigned char [] OSMapKitAdapterVersionString; [Field("OSMapKitAdapterVersionString", "__Internal")] IntPtr OSMapKitAdapterVersionString { get; } } // @interface OSTileOverlay : MKTileOverlay [BaseType(typeof(MKTileOverlay))] [Protocol] interface OSTileOverlay { // @property (assign, nonatomic) BOOL clipOverlay; [Export("clipOverlay")] bool ClipOverlay { get; set; } // -(instancetype _Nonnull)initWithAPIKey:(NSString * _Nonnull)apiKey product:(OSMapProduct)product __attribute__((objc_designated_initializer)); [Export("initWithAPIKey:product:")] [DesignatedInitializer] IntPtr Constructor(string apiKey, OSMapProduct product); } // @interface OSMapViewRegionRestriction : NSObject [BaseType(typeof(NSObject))] [Protocol] interface OSMapViewRegionRestriction { // @property (readonly, nonatomic) MKCoordinateRegion initialRegion; [Export("initialRegion")] MKCoordinateRegion InitialRegion { get; } // -(void)updateMapViewRegionIfRequired:(MKMapView * _Nonnull)mapView; [Export("updateMapViewRegionIfRequired:")] void UpdateMapViewRegionIfRequired(MKMapView mapView); } // @interface OSMapKitAdapter : NSObject [BaseType(typeof(NSObject))] [Protocol] interface OSMapKitAdapter { } 

新版本的结构

 #if __UNIFIED__ [Native] public enum OSMapProduct : long { Road, Outdoor, Light, Night } #endif static class CFunctions { // extern NSString * NSStringFromOSMapProduct (OSMapProduct product); [DllImport ("__Internal")] //[Verify (PlatformInvoke)] static extern NSString NSStringFromOSMapProduct (OSMapProduct product); // extern CLLocationCoordinate2D OSUpperLeftCorner (); [DllImport ("__Internal")] //[Verify (PlatformInvoke)] static extern CLLocationCoordinate2D OSUpperLeftCorner (); // extern CLLocationCoordinate2D OSLowerRightCorner (); [DllImport ("__Internal")] //[Verify (PlatformInvoke)] static extern CLLocationCoordinate2D OSLowerRightCorner (); // extern MKMapRect OSMapRectForUK (); [DllImport ("__Internal")] //[Verify (PlatformInvoke)] static extern MKMapRect OSMapRectForUK (); } 

问题是我遇到了这个错误:

错误MT5214:本机链接失败,未定义符号:_OSMapKitAdapterVersionNumber。 此符号由托管成员OSTest.Constants.OSMapKitAdapterVersionNumber引用。 请validation是否已引用所有必需的框架并链接了本机库。 (MT5214)

错误MT5214:本机链接失败,未定义的符号:_OSMapKitAdapterVersionString。 此符号由托管成员OSTest.Constants.OSMapKitAdapterVersionString引用。 请validation是否已引用所有必需的框架并链接了本机库。 (MT5214)

错误MT5202:本机链接失败。 请查看构建日志。 (MT5202)

如何查看_ Xamarin.Bindings_项目的.csproj文件:

                  False Framework   Static False     

它适用于真实设备,但在模拟器上仍然会出现这种奇怪错误的错误。

UPD:

只需确保您在链接器上选择“仅链接框架SDK”并作为例外工作!

该库是用纯ObjC编写的。 Swift只写了一个例子。 鉴于库代码相对较小,我建议你重新写入C#