Xamarin.iOS绑定库/本机框架

Xamarin.iOS绑定库/本机框架,ios,xamarin.ios,static-libraries,ios-frameworks,xamarin.ios-binding,Ios,Xamarin.ios,Static Libraries,Ios Frameworks,Xamarin.ios Binding,出于某种原因,我需要在我的Xamarin.iOS应用程序中使用本机框架,但问题是,我不知道如何正确地进行绑定 正如我正确理解的,这个框架也使用了另一个框架,我有点困惑,我到底需要做什么 问题: 我是否需要实现如图所示的静态库(这是否可能与本机框架相关) 我能不能也使用另一个框架,或者我需要单独实现它们 也许我应该将所有这些本机框架重新写入C版本?!?(但这里出现了另一个问题,框架使用了ObjC,对我来说很难在C#中复制) 实现我的目标的最佳方法是什么?(可能没有描述,你可以告诉我更多) 有什

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


正如我正确理解的,这个框架也使用了另一个框架,我有点困惑,我到底需要做什么


问题:
  • 我是否需要实现如图所示的静态库(这是否可能与本机框架相关)
  • 我能不能也使用另一个框架,或者我需要单独实现它们
  • 也许我应该将所有这些本机框架重新写入C版本?!?(但这里出现了另一个问题,框架使用了ObjC,对我来说很难在C#中复制)
  • 实现我的目标的最佳方法是什么?(可能没有描述,你可以告诉我更多)

  • 有什么建议吗?谢谢

    此库是用纯ObjC编写的。斯威夫特只写了一个例子。
    鉴于库代码相对较小,我建议您重新写入C#

    好的,最后我制作了一个静态库,但出现了一些问题,目前我无法在Emulator上使用它(

    我将逐步解释我是如何制作静态库的:

    • 我从这里得到了所有的源文件
    • XcodeIDE中,我创建了静态库项目,之后我将所有源文件从存储库复制到我的项目中

    • 通过Carthage我下载了(正如我所解释的,源文件使用这个框架),并且我在构建阶段添加了新的类别->将文件(我选择了框架)复制到我的静态库中,并成功构建(关于部署目标10.2)

    • 接下来,我制作了MakeFile,并成功地生成了四个Fat二进制文件

    Xcrun命令显示:

     xcrun -sdk iphoneos lipo -info libOSMapKitAdapter.a
     Architectures in the fat file: libOSMapKitAdapter.a are: i386 armv7 x86_64 arm64
    
    • 然后,我在Xamarin中创建了绑定库项目,并将Fat二进制静态库添加为本机参考(我将在下面显示我的.csproj文件),并且我还将相同的文件放在框架中(我已将其复制到项目路径中),该框架链接到静态库(可能是多余的?)


      此外,我还制作了另一个名为OSTransformation.framework.linkwith.cs的文件,其中包含以下代码:

    • 通过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 ();
    }
    
       [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 ();
    }
    
    好的,现在我得到了编译错误,因此,我需要使用[Verify]属性检查字段,解决问题后,需要删除该属性,并添加协议属性等

    ApiDefinition.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 ();
    }
    
       [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 ();
    }
    
    结构的新版本

    [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 ();
    }
    
       [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引用了此符号。请验证是否已引用所有必要的框架并链接了本机库。(MT5214)

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

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

    .Xamarin.Bindings项目的.csproj文件外观如何:

     <ItemGroup>
        <Reference Include="System" />
        <Reference Include="Xamarin.iOS" />
      </ItemGroup>
      <ItemGroup>
        <Compile Include="Properties\AssemblyInfo.cs" />
        <Compile Include="OSTransformation.framework.linkwith.cs" />
      </ItemGroup>
      <ItemGroup>
        <ObjcBindingApiDefinition Include="ApiDefinition.cs" />
      </ItemGroup>
      <ItemGroup>
        <ObjcBindingCoreSource Include="Structs.cs" />
      </ItemGroup>
      <ItemGroup>
        <NativeReference Include="OSTransformation.framework">
          <IsCxx>False</IsCxx>
          <Kind>Framework</Kind>
     </NativeReference>
          <NativeReference Include="..\..\..\MyPath\OSMapKitAdapter\libOSMapKitAdapter.a">
            <Kind>Static</Kind>
            <SmartLink>False</SmartLink>
          </NativeReference>
      </ItemGroup>
      <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.ObjCBinding.CSharp.targets" />
    </Project>
    
    
    假的
    框架
    静止的
    假的
    
    它在真实设备上运行,但在模拟器上仍然会出现这种奇怪的错误

    UPD:
    只需确保您在linker上选择了“仅链接框架SDK”,并且可以正常工作!

    谢谢您的回复,但正如我上面所说的,很难从ObjC复制到C。是的,我错了,两者都是ObjC。无论如何,我已经创建了一个静态库,不幸的是它不起作用。我将更新我的主要问题。请继续关注!