플랫폼 간 앱에서의 네이티브 형식 작업Working with Native Types in Cross-Platform Apps

이 문서에서는 Android 또는 Windows Phone Os와 같은 비 iOS 장치를 사용 하 여 코드 공유 되는 위치 하는 플랫폼 간 응용 프로그램에서 새 iOS API 네이티브 통합 형식 (nint, nuint nfloat)를 사용 하 여 설명 합니다.This article covers using the new iOS Unified API Native types (nint, nuint, nfloat) in a cross-platform application where code is shared with non-iOS devices such as Android or Windows Phone OSes.

IOS 및 Mac Api를 사용 하는 64 형식을 네이티브 형식입니다.The 64-types native types work with the iOS and Mac APIs. 에서도 Android 또는 Windows에서 실행 되는 공유 코드를 작성 하는 경우 관리 통합 형식 공유할 수 있는 일반.NET 형식으로 변환 해야 합니다.If you are writing shared code that runs on Android or Windows as well, you'll need to manage the conversion of Unified types into regular .NET types that you can share.

이 문서에서는 일반적인 공유 코드에서 통합 API를 사용 하 여 상호 운용 하는 다양 한 방법 설명.This document discusses different ways to interoperate with the Unified API from your shared/common code.

네이티브 형식을 사용 하는 경우When to Use the Native Types

Xamarin.iOS 및 Xamarin.Mac 통합 Api는 계속 포함 합니다 int, uintfloat 데이터 형식 뿐만 RectangleF, SizeFPointF 형식.Xamarin.iOS and Xamarin.Mac Unified APIs still include the int, uint and float data types, as well as the RectangleF, SizeF and PointF types. 이러한 기존 데이터 형식 공유 되는 플랫폼 간 코드에서 사용할 계속 해야 합니다.These existing data types should continue to be used in any shared, cross-platform code. 새 네이티브 데이터 형식은 여기서 아키텍처 인식 형식이 필요한 지에 대 한 지원 iOS 또는 Mac API를 호출 하는 경우에 사용 해야 합니다.The new Native data types should only be used when making a call to a Mac or iOS API where support for architecture-aware types are required.

공유 되는 코드의 특성에 따라 경우도 플랫폼 간 코드를 처리 해야 할 위치를 nint, nuintnfloat 데이터 형식입니다.Depending on the nature of the code being shared, there might be times where cross-platform code might need to deal with the nint, nuint and nfloat data types. 예를 들어: 이전에 사용 하는 사각형 데이터에 변환을 처리 하는 라이브러리 System.Drawing.RectangleF Xamarin.iOS 및 Xamarin.Android 앱 버전 간의 기능을 공유 해야 iOS의 기본 유형을 처리 하도록 업데이트 되어야 합니다.For example: a library that handles transformations on rectangular data that was previously using System.Drawing.RectangleF to share functionality between Xamarin.iOS and Xamarin.Android versions of an app, would need to be updated to handle Native Types on iOS.

코드를 공유 하는 형식의 다음 섹션에서 보듯이 사용 된 및 이러한 변경 내용을 처리 하는 방법을 크기와 응용 프로그램의 복잡성에 따라 다릅니다.How these changes are handled depends on the size and complexity of the application and the form of code sharing that has been used, as we will see in the following sections.

코드 공유 고려 사항Code Sharing Considerations

에 명시 된 대로 합니다 코드 공유 옵션 문서, 플랫폼 간 프로젝트 간에 코드를 공유 하는 방법에 두 가지가 있습니다. 프로젝트 및 이식 가능한 클래스 라이브러리를 공유 합니다.As stated in the Sharing Code Options document, there are two main ways to sharing code between cross-platform projects: Shared Projects and Portable Class Libraries. 두 형식 중 사용 된, 옵션 플랫폼 간 코드에서 네이티브 데이터 형식을 처리 하는 경우에 제한 됩니다.Which of the two types has been used, will limit the options we have when handling the Native data types in cross-platform code.

이식 가능한 클래스 라이브러리 프로젝트Portable Class Library Projects

이식 가능한 클래스 라이브러리 (PCL)를 사용 하면를 지원 하 고 인터페이스를 사용 하 여 플랫폼 특정 기능을 제공 하려는 플랫폼을 대상으로 수 있습니다.A Portable Class Library (PCL) allows you to target the platforms you wish to support, and use interfaces to provide platform-specific functionality.

PCL 프로젝트 형식으로 컴파일된 이후를 .DLL Unified API의 당면한 있기를 기존 데이터 형식을 사용 하 여 유지 해야 할 수 있습니다 (intuint, float) PCL에서 소스 코드 형식으로 캐스팅 PCL의에 대 한 호출 클래스 및 프런트 엔드 응용 프로그램의 메서드입니다.Since the PCL Project type is compiled down to a .DLL and it has no sense of the Unified API, you'll be forced to keep using the existing data types (int, uint, float) in the PCL source code and type cast the calls to the PCL's classes and methods in the front-end applications. 예를 들어:For example:

using NativePCL;
...

CGRect rect = new CGRect (0, 0, 200, 200);
Console.WriteLine ("Rectangle Area: {0}", Transformations.CalculateArea ((RectangleF)rect));

공유 프로젝트Shared Projects

공유 자산 프로젝트 형식을 사용 하면 개별 플랫폼 특정 프런트 엔드 앱에 다음 포함 가져오고 컴파일되는 별도 프로젝트에서 소스 코드를 구성 하 고 사용할 #if 관리 하는 데 필요한 컴파일러 지시문 플랫폼 특정 요구 사항입니다.The Shared Asset Project type allows you to organize your source code in a separate project that then gets included and compiled into the individual platform-specific front end apps, and use #if compiler directives as required to manage platform-specific requirements.

크기 및 크기와 공유 되는 코드의 복잡성과 함께 공유 코드를 사용 하는, 크로스 플랫폼에서 네이티브 데이터 형식에 대 한 지원의 메서드를 선택할 때 고려해 야 하는 프런트 엔드 모바일 응용 프로그램의 복잡성 공유 자산 프로젝트입니다.The size and complexity of the front end mobile applications that are consuming shared code, along with the size and the complexity of the code being shared, needs to be taken into account when choosing the method of support for Native data types in a cross-platform Shared Asset Project.

이러한 요인에 따라 다음과 같은 유형의 솔루션을 구현할 수 있습니다를 사용 하 여는 if __UNIFIED__ ... #endif 컴파일러 지시문을 코드를 Unified API 특정 변경을 처리할 수 있도록 합니다.Based on these factors, the following types of solutions might be implemented using the if __UNIFIED__ ... #endif compiler directives to handle the Unified API specific changes to the code.

중복 된 메서드를 사용 하 여Using Duplicate Methods

위에 지정 된 사각형 데이터 변환을 수행 하는 라이브러리를 예로 들어를 보겠습니다.Take the example of a library that is doing transformations on rectangular data given above. 라이브러리에는 하나 또는 두 개의 간단한 방법만 포함 된, Xamarin.iOS 및 Xamarin.Android에 대 한 해당 메서드 중 중복 버전을 만들 수 있습니다.If the library only contains one or two very simple methods, you might choose to create duplicate versions of those methods for Xamarin.iOS and Xamarin.Android. 예를 들어:For example:

using System;
using System.Drawing;

#if __UNIFIED__
using CoreGraphics;
#endif

namespace NativeShared
{
    public class Transformations
    {
        #region Constructors
        public Transformations ()
        {
        }
        #endregion

        #region Public Methods
        #if __UNIFIED__
            public static nfloat CalculateArea(CGRect rect) {

                // Calculate area...
                return (rect.Width * rect.Height);

            }
        #else
            public static float CalculateArea(RectangleF rect) {

                // Calculate area...
                return (rect.Width * rect.Height);

            }
        #endif
        #endregion
    }
}

위의 코드에서 이후는 CalculateArea 루틴은 매우 간단 하며 조건부 컴파일을 사용 하 고 통합 API 버전의 메서드를 별도 생성 합니다.In the above code, since the CalculateArea routine is very simple, we have used conditional compilation and created a separate, Unified API version of the method. 반면, 라이브러리는 많은 루틴 또는 여러 복잡 한 루틴에 포함 하는 경우이 솔루션은 되지 실현 가능한 경우 모든 메서드의 수정 또는 버그 수정에 대 한 동기화를 유지 하는 문제를 나타낼.On the other hand, if the library contained many routines or several complex routines, this solution would not be feasible, as it would present an issue keeping all of the methods in sync for modifications or bug fixes.

메서드를 사용 하 여 오버 로드Using Method Overloads

이 경우, 솔루션을 이제 가지도록 32-bit 데이터 형식을 사용 하 여 메서드의 오버 로드 버전을 만들어 수 있습니다 CGRect 매개 변수 및/또는 반환 값을 해당 값을 변환할를 RectangleF (해당 변환에서 알 nfloatfloat 손실 변환이), 실제 작업을 수행 하는 루틴 원래 버전을 호출 합니다.In that case, the solution might be to create an overload version of the methods using 32-bit data types so that they now take CGRect as a parameter and/or a return value, convert that value to a RectangleF (knowing that converting from nfloat to float is a lossy conversion), and call the original version of the routine to do the actual work. 예를 들어:For example:

using System;
using System.Drawing;

#if __UNIFIED__
using CoreGraphics;
#endif

namespace NativeShared
{
    public class Transformations
    {
        #region Constructors
        public Transformations ()
        {
        }
        #endregion

        #region Public Methods
        #if __UNIFIED__
            public static nfloat CalculateArea(CGRect rect) {

                // Call original routine to calculate area
                return (nfloat)CalculateArea((RectangleF)rect);

            }
        #endif

        public static float CalculateArea(RectangleF rect) {

            // Calculate area...
            return (rect.Width * rect.Height);

        }

        #endregion
    }
}

마찬가지로이 적합 한 솔루션 한 정밀도 손실이 응용 프로그램의 특정 요구 사항에 대 한 결과 영향을 주지 않습니다.Again, this is a good solution as long as the loss of precision doesn't affect the results for your application's specific needs.

Using 별칭 지시문Using Alias Directives

정밀도의 손실 되는 문제 영역에 대 한 다른 가능한 솔루션 사용 방법은 using 공유 소스 코드 파일의 맨 위에 다음 코드를 포함 하 고 변환 네이티브 및 CoreGraphics 데이터 형식에 대 한 별칭을 만들려면 지시문 필요한 int, uint 또는 float 값을 nint하십시오 nuint 또는 nfloat:For areas where the loss of precision is an issue, another possible solution is to use using directives to create an alias for Native and CoreGraphics data types by including the following code to the top of the shared source code files and converting any needed int, uint or float values to nint, nuint or nfloat:

#if __UNIFIED__
    // Mappings Unified CoreGraphic classes to MonoTouch classes
    using RectangleF = global::CoreGraphics.CGRect;
    using SizeF = global::CoreGraphics.CGSize;
    using PointF = global::CoreGraphics.CGPoint;
#else
    // Mappings Unified types to MonoTouch types
    using nfloat = global::System.Single;
    using nint = global::System.Int32;
    using nuint = global::System.UInt32;
#endif

그러면 예제 코드 있도록:So that our example code then becomes:

using System;
using System.Drawing;

#if __UNIFIED__
    // Map Unified CoreGraphic classes to MonoTouch classes
    using RectangleF = global::CoreGraphics.CGRect;
    using SizeF = global::CoreGraphics.CGSize;
    using PointF = global::CoreGraphics.CGPoint;
#else
    // Map Unified types to MonoTouch types
    using nfloat = global::System.Single;
    using nint = global::System.Int32;
    using nuint = global::System.UInt32;
#endif

namespace NativeShared
{

    public class Transformations
    {
        #region Constructors
        public Transformations ()
        {
        }
        #endregion

        #region Public Methods
        public static nfloat CalculateArea(RectangleF rect) {

            // Calculate area...
            return (rect.Width * rect.Height);

        }
        #endregion
    }
}

변경한 다음 합니다 CalculateArea 반환할 메서드는 nfloat 표준 대신 float.Note that here we have changed the CalculateArea method to return an nfloat instead of the standard float. 가 이렇게 하는 동안 컴파일 오류가 발생 하지 얻게 암시적으로 변환 합니다 nfloat 계산의 결과 (형식의 값을 곱하는 모두 되므로 nfloat)에 float 값을 반환 합니다.This was done so that we would not get a compile error trying to implicitly convert the nfloat result of our calculation (since both values being multiplied are of type nfloat) into a float return value.

코드 컴파일 및 비 통합 API 장치에서 실행 하는 경우는 using nfloat = global::System.Single; 매핑합니다를 nfloatSingle 는 암시적으로 변환 됩니다는 float 프런트 엔드 응용 프로그램을 사용 하려면 허용를 CalculateArea 없이 메서드 수정 내용입니다.If the code is compiled and run on a non Unified API device, the using nfloat = global::System.Single; maps the nfloat to a Single which will implicitly convert to a float allowing the consuming front-end application to call the CalculateArea method without modification.

프런트 엔드 앱에서 형식 변환 사용Using Type Conversions in the Front End App

프런트 엔드 응용 프로그램에만 몇 가지 공유 코드 라이브러리에 대 한 호출을, 하는 경우에 다른 라이브러리 변경 되지 않은 상태로 유지 하는 것입니다 솔루션과 수행 형식 캐스팅 Xamarin.iOS 또는 Xamarin.Mac 응용 프로그램에서 기존 루틴을 호출 하는 경우.In the event that your front end applications only make a handful of calls to your shared code library, another solution could be to leave the library unchanged and do type casting in the Xamarin.iOS or Xamarin.Mac application when calling the existing routine. 예를 들어:For example:

using NativeShared;
...

CGRect rect = new CGRect (0, 0, 200, 200);
Console.WriteLine ("Rectangle Area: {0}", Transformations.CalculateArea ((RectangleF)rect));

응용 프로그램을 사용 하면 수백 개의 공유 코드 라이브러리를 호출 하는 경우이 다시 아닐 적합 한 솔루션입니다.If the consuming application makes hundreds of calls to the shared code library, this again, might not be a good solution.

응용 프로그램의 아키텍처에 따라 수를 얻게 네이티브 데이터를 지원 하기 위해 위의 솔루션 중 하나 이상을 사용 하 여 플랫폼 간 코드에서 (필수) 되는 형식입니다.Based on our application's architecture, we might end up using one or more of the above solutions to support Native Data Types (where required) in our cross-platform code.

Xamarin.Forms 응용 프로그램Xamarin.Forms Applications

다음 해야도 공유 하는 통합 API 응용 프로그램을 사용 하 여 플랫폼 간 Ui에 대 한 Xamarin.Forms를 사용 합니다.The following is required to use Xamarin.Forms for cross-platform UIs that will also be shared with a Unified API application:

  • 전체 솔루션을 버전 1.3.1 사용 해야 합니다 (또는 이상)의 Xamarin.Forms NuGet 패키지.The entire solution must be using version 1.3.1 (or greater) of the Xamarin.Forms NuGet Package.
  • 모든 Xamarin.iOS 사용자 지정 렌더링에 대 한 UI 코드 공유 (공유 프로젝트 또는 PCL) 되었으면 하는 방법에 따라 위의 솔루션의 동일한 형식을 사용 합니다.For any Xamarin.iOS custom renders, use the same types of solutions presented above based on how the UI code has been shared (Shared Project or PCL).

표준 플랫폼 간 응용 프로그램에서와 같이 대부분의 상황에 대 한 기존 32-bit 데이터 형식은 공유 되는 플랫폼 간 코드에서 사용 해야 합니다.As in a standard cross-platform application, the existing 32-bit data types should be used in any shared, cross-platform code for most situations. 새로운 네이티브 데이터 형식은 반드시 있는 아키텍처를 인식 한 형식에 대 한 지원 iOS 또는 Mac API 호출 하 하는 경우에 사용 해야 합니다.The new Native Data Types should only be used when making a call to a Mac or iOS API where support for architecture-aware types is required.

자세한 내용은 참조 하세요. 당사의 기존 Xamarin.Forms 앱 업데이트 설명서.For more details, see our Updating Existing Xamarin.Forms Apps documentation.

요약Summary

이 문서는 통합 API 응용 프로그램 및 해당 의미 플랫폼의 네이티브 데이터 형식을 사용 하는 경우 살펴보았습니다.In this article we have seen when to use the Native Data Types in a Unified API application and their implications cross-platform. 플랫폼 간 라이브러리에서 새 기본 데이터 형식을 사용 해야 합니다는 상황에서 사용할 수 있는 몇 가지 솔루션을 설명 합니다.We have presented several solutions that can be used in situations where the new Native Data Types must be used in cross-platform libraries. 또한 Xamarin.Forms 플랫폼 간 응용 프로그램에서 통합 Api를 지원 하기 위한 요약 가이드가 살펴보았습니다.Also, we've seen a quick guide to supporting Unified APIs in Xamarin.Forms cross-platform applications.