코드를 Unified API로 업데이트하는 팁

이전 Xamarin 솔루션을 Unified API로 업데이트할 때 다음 오류가 발생할 수 있습니다.

NSInvalidArgumentException에서 스토리보드 오류를 찾을 수 없음

현재 버전의 Mac용 Visual Studio 자동화된 마이그레이션 도구를 사용하여 프로젝트를 통합 API로 변환한 후에 발생할 수 있는 버그가 있습니다. 업데이트 후 양식에 오류 메시지가 표시되면 다음을 수행합니다.

Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Could not find a storyboard named 'xxx' in bundle NSBundle...

다음을 수행하여 이 문제를 해결하고 다음 빌드 대상 파일을 찾을 수 있습니다.

/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/2.1/Xamarin.iOS.Common.targets

이 파일에서 다음 대상 선언을 찾아야 합니다.

<Target Name="_CopyContentToBundle"
        Inputs = "@(_BundleResourceWithLogicalName)"
        Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >

그리고 특성에 DependsOnTargets="_CollectBundleResources" 추가합니다. 다음과 같습니다.

<Target Name="_CopyContentToBundle"
        DependsOnTargets="_CollectBundleResources"
        Inputs = "@(_BundleResourceWithLogicalName)"
        Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >

파일을 저장하고, Mac용 Visual Studio 다시 부팅하고, 프로젝트의 클린 및 다시 빌드를 수행합니다. 이 문제에 대한 수정 사항은 곧 Xamarin에서 릴리스되어야 합니다.

유용한 팁

마이그레이션 도구를 사용한 후에도 수동 개입이 필요한 몇 가지 컴파일러 오류가 발생할 수 있습니다. 수동으로 수정해야 할 수 있는 몇 가지 사항은 다음과 같습니다.

  • s를 비교하려면 enum캐스트가 (int) 필요할 수 있습니다.

  • NSDictionary.IntValue가 반환됩니다nintInt32Value. 대신 사용할 수 있는 항목이 있습니다.

  • nfloat형식을 nint 표시 conststatic readonly nint 할 수 없습니다. 적절한 대안입니다.

  • 네임스페이스에 MonoTouch. 직접 사용되던 항목은 이제 일반적으로 ObjCRuntime. 네임스페이스에 있습니다(예: MonoTouch.Constants.Version 현재 ObjCRuntime.Constants.Version).

  • 개체를 serialize하는 코드는 직렬화 nintnfloat 형식을 시도할 때 중단됩니다. 마이그레이션 후 serialization 코드가 예상대로 작동하는지 검사 합니다.

  • 자동화된 도구가 조건부 컴파일러 지시문 내 #if #else 의 코드를 누락하는 경우가 있습니다. 이 경우 수동으로 수정해야 합니다(아래 일반적인 오류 참조).

  • 수동으로 내보낸 메서드는 [Export] 마이그레이션 도구에서 자동으로 수정되지 않을 수 있습니다. 예를 들어 이 코드 조각에서는 반환 형식 nfloat을 다음으로 수동으로 업데이트해야 합니다.

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • 통합 API는 손실 없는 변환이 아니므로 NSDate와 .NET DateTime 간에 암시적 변환을 제공하지 않습니다. 캐스팅하기 전에 .NET DateTimeDateTimeKind.Unspecified 로컬 또는 UTC로 변환하는 데 관련된 오류를 방지하려면 NSDate.

  • Objective-C 범주 메서드는 이제 통합 API에서 확장 메서드로 생성됩니다. 예를 들어 이전에 사용한 UIView.DrawString 코드는 이제 통합 API에서 참조 NSString.DrawString 됩니다.

  • AVFoundation 클래스를 사용하는 코드는 VideoSettings 속성을 사용하도록 WeakVideoSettings 변경해야 합니다. 이렇게 하려면 설정 클래스에서 속성으로 사용할 수 있는 Dictionary/>가 필요합니다. 예를 들면 다음과 같습니다.

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • NSObject .ctor(IntPtr) 생성자가 public에서 protected로 변경되었습니다(부적절한 사용을 방지하기 위해).

  • NSAction표준 .NETAction으로 바뀌었습니다. 일부 단순(단일 매개 변수) 대리자도 .로 Action<T>대체되었습니다.

마지막으로, 클래식 v 통합 API 차이점을 참조하여 코드에서 API에 대한 변경 내용을 조회합니다. 이 페이지를 검색하면 클래식 API 및 업데이트된 항목을 찾는 데 도움이 됩니다.

참고 항목

네임스페이 MonoTouch.Dialog 스는 마이그레이션 후 동일하게 기본. 코드에서 MonoTouch.Dialog를 사용하는 경우 해당 네임스페이스를계속 사용해야 합니다. !MonoTouch.DialogDialog

일반적인 컴파일러 오류

일반적인 오류의 다른 예는 솔루션과 함께 아래에 나열되어 있습니다.

오류 CS0012: 'MonoTouch.UIKit.UIView' 형식은 참조되지 않는 어셈블리에 정의되어 있습니다.

수정: 일반적으로 프로젝트는 통합 API를 사용하여 빌드되지 않은 구성 요소 또는 NuGet 패키지를 참조합니다. 모든 구성 요소 및 NuGet 패키지를 삭제하고 다시 추가해야 합니다. 이 오류가 해결되지 않으면 외부 라이브러리가 아직 통합 API를 지원하지 않을 수 있습니다.

오류 MT0034: 동일한 Xamarin.iOS 프로젝트에 'monotouch.dll' 및 'Xamarin.iOS.dll'을 둘 다 포함할 수 없습니다. 'Xamarin.iOS.dll'은 명시적으로 참조되고 'monotouch.dll'은 'Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null'에서 참조됩니다.

수정: 이 오류를 일으키는 구성 요소를 삭제하고 프로젝트에 다시 추가합니다.

오류 CS0234: 형식 또는 네임스페이스 이름 'Foundation'이 네임스페이스 'MonoTouch'에 없습니다. 어셈블리 참조가 있는지 확인하세요.

수정: Mac용 Visual Studio 자동화된 마이그레이션 도구는 모든 MonoTouch.Foundation 참조를 Foundation업데이트해야 하지만 일부 경우에는 수동으로 업데이트해야 합니다. 와 같이 UIKit이전에 포함된 MonoTouch다른 네임스페이스에 대해 유사한 오류가 나타날 수 있습니다.

오류 CS0266: 'double' 형식을 'System.float'로 암시적으로 변환할 수 없습니다.

수정: 형식을 변경하고 .로 캐스팅합니다 nfloat. 이 오류는 64비트 등가물이 있는 다른 형식에 대해서도 발생할 수 있습니다(예: nint).

nfloat scale = (nfloat)Math.Min(rect.Width, rect.Height);

오류 CS0266: 'CoreGraphics.CGRect' 형식을 'System.Drawing.RectangleF'로 암시적으로 변환할 수 없습니다. 명시적 변환이 있습니다. 캐스트가 있는지 확인하세요.

수정: 인스턴스를 CGRectCGSizeSizeF a0/gt;로 변경합니다.PointFCGPoint 네임스페이스를 using System.Drawing; 대체해야 using CoreGraphics; 합니다(아직 없는 경우).

오류 CS1502: 'CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])'에 대한 최상의 오버로드된 메서드 일치에 잘못된 인수가 있습니다.

수정: 배열 형식을 명시적으로 캐스팅Math.PI합니다nfloat[].

grphc.SetLineDash (0, new nfloat[] { 0, 3 * (nfloat)Math.PI });

오류 CS0115: 'WordsTableSource.RowsInSection(UIKit.UITableView, int)'이 재정의로 표시되었지만 재정의하기에 적합한 메서드는 없습니다.

수정: 반환 값 및 매개 변수 형식을 .로 nint변경합니다. 이는 일반적으로 메서드 재정의(예: , 등)TitleForHeaderGetViewForHeaderRowsInSectionGetHeightForRowNumberOfSections에서 UITableViewSource발생합니다.

public override nint RowsInSection (UITableView tableview, nint section) {

오류 CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView)재정의된 멤버와 일치하려면 반환 형식이 'System.nint'여야 합니다. UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)

수정: 반환 형식이 변경 nint되면 반환 값을 nint.로 캐스팅합니다.

public override nint NumberOfSections (UITableView tableView)
{
    return (nint)navItems.Count;
}

오류 CS1061: 'CoreGraphics.CGPath' 형식에 'AddElipseInRect'에 대한 정의가 없습니다.

수정: 맞춤법을 수정합니다 AddEllipseInRect. 다른 이름 변경 내용은 다음과 같습니다.

  • 'Color.Black'을 .로 NSColor.Black변경합니다.
  • MapKit 'AddAnnotation'을 .로 AddAnnotations변경합니다.
  • AVFoundation 'DataUsingEncoding'을 .로 Encode변경합니다.
  • AVFoundation 'AVMetadataObject.TypeQRCode'를 AVMetadataObjectType.QRCode.
  • AVFoundation 'Video설정'를 WeakVideoSettings.
  • PopViewControllerAnimated를 .로 PopViewController변경합니다.
  • CoreGraphics 'CGBitmapContext.SetRGBFillColor'를 SetFillColor.

오류 CS0546: 'MapKit.MKAnnotation.Coordinate'에 재정의 가능한 set 접근자(CS0546)가 없으므로 재정의할 수 없습니다.

MKAnnotation을 서브클래싱하여 사용자 지정 주석을 만들 때 좌표 필드에는 setter가 없고 getter만 있습니다.

수정 사항

  • 좌표를 추적하는 필드 추가
  • 좌표 속성의 getter에서 이 필드를 반환합니다.
  • SetCoordinate 메서드를 재정의하고 필드를 설정합니다.
  • 전달된 좌표 매개 변수를 사용하여 ctor에서 SetCoordinate 호출

다음과 유사하게 나타납니다.

class BasicPinAnnotation : MKAnnotation
{
    private CLLocationCoordinate2D _coordinate;

    public override CLLocationCoordinate2D Coordinate
    {
        get
        {
            return _coordinate;
        }
    }

    public override void SetCoordinate(CLLocationCoordinate2D value)
    {
        _coordinate = value;
    }

    public BasicPinAnnotation (CLLocationCoordinate2D coordinate)
    {
        SetCoordinate(coordinate);
    }
}