연습: iOS Objective-C 라이브러리 바인딩

Important

현재 Xamarin 플랫폼에서 사용자 지정 바인딩 사용을 조사하고 있습니다. 설문 조사에 참여하여 향후 개발 작업에 대해 알려 주시기 바랍니다.

이 문서에서는 기존 Objective-C 라이브러리 InfColorPicker에 대한 Xamarin.iOS 바인딩을 만드는 실습 연습을 제공합니다. 정적 Objective-C 라이브러리 컴파일, 바인딩 및 Xamarin.iOS 애플리케이션의 바인딩 사용과 같은 항목에 대해 설명합니다.

iOS에서 작업할 때 타사 Objective-C 라이브러리를 사용하려는 경우가 발생할 수 있습니다. 이러한 상황에서는 Xamarin.iOS 바인딩 프로젝트를 사용하여 Xamarin.iOS 애플리케이션에서 라이브러리를 사용할 수 있는 C# 바인딩을 만들 수 있습니다.

일반적으로 iOS 에코시스템에서는 3가지 버전으로 라이브러리를 찾을 수 있습니다.

  • 헤더(.h 파일)와 .a 확장이 함께 포함된 미리 컴파일된 정적 라이브러리 파일입니다. 예를 들어 Google의 분석 라이브러리
  • 미리 컴파일된 프레임워크입니다. 이는 정적 라이브러리, 헤더 및 확장이 있는 추가 리소스 .framework 를 포함하는 폴더일 뿐입니다. 예를 들어 Google의 AdMob 라이브러리입니다.
  • 소스 코드 파일로도 사용할 수 있습니다. 예를 들어 Just .m.h Objective C 파일이 포함된 라이브러리입니다.

첫 번째 및 두 번째 시나리오에는 이미 미리 컴파일된 CocoaTouch 정적 라이브러리가 있으므로 이 문서에서는 세 번째 시나리오에 집중합니다. 바인딩을 만들기 전에 항상 라이브러리와 함께 제공된 라이선스를 검사 자유롭게 바인딩할 수 있습니다.

이 문서에서는 오픈 소스 InfColorPickerObjective-C 프로젝트를 예로 사용하여 바인딩 프로젝트를 만드는 단계별 연습을 제공하지만 이 가이드의 모든 정보는 타사 Objective-C 라이브러리에서 사용하도록 조정할 수 있습니다. InfColorPicker 라이브러리는 사용자가 HSB 표현에 따라 색을 선택할 수 있는 재사용 가능한 뷰 컨트롤러를 제공하여 색 선택을 보다 사용자에게 친숙하게 만듭니다.

Example of the InfColorPicker library running on iOS

Xamarin.iOS에서 이 특정 Objective-C API를 사용하는 데 필요한 모든 단계를 살펴보겠습니다.

  • 먼저 Xcode를 사용하여 정적 라이브러리를 Objective-C 만듭니다.
  • 그런 다음 이 정적 라이브러리를 Xamarin.iOS와 바인딩합니다.
  • 다음으로 Objective Sharpie가 Xamarin.iOS 바인딩에 필요한 필요한 API 정의의 일부(전부는 아님)를 자동으로 생성하여 워크로드를 줄일 수 있는 방법을 보여 줍니다.
  • 마지막으로 바인딩을 사용하는 Xamarin.iOS 애플리케이션을 만듭니다.

샘플 애플리케이션은 InfColorPicker API와 C# 코드 간의 통신에 강력한 대리자를 사용하는 방법을 보여 줍니다. 강력한 대리자를 사용하는 방법을 알아보면 약한 대리자를 사용하여 동일한 작업을 수행하는 방법을 설명합니다.

요구 사항

이 문서에서는 Xcode 및 Objective-C 언어에 대해 잘 알고 있으며 바인딩 Objective-C 설명서를 읽었다고 가정합니다. 또한 제공된 단계를 완료하려면 다음이 필요합니다.

  • Xcode 및 iOS SDK - Apple의 Xcode 및 최신 iOS API를 개발자 컴퓨터에 설치하고 구성해야 합니다.
  • Xcode 명령줄 도구 - Xcode 명령줄 도구는 현재 설치된 Xcode 버전에 대해 설치해야 합니다(설치 세부 정보는 아래 참조).
  • Mac용 Visual Studio 또는 Visual Studio - 최신 버전의 Mac용 Visual Studio 또는 Visual Studio를 개발 컴퓨터에 설치하고 구성해야 합니다. Apple Mac은 Xamarin.iOS 애플리케이션을 개발하는 데 필요하며 Visual Studio를 사용하는 경우 Xamarin.iOS 빌드 호스트에 연결해야 합니다.
  • Objective Sharpie의 최신 버전 - 여기에서 다운로드한 Objective Sharpie 도구의 현재 복사본입니다. Objective Sharpie가 이미 설치되어 있는 경우 다음을 사용하여 최신 버전으로 업데이트할 수 있습니다. sharpie update

Xcode 명령줄 도구 설치

위에서 설명한 대로 이 연습에서는 Xcode 명령줄 도구(특히 makelipo)를 사용합니다. 이 make 명령은 프로그램을 빌드하는 방법을 지정하는 메이크파일을 사용하여 실행 프로그램 및 라이브러리의 컴파일을 자동화하는 매우 일반적인 Unix 유틸리티입니다. 이 lipo 명령은 다중 아키텍처 파일을 만들기 위한 OS X 명령줄 유틸리티이며, 여러 .a 파일을 모든 하드웨어 아키텍처에서 사용할 수 있는 하나의 파일로 결합합니다.

Xcode FAQ 설명서가 있는 명령줄의 Apple Building에 따르면 OS X 10.9 이상에서는 Xcode 기본 설정 대화 상자의 다운로드 창이 더 이상 다운로드 명령줄 도구를 지원하지 않습니다.

도구를 설치하려면 다음 방법 중 하나를 사용해야 합니다.

  • Xcode 설치 - Xcode를 설치하면 모든 명령줄 도구와 함께 제공됩니다. OS X 10.9 shim(설치됨)에서 /usr/binXcode 내의 해당 도구에 /usr/bin 포함된 모든 도구를 매핑할 수 있습니다. 예를 들어 xcrun 명령줄에서 Xcode 내에서 도구를 찾거나 실행할 수 있는 명령입니다.

  • 터미널 애플리케이션 - 터미널 애플리케이션에서 다음 명령을 실행하여 명령줄 도구를 설치할 수 있습니다.xcode-select --install

    • 터미널 애플리케이션을 시작합니다.
    • Enter 키를 입력 xcode-select --install 하고 누릅니다. 예를 들면 다음과 같습니다.
    Europa:~ kmullins$ xcode-select --install
    
    • 명령줄 도구를 설치하라는 메시지가 표시되면 설치 단추를 클릭합니다.Installing the command line tools

    • 이 도구는 Apple 서버에서 다운로드하여 설치됩니다. Downloading the tools

  • Apple 개발자용 다운로드 - 명령줄 도구 패키지는 Apple 개발자용 다운로드 웹 페이지에서 사용할 수 있습니다. Apple ID로 로그인한 다음 명령줄 도구를 검색하여 다운로드합니다. Finding the Command Line Tools

명령줄 도구가 설치되면 연습을 계속할 준비가 된 것입니다.

연습

이 연습에서는 다음 단계를 설명합니다.

  • 정적 라이브러리 만들기 - 이 단계에서는 InfColorPickerObjective-C 코드의 정적 라이브러리를 만듭니다. 정적 라이브러리에는 파일 확장명이 .a 있으며 라이브러리 프로젝트의 .NET 어셈블리에 포함됩니다.
  • Xamarin.iOS 바인딩 프로젝트 만들기 - 정적 라이브러리가 있으면 이를 사용하여 Xamarin.iOS 바인딩 프로젝트를 만듭니다. 바인딩 프로젝트는 방금 만든 정적 라이브러리와 API를 사용하는 방법을 Objective-C 설명하는 C# 코드 형식의 메타데이터로 구성됩니다. 이 메타데이터를 일반적으로 API 정의라고 합니다. Objective Sharpie를 사용하여 API 정의를 만드는 데 도움을 드리겠습니다.
  • API 정의 정규화 - Objective Sharpie는 우리를 돕는 훌륭한 일을 하지만 모든 것을 할 수는 없습니다. API 정의를 사용하려면 API 정의를 변경해야 하는 몇 가지 변경 사항에 대해 설명합니다.
  • 바인딩 라이브러리 사용 - 마지막으로 Xamarin.iOS 애플리케이션을 만들어 새로 만든 바인딩 프로젝트를 사용하는 방법을 보여 드리겠습니다.

이제 어떤 단계가 관련되어 있는지 이해했으므로 연습의 나머지 단계로 넘어가겠습니다.

정적 라이브러리 만들기

Github에서 InfColorPicker에 대한 코드를 검사하는 경우:

Inspect the code for InfColorPicker in Github

프로젝트에서 다음 세 개의 디렉터리를 볼 수 있습니다.

  • InfColorPicker - 이 디렉터리에는 프로젝트에 대한 코드가 포함되어 있습니다 Objective-C .
  • PickerSamplePad - 이 디렉터리에는 샘플 iPad 프로젝트가 포함되어 있습니다.
  • PickerSample전화 - 이 디렉터리에는 샘플 i전화 프로젝트가 포함되어 있습니다.

GitHub에서 InfColorPicker 프로젝트를 다운로드하고 선택한 디렉터리에서 압축을 풉시다. 프로젝트의 Xcode 대상을 PickerSamplePhone 열면 Xcode 탐색기에서 다음 프로젝트 구조가 표시됩니다.

The project structure in the Xcode Navigator

이 프로젝트는 각 샘플 프로젝트에 InfColorPicker 소스 코드(빨간색 상자)를 직접 추가하여 코드 재사용을 달성합니다. 샘플 프로젝트의 코드는 파란색 상자 안에 있습니다. 이 특정 프로젝트는 정적 라이브러리를 제공하지 않으므로 정적 라이브러리를 컴파일하는 Xcode 프로젝트를 만들어야 합니다.

첫 번째 단계는 InfoColorPicker 소스 코드를 정적 라이브러리에 추가하는 것입니다. 이를 위해 다음을 수행해 보겠습니다.

  1. Xcode를 시작합니다.

  2. [파일] 메뉴에서 [새>프로젝트]를 선택합니다.

    Screenshot shows Project selected from the New menu of the File menu.

  3. 프레임워크 및 라이브러리, Cocoa Touch 정적 라이브러리 템플릿을 선택하고 다음 단추를 클릭합니다.

    Select the Cocoa Touch Static Library template

  4. 프로젝트 이름을 입력 InfColorPicker 하고 다음 단추를 클릭합니다.

    Enter InfColorPicker for the Project Name

  5. 프로젝트를 저장할 위치를 선택하고 확인 단추를 클릭합니다.

  6. 이제 InfColorPicker 프로젝트의 원본을 정적 라이브러리 프로젝트에 추가해야 합니다. InfColorPicker.h 파일이 정적 라이브러리에 이미 있기 때문에(기본적으로) Xcode에서 덮어쓸 수 없습니다. Finder에서 GitHub에서 압축을 푼 원래 프로젝트의 InfColorPicker 소스 코드로 이동하여 모든 InfColorPicker 파일을 복사하여 새 정적 라이브러리 프로젝트에 붙여넣습니다.

    Copy all of the InfColorPicker files

  7. Xcode로 돌아가서 InfColorPicker 폴더를 마우스 오른쪽 단추로 클릭하고 "InfColorPicker..."에 파일 추가를 선택합니다.

    Adding files

  8. 파일 추가 대화 상자에서 방금 복사한 InfColorPicker 소스 코드 파일로 이동하여 모두 선택하고 추가 단추를 클릭합니다.

    Select all and click the Add button

  9. 소스 코드가 프로젝트에 복사됩니다.

    The source code will be copied into the project

  10. Xcode 프로젝트 탐색기에서 InfColorPicker.m 파일을 선택하고 마지막 두 줄을 주석으로 처리합니다(이 라이브러리가 작성된 방식 때문에 이 파일은 사용되지 않음).

    Editing the InfColorPicker.m file

  11. 이제 라이브러리에 필요한 프레임워크가 있는지 검사 합니다. 이 정보는 추가 정보 또는 제공된 샘플 프로젝트 중 하나를 열어 찾을 수 있습니다. 이 예제에서는 ,를 UIKit.frameworkCoreGraphics.framework 사용Foundation.framework하므로 추가해 보겠습니다.

  12. InfColorPicker 대상 > 빌드 단계를 선택하고 라이브러리를 사용하여 이진 연결 섹션을 확장합니다.

    Expand the Link Binary With Libraries section

  13. 위에 + 나열된 필수 프레임 프레임워크를 추가할 수 있도록 단추를 사용하여 대화 상자를 엽니다.

    Add the required frames frameworks listed above

  14. 이제 라이브러리를 사용하여 이진 연결 섹션이 아래 이미지와 같이 표시됩니다.

    The Link Binary With Libraries section

이 시점에서 우리는 가깝지만 아직 끝나지 않았습니다. 정적 라이브러리가 만들어졌지만 iOS 디바이스 및 iOS 시뮬레이터 모두에 필요한 모든 아키텍처를 포함하는 Fat 이진 파일을 만들기 위해 빌드해야 합니다.

Fat 이진 만들기

모든 iOS 디바이스에는 시간이 지남에 따라 개발된 ARM 아키텍처로 구동되는 프로세서가 있습니다. 각각의 새로운 아키텍처는 이전 버전과의 호환성을 유지하면서 기본 새로운 지침 및 기타 개선 사항을 추가했습니다. iOS 디바이스에는 armv6, armv7, armv7s, arm64 명령 집합이 있지만 armv6은 더 이상 사용되지 않습니다. iOS 시뮬레이터는 ARM에서 구동되지 않으며 대신 x86 및 x86_64 전원이 공급되는 시뮬레이터입니다. 즉, 각 명령 집합에 대해 라이브러리를 제공해야 합니다.

Fat 라이브러리는 .a 지원되는 모든 아키텍처를 포함하는 파일입니다.

fat 이진 파일을 만드는 것은 3단계 프로세스입니다.

  • ARM 7 및 ARM64 버전의 정적 라이브러리를 컴파일합니다.
  • 정적 라이브러리의 x86 및 x84_64 버전을 컴파일합니다.
  • lipo 명령줄 도구를 사용하여 두 정적 라이브러리를 하나로 결합합니다.

이러한 세 단계는 다소 간단하지만 라이브러리에서 업데이트를 받거나 버그 수정이 필요한 경우 나중에 Objective-C 반복해야 할 수 있습니다. 이러한 단계를 자동화하려는 경우 iOS 바인딩 프로젝트의 향후 기본 테넌트 및 지원을 간소화합니다.

셸 스크립트, 레이크, xbuild 및 make와 같은 작업을 자동화하는 데 사용할 수 있는 많은 도구가 있습니다. Xcode 명령줄 도구가 설치되면 make 이 연습에 사용할 빌드 시스템도 설치됩니다. iOS 디바이스에서 작동하는 다중 아키텍처 공유 라이브러리와 모든 라이브러리의 시뮬레이터를 만드는 데 사용할 수 있는 메이크파일다음과 같습니다.

XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=./YOUR-PROJECT-NAME
PROJECT=$(PROJECT_ROOT)/YOUR-PROJECT-NAME.xcodeproj
TARGET=YOUR-PROJECT-NAME

all: lib$(TARGET).a

lib$(TARGET)-i386.a:
	$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator -configuration Release clean build
	-mv $(PROJECT_ROOT)/build/Release-iphonesimulator/lib$(TARGET).a $@

lib$(TARGET)-armv7.a:
	$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch armv7 -configuration Release clean build
	-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@

lib$(TARGET)-arm64.a:
	$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch arm64 -configuration Release clean build
	-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@

lib$(TARGET).a: lib$(TARGET)-i386.a lib$(TARGET)-armv7.a lib$(TARGET)-arm64.a
	xcrun -sdk iphoneos lipo -create -output $@ $^

clean:
	-rm -f *.a *.dll

선택한 일반 텍스트 편집기에서 메이크파일 명령을 입력하고 프로젝트 이름으로 섹션을 YOUR-PROJECT-NAME으로 업데이트합니다. 지침 내의 탭이 유지된 상태에서 위의 지침을 정확하게 붙여넣는 것도 중요합니다.

메이크파일이라는 이름의 파일을 위에서 만든 InfColorPicker Xcode 정적 라이브러리와 동일한 위치에 저장합니다.

Save the file with the name Makefile

Mac에서 터미널 애플리케이션을 열고 메이크파일의 위치로 이동합니다. 터미널에 입력 make 하고 Enter 키를 누르면 메이크파일이 실행됩니다.

Sample makefile output

make를 실행하면 스크롤하는 텍스트가 많이 표시됩니다. 모든 항목이 올바르게 작동하면 빌드 성공과 파일이 메이크파일libInfColorPickerSDK.alibInfColorPicker-armv7.alibInfColorPicker-i386.a 동일한 위치에 복사됩니다.

The libInfColorPicker-armv7.a, libInfColorPicker-i386.a and libInfColorPickerSDK.a files generated by the Makefile

다음 명령을 사용하여 Fat 이진 파일 내의 아키텍처를 확인할 수 있습니다.

xcrun -sdk iphoneos lipo -info libInfColorPicker.a

다음과 같은 내용이 표시됩니다.

Architectures in the fat file: libInfColorPicker.a are: i386 armv7 x86_64 arm64

이 시점에서 Xcode 및 Xcode 명령줄 도구 make 및 을 사용하여 정적 라이브러리를 만들어 iOS 바인딩의 첫 번째 단계를 완료했습니다 lipo. 다음 단계로 이동하고 Objective-Sharpie를 사용하여 API 바인딩 만들기를 자동화해 보겠습니다.

Xamarin.iOS 바인딩 프로젝트 만들기

Objective-Sharpie를 사용하여 바인딩 프로세스를 자동화하려면 API 정의를 보관하는 Xamarin.iOS 바인딩 프로젝트를 만들고(Objective-Sharpie를 사용하여 빌드할 수 있도록) C# 바인딩을 만들어야 합니다.

다음을 수행해 보겠습니다.

  1. Mac용 Visual Studio를 시작합니다.

  2. [파일] 메뉴에서 [새>솔루션]을 선택합니다.

    Starting a new solution

  3. 새 솔루션 대화 상자에서 라이브러리>iOS 바인딩 프로젝트를 선택합니다.

    Select iOS Binding Project

  4. 다음 단추를 클릭합니다.

  5. 프로젝트 이름으로 "InfColorPickerBinding"을 입력하고 만들기 단추를 클릭하여 솔루션을 만듭니다.

    Enter InfColorPickerBinding as the Project Name

솔루션이 만들어지고 두 개의 기본 파일이 포함됩니다.

The solution structure in the Solution Explorer

  • ApiDefinition.cs - 이 파일에는 API가 C#으로 래핑되는 방법을 Objective-C 정의하는 계약이 포함됩니다.
  • Structs.cs - 이 파일에는 인터페이스 및 대리자에 필요한 구조 또는 열거형 값이 포함됩니다.

이 두 파일은 연습 뒷부분에서 작업할 예정입니다. 먼저 바인딩 프로젝트에 InfColorPicker 라이브러리를 추가해야 합니다.

바인딩 프로젝트에 정적 라이브러리 포함

이제 기본 바인딩 프로젝트가 준비되었습니다. InfColorPicker 라이브러리에 대해 위에서 만든 Fat Binary 라이브러리를 추가해야 합니다.

다음 단계에 따라 라이브러리를 추가합니다.

  1. Solution Pad에서 네이티브 참조 폴더를 마우스 오른쪽 단추로 클릭하고 네이티브 참조 추가를 선택합니다.

    Add Native References

  2. 앞에서 만든 Fat Binary(libInfColorPickerSDK.a)로 이동하여 열기 단추를 누릅니다.

    Select the libInfColorPickerSDK.a file

  3. 이 파일은 프로젝트에 포함됩니다.

    Including a file

.a 파일이 프로젝트에 추가되면 Xamarin.iOS는 파일의 빌드 동작을 ObjcBindingNativeLibrary로 자동으로 설정하고 특수 libInfColorPickerSDK.linkwith.cs파일을 만듭니다.

이 파일에는 방금 추가한 LinkWith 정적 라이브러리를 처리하는 방법을 Xamarin.iOS에 알려주는 특성이 포함되어 있습니다. 이 파일의 내용은 다음 코드 조각에 나와 있습니다.

using ObjCRuntime;

[assembly: LinkWith ("libInfColorPickerSDK.a", SmartLink = true, ForceLoad = true)]

이 특성은 LinkWith 프로젝트의 정적 라이브러리와 몇 가지 중요한 링커 플래그를 식별합니다.

다음으로 InfColorPicker 프로젝트에 대한 API 정의를 만들어야 합니다. 이 연습에서는 Objective Sharpie를 사용하여 파일 ApiDefinition.cs 생성합니다.

Objective Sharpie 사용

Objective Sharpie는 타사 Objective-C 라이브러리를 C#에 바인딩하는 데 필요한 정의를 만드는 데 도움이 되는 명령줄 도구(Xamarin에서 제공)입니다. 이 섹션에서는 Objective Sharpie를 사용하여 InfColorPicker 프로젝트에 대한 초기 ApiDefinition.cs 만듭니다.

시작하려면 이 가이드에 설명된 대로 Objective Sharpie 설치 관리자 파일을 다운로드해 보겠습니다. 설치 관리자를 실행하고 설치 마법사의 모든 화면 프롬프트에 따라 개발 컴퓨터에 Objective Sharpie를 설치합니다.

Objective Sharpie가 성공적으로 설치되면 터미널 앱을 시작하고 다음 명령을 입력하여 바인딩을 지원하기 위해 제공하는 모든 도구에 대한 도움말을 확인해 보겠습니다.

sharpie -help

위의 명령을 실행하면 다음 출력이 생성됩니다.

Europa:Resources kmullins$ sharpie -help
usage: sharpie [OPTIONS] TOOL [TOOL_OPTIONS]

Options:
  -h, --helpShow detailed help
  -v, --versionShow version information

Available Tools:
  xcode              Get information about Xcode installations and available SDKs.
  pod                Create a Xamarin C# binding to Objective-C CocoaPods
  bind               Create a Xamarin C# binding to Objective-C APIs
  update             Update to the latest release of Objective Sharpie
  verify-docs        Show cross reference documentation for [Verify] attributes
  docs               Open the Objective Sharpie online documentation

이 연습을 위해 다음과 같은 Objective Sharpie 도구를 사용합니다.

  • xcode - 이 도구는 현재 Xcode 설치 및 설치된 iOS 및 Mac API 버전에 대한 정보를 제공합니다. 나중에 바인딩을 생성할 때 이 정보를 사용합니다.
  • bind - 이 도구를 사용하여 InfColorPicker 프로젝트의 .h 파일을 초기 ApiDefinition.cs 구문 분석하고 파일을 StructsAndEnums.cs.

특정 Objective Sharpie 도구에 대한 도움말을 보려면 도구 이름과 옵션을 입력합니다 -help . 예를 들어 sharpie xcode -help 다음 출력을 반환합니다.

Europa:Resources kmullins$ sharpie xcode -help
usage: sharpie xcode [OPTIONS]+

Options:
  -h, -help           Show detailed help
  -v, -verbose        Be verbose with output

Xcode Options:
  -sdks               List all available Xcode SDKs. Pass -verbose for more
                        details.
  -sdkpath SDK        Output the path of the SDK
  -frameworks SDK     List all available framework directories in a given SDK.

바인딩 프로세스를 시작하기 전에 터미널 sharpie xcode -sdks에 다음 명령을 입력하여 현재 설치된 SDK에 대한 정보를 가져와야 합니다.

amyb:Desktop amyb$ sharpie xcode -sdks
sdk: appletvos9.2    arch: arm64
sdk: iphoneos9.3     arch: arm64   armv7
sdk: macosx10.11     arch: x86_64  i386
sdk: watchos2.2      arch: armv7

위에서는 컴퓨터에 SDK가 iphoneos9.3 설치되어 있음을 알 수 있습니다. 이 정보를 사용하여 InfColorPicker 프로젝트 .h 파일을 초기 ApiDefinition.cs InfColorPicker StructsAndEnums.cs 프로젝트로 구문 분석할 준비가 되었습니다.

터미널 앱에서 다음 명령을 입력합니다.

sharpie bind --output=InfColorPicker --namespace=InfColorPicker --sdk=[iphone-os] -scope [full-path-to-project]/InfColorPicker/InfColorPicker [full-path-to-project]/InfColorPicker/InfColorPicker/*.h

InfColorPicker Xcode 프로젝트 파일이 컴퓨터에 있고 [iphone-os]가 설치한 iOS SDK인 디렉터리의 전체 경로는 다음과 [full-path-to-project] 같습니다sharpie xcode -sdks. 이 예제에서는 *.h를 이 디렉터리의 모든 헤더 파일을 포함하는 매개 변수로 전달했습니다. 일반적으로 이 작업을 수행하지 말고 헤더 파일을 주의 깊게 읽어 다른 모든 관련 파일을 참조하는 최상위 .h 파일을 찾아 Objective Sharpie에 전달하면 됩니다.

인수의 -scope 경우 바인딩할 헤더가 있는 폴더를 전달합니다. 인수가 -scope 없으면 Objective Sharpie는 가져온 iOS SDK 헤더에 대한 바인딩을 생성하려고 시도합니다(예: #import <UIKit.h>바인딩 프로젝트를 컴파일할 때 오류가 발생할 수 있는 거대한 정의 파일). 인수 집합을 -scope 사용하면 Objective Sharpie는 범위가 지정된 폴더 외부의 헤더에 대한 바인딩을 생성하지 않습니다.

터미널에서 다음 출력 이 생성됩니다.

Europa:Resources kmullins$ sharpie bind -output InfColorPicker -namespace InfColorPicker -sdk iphoneos8.1 /Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPicker.h -unified
Compiler configuration:
    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -miphoneos-version-min=8.1 -resource-dir /Library/Frameworks/ObjectiveSharpie.framework/Versions/1.1.1/clang-resources -arch armv7 -ObjC

[  0%] parsing /Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPicker.h
In file included from /Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPicker.h:60:
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:28:1: warning: no 'assign',
      'retain', or 'copy' attribute is specified - 'assign' is assumed [-Wobjc-property-no-attribute]
@property (nonatomic) UIColor* sourceColor;
^
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:28:1: warning: default property
      attribute 'assign' not appropriate for non-GC object [-Wobjc-property-no-attribute]
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:29:1: warning: no 'assign',
      'retain', or 'copy' attribute is specified - 'assign' is assumed [-Wobjc-property-no-attribute]
@property (nonatomic) UIColor* resultColor;
^
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:29:1: warning: default property
      attribute 'assign' not appropriate for non-GC object [-Wobjc-property-no-attribute]
4 warnings generated.
[100%] parsing complete
[bind] InfColorPicker.cs
Europa:Resources kmullins$

또한 InfColorPicker.enums.csInfColorPicker.cs 파일이 디렉터리에 만들어집니다.

The InfColorPicker.enums.cs and InfColorPicker.cs files

위에서 만든 바인딩 프로젝트에서 두 파일을 모두 엽니다. InfColorPicker.cs 파일의 내용을 복사하여 ApiDefinition.cs 파일에 붙여넣고, 기존 namespace ... 코드 블록을 InfColorPicker.cs 파일의 내용으로 바꿔서 문을 그대로 둡 using 니다.

The InfColorPickerControllerDelegate file

API 정의 정규화

Objective Sharpie에서 변환 Delegates하는 데 문제가 있는 경우가 있으므로 인터페이스 정의를 InfColorPickerControllerDelegate 수정하고 줄을 다음으로 바꿔 [Protocol, Model] 야 합니다.

[BaseType(typeof(NSObject))]
[Model]

정의가 다음과 같이 표시되도록 합니다.

The definition

다음으로 파일 내용 InfColorPicker.enums.cs 과 동일한 작업을 수행하여 파일을 복사하여 StructsAndEnums.cs 파일에 붙여넣고 문을 그대로 유지 using 합니다.

The contents the StructsAndEnums.cs file

Objective Sharpie가 특성으로 바인딩 [Verify] 에 주석을 추가한 것을 확인할 수도 있습니다. 이러한 특성은 바인딩을 원래 C/Objective-C 선언(바인딩된 선언 위의 주석에 제공됨)과 비교하여 Objective Sharpie가 올바른 작업을 했는지 확인해야 함을 나타냅니다. 바인딩을 확인한 후에는 verify 특성을 제거해야 합니다. 자세한 내용은 확인 가이드를 참조하세요.

이 시점에서 바인딩 프로젝트는 완료되고 빌드할 준비가 되어 있어야 합니다. 바인딩 프로젝트를 빌드하고 오류 없이 끝났는지 확인해 보겠습니다.

바인딩 프로젝트를 빌드하고 오류가 없는지 확인합니다.

바인딩 사용

다음 단계에 따라 위에서 만든 iOS 바인딩 라이브러리를 사용하는 샘플 i전화 애플리케이션을 만듭니다.

  1. Xamarin.iOS 프로젝트 만들기 - 다음 스크린샷과 같이 InfColorPickerSample이라는 새 Xamarin.iOS 프로젝트를 솔루션에 추가합니다.

    Adding a Single View App

    Setting the Identifier

  2. 바인딩 프로젝트에 대한 참조 추가 - InfColorPickerBinding 프로젝트에 대한 참조가 있도록 InfColorPickerSample 프로젝트를 업데이트합니다.

    Adding Reference to the Binding Project

  3. i전화 사용자 인터페이스 만들기 - InfColorPickerSample 프로젝트에서 MainStoryboard.storyboard 파일을 두 번 클릭하여 iOS 디자이너에서 편집합니다. 보기에 단추를 추가하고 다음과 같이 호출 ChangeColorButton합니다.

    Adding a Button to the view

  4. InfColorPickerView.xib 추가 - InfColorPicker Objective-C 라이브러리에는 .xib 파일이 포함됩니다. Xamarin.iOS는 이 .xib 를 바인딩 프로젝트에 포함하지 않으므로 샘플 애플리케이션에서 런타임 오류가 발생합니다. 이에 대한 해결 방법은 Xamarin.iOS 프로젝트에 .xib 파일을 추가하는 것입니다. Xamarin.iOS 프로젝트를 선택하고, 마우스 오른쪽 단추를 클릭하고, 파일 추가 > 를 선택하고, 다음 스크린샷과 같이 .xib 파일을 추가합니다.

    Add the InfColorPickerView.xib

  5. 메시지가 표시되면 .xib 파일을 프로젝트에 복사합니다.

다음으로 프로토콜 및 바인딩 및 C# 코드에서 Objective-C 프로토콜을 처리하는 방법을 간략하게 살펴보겠습니다.

프로토콜 및 Xamarin.iOS

에서 Objective-C프로토콜은 특정 상황에서 사용할 수 있는 메서드(또는 메시지)를 정의합니다. 개념적으로 C#의 인터페이스와 매우 유사합니다. 프로토콜과 C# 인터페이스의 Objective-C 한 가지 주요 차이점은 프로토콜에 클래스가 구현할 필요가 없는 메서드인 선택적 메서드가 있을 수 있다는 것입니다. Objective-C@optional 는 선택적 메서드를 나타내는 데 사용되는 키워드(keyword) 사용합니다. 프로토콜에 대한 자세한 내용은 이벤트, 프로토콜 및 대리자를 참조 하세요.

InfColorPickerController 에는 아래 코드 조각에 표시된 프로토콜이 하나 있습니다.

@protocol InfColorPickerControllerDelegate

@optional

- (void) colorPickerControllerDidFinish: (InfColorPickerController*) controller;
// This is only called when the color picker is presented modally.

- (void) colorPickerControllerDidChangeColor: (InfColorPickerController*) controller;

@end

이 프로토콜은 InfColorPickerController에서 사용자가 새 색을 선택했으며 InfColorPickerController완료되었음을 클라이언트에 알리는 데 사용됩니다. Objective Sharpie는 다음 코드 조각과 같이 이 프로토콜을 매핑했습니다.

[BaseType(typeof(NSObject))]
[Model]
public partial interface InfColorPickerControllerDelegate {

    [Export ("colorPickerControllerDidFinish:")]
    void ColorPickerControllerDidFinish (InfColorPickerController controller);

    [Export ("colorPickerControllerDidChangeColor:")]
    void ColorPickerControllerDidChangeColor (InfColorPickerController controller);
}

바인딩 라이브러리가 컴파일되면 Xamarin.iOS는 가상 메서드를 사용하여 이 인터페이스를 구현하는 추상 기본 클래스를 InfColorPickerControllerDelegate만듭니다.

Xamarin.iOS 애플리케이션에서 이 인터페이스를 구현할 수 있는 두 가지 방법이 있습니다.

  • 강력한 대리자 - 강력한 대리자를 사용하려면 적절한 메서드를 서브클래싱 InfColorPickerControllerDelegate 하고 재정의하는 C# 클래스를 만들어야 합니다. InfColorPickerController 는 이 클래스의 인스턴스를 사용하여 클라이언트와 통신합니다.
  • 약한 대리자 - 약한 대리자는 일부 클래스(예: InfColorPickerSampleViewController)에서 public 메서드를 만든 다음 특성을 통해 Export 프로토콜에 해당 메서드 InfColorPickerDelegate 를 노출하는 것과 약간 다른 기술입니다.

강력한 대리자는 Intellisense, 형식 안전성 및 더 나은 캡슐화를 제공합니다. 이러한 이유로 약한 대리자 대신 가능한 경우 강력한 대리자를 사용해야 합니다.

이 연습에서는 먼저 강력한 대리자를 구현한 다음 약한 대리자를 구현하는 방법을 설명하는 두 가지 기술에 대해 설명합니다.

강력한 대리자 구현

강력한 대리자를 사용하여 메시지에 응답하여 Xamarin.iOS 애플리케이션을 colorPickerControllerDidFinish: 완료합니다.

하위 클래스 InfColorPickerControllerDelegate - 프로젝트에 ColorSelectedDelegate새 클래스를 추가합니다. 다음 코드가 있도록 클래스를 편집합니다.

using InfColorPickerBinding;
using UIKit;

namespace InfColorPickerSample
{
  public class ColorSelectedDelegate:InfColorPickerControllerDelegate
  {
    readonly UIViewController parent;

    public ColorSelectedDelegate (UIViewController parent)
    {
      this.parent = parent;
    }

    public override void ColorPickerControllerDidFinish (InfColorPickerController controller)
    {
      parent.View.BackgroundColor = controller.ResultColor;
      parent.DismissViewController (false, null);
    }
  }
}

Xamarin.iOS는 라는 InfColorPickerControllerDelegate추상 기본 클래스를 만들어 대리자를 바인딩 Objective-C 합니다. 이 형식을 서브클래스하고 메서드를 ColorPickerControllerDidFinish 재정의하여 속성InfColorPickerController의 값에 ResultColor 액세스합니다.

ColorSelectedDelegate 인스턴스 만들기 - 이벤트 처리기에는 이전 단계에서 만든 형식의 ColorSelectedDelegate 인스턴스가 필요합니다. 클래스 InfColorPickerSampleViewController 를 편집하고 클래스에 다음 인스턴스 변수를 추가합니다.

ColorSelectedDelegate selector;

ColorSelectedDelegate 변수 초기화 - 유효한 인스턴스인지 확인 selector 하려면 다음 코드 조각과 일치하도록 메서드 ViewDidLoadViewController 를 업데이트합니다.

public override void ViewDidLoad ()
{
  base.ViewDidLoad ();
  ChangeColorButton.TouchUpInside += HandleTouchUpInsideWithStrongDelegate;
  selector = new ColorSelectedDelegate (this);
}

HandleTouchUpInsideWithStrongDelegate 메서드 구현 - 사용자가 ColorChangeButton을 터치할 때의 이벤트 처리기를 구현합니다. 편집 ViewController하고 다음 메서드를 추가합니다.

using InfColorPicker;
...

private void HandleTouchUpInsideWithStrongDelegate (object sender, EventArgs e)
{
    InfColorPickerController picker = InfColorPickerController.ColorPickerViewController();
    picker.Delegate = selector;
    picker.PresentModallyOverViewController (this);
}

먼저 정적 메서드를 통해 인스턴스 InfColorPickerController 를 가져오고 해당 인스턴스가 속성을 InfColorPickerController.Delegate통해 강력한 대리자를 인식하게 합니다. 이 속성은 Objective Sharpie에 의해 자동으로 생성되었습니다. 마지막으로 사용자가 색을 선택할 수 있도록 보기를 InfColorPickerSampleViewController.xib 표시하도록 호출 PresentModallyOverViewController 합니다.

애플리케이션 실행 - 이 시점에서 모든 코드로 완료되었습니다. 애플리케이션을 실행하는 경우 다음 스크린샷과 같이 배경색을 InfColorColorPickerSampleView 변경할 수 있습니다.

Running the Application

축하합니다! 이 시점에서 Xamarin.iOS 애플리케이션에서 사용할 라이브러리를 성공적으로 만들고 바인딩 Objective-C 했습니다. 다음으로 약한 대리자 사용에 대해 알아보겠습니다.

약한 대리자 구현

Xamarin.iOS는 특정 대리자에 대한 프로토콜에 Objective-C 바인딩된 클래스를 서브클래싱하는 대신 파생되는 모든 클래스에서 NSObject프로토콜 메서드를 구현하고 메서드 ExportAttribute를 데코레이팅한 다음 적절한 선택기를 제공할 수 있습니다. 이 방법을 사용하면 속성 대신 속성에 WeakDelegate 클래스의 인스턴스를 Delegate 할당합니다. 약한 대리자는 대리자 클래스를 다른 상속 계층 구조로 전환할 수 있는 유연성을 제공합니다. Xamarin.iOS 애플리케이션에서 약한 대리자를 구현하고 사용하는 방법을 살펴보겠습니다.

TouchUpInside 에 대한 이벤트 처리기 만들기 - 배경색 변경 단추의 이벤트에 대한 TouchUpInside 새 이벤트 처리기를 만들어 보겠습니다. 이 처리기는 이전 섹션에서 만든 처리기와 동일한 역할을 HandleTouchUpInsideWithStrongDelegate 채우지만 강력한 대리자 대신 약한 대리자를 사용합니다. 클래스 ViewController를 편집하고 다음 메서드를 추가합니다.

private void HandleTouchUpInsideWithWeakDelegate (object sender, EventArgs e)
{
    InfColorPickerController picker = InfColorPickerController.ColorPickerViewController();
    picker.WeakDelegate = this;
    picker.SourceColor = this.View.BackgroundColor;
    picker.PresentModallyOverViewController (this);
}

ViewDidLoad 업데이트 - 방금 만든 이벤트 처리기를 사용할 수 있도록 변경 ViewDidLoad 해야 합니다. 다음 코드 조각과 유사하게 편집 ViewController 하고 변경 ViewDidLoad 합니다.

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    ChangeColorButton.TouchUpInside += HandleTouchUpInsideWithWeakDelegate;
}

colorPickerControllerDidFinish 처리: 메시지 - ViewController 완료되면 iOS에서 메시지를 colorPickerControllerDidFinish:WeakDelegate보냅니다. 이 메시지를 처리할 수 있는 C# 메서드를 만들어야 합니다. 이렇게 하려면 C# 메서드를 만든 다음 , 를 사용하여 표시합니다 ExportAttribute. 를 편집 ViewController하고 클래스에 다음 메서드를 추가합니다.

[Export("colorPickerControllerDidFinish:")]
public void ColorPickerControllerDidFinish (InfColorPickerController controller)
{
    View.BackgroundColor = controller.ResultColor;
    DismissViewController (false, null);
}

애플리케이션을 실행합니다. 이제 이전과 똑같이 동작해야 하지만 강력한 대리자 대신 약한 대리자를 사용합니다. 이 시점에서 이 연습을 성공적으로 완료했습니다. 이제 Xamarin.iOS 바인딩 프로젝트를 만들고 사용하는 방법을 이해해야 합니다.

요약

이 문서에서는 Xamarin.iOS 바인딩 프로젝트를 만들고 사용하는 과정을 안내했습니다. 먼저 기존 라이브러리를 정적 라이브러리로 컴파일하는 Objective-C 방법을 설명했습니다. 그런 다음 Xamarin.iOS 바인딩 프로젝트를 만드는 방법과 Objective Sharpie를 사용하여 라이브러리에 대한 Objective-C API 정의를 생성하는 방법을 설명했습니다. 생성된 API 정의를 업데이트하고 조정하여 공용 사용에 적합하도록 하는 방법을 설명했습니다. Xamarin.iOS 바인딩 프로젝트가 완료된 후 강력한 대리자와 약한 대리자를 사용하는 데 중점을 두고 Xamarin.iOS 애플리케이션에서 해당 바인딩을 사용하기로 했습니다.