Поделиться через


Советы по обновлению кода в Unified API

При обновлении старых решений Xamarin до единого API могут возникнуть следующие ошибки.

NSInvalidArgumentException не удалось найти ошибку раскадровки

Существует ошибка в текущей версии Visual Studio для Mac, которая может возникнуть после использования средства автоматической миграции для преобразования проекта в объединенные 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)')" >

Сохраните файл, перезагрузите Visual Studio для Mac и выполните очистку и перестроение проекта. Исправление этой проблемы должно быть выпущено Xamarin в ближайшее время.

Полезные Советы

После использования средства миграции могут по-прежнему возникать некоторые ошибки компилятора, требующие вмешательства вручную. Некоторые вещи, которые могут быть исправлены вручную, включают:

  • enumДля сравнения s может потребоваться (int) приведение.

  • NSDictionary.IntValue теперь возвращает значение nint, Int32Value есть, который можно использовать вместо этого.

  • nfloat и nint типы не могут быть помечены const; static readonly nint является разумной альтернативой.

  • Элементы, которые использовались непосредственно в пространстве имен, теперь обычно находятся в MonoTouch.ObjCRuntime. пространстве имен (например, MonoTouch.Constants.Version сейчас ObjCRuntime.Constants.Version).

  • Код, сериализующий объекты, может прерваться при попытке сериализации nint и nfloat типов. Обязательно проверка код сериализации работает должным образом после миграции.

  • Иногда автоматизированное средство пропускает код в #if #else директивах условного компилятора. В этом случае необходимо вручную внести исправления (см. распространенные ошибки ниже).

  • Экспортированные вручную методы могут не быть автоматически исправлены [Export] средством миграции, например в этом фрагменте кода, необходимо вручную обновить тип возвращаемого значения nfloat:

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • Унифицированный API не предоставляет неявное преобразование между NSDate и .NET DateTime, так как это не без потери преобразования. Чтобы предотвратить ошибки, связанные с DateTimeKind.Unspecified преобразованием .NET DateTime в локальный или UTC перед приведением в NSDate.

  • Objective-C Теперь методы категории создаются как методы расширения в едином API. Например, код, который ранее использовался UIView.DrawString , будет ссылаться NSString.DrawString на единый API.

  • Код, использующий классы AVFoundation, VideoSettings должен измениться для использования WeakVideoSettings свойства. Для этого требуется Dictionary, который доступен в качестве свойства в классах параметров, например:

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • Конструктор NSObject .ctor(IntPtr) был изменен с общедоступного на защищенный (чтобы предотвратить неправильное использование).

  • NSAction заменен стандартным .NET Action. Некоторые простые делегаты (один параметр) также были заменены Action<T>на .

Наконец, ознакомьтесь с различиями в классическом унифицированном API для поиска изменений в API в коде. Поиск на этой странице поможет найти классические API и то, что они были обновлены.

Примечание.

Пространство MonoTouch.Dialog имен остается неизменным после миграции. Если в коде используется MonoTouch.Dialog , вы должны продолжать использовать это пространство имен — не изменяйтесь MonoTouch.Dialog на Dialog!

Распространенные ошибки компилятора

Ниже перечислены другие примеры распространенных ошибок, а также решение:

Ошибка CS0012: тип MonoTouch.UIKit.UIView определен в сборке, на которую не ссылается ссылка.

Исправление. Обычно это означает, что проект ссылается на компонент или пакет NuGet, который не был создан с помощью единого API. Необходимо удалить и повторно добавить все компоненты и пакеты NuGet. Если эта ошибка не устранена, внешняя библиотека пока не поддерживает единый API.

Ошибка MT0034: не удается включить как monotouch.dll, так и "Xamarin.iOS.dll" в одном проекте Xamarin.iOS : "Xamarin.iOS.dll" ссылается явно, а "monotouch.dll" ссылается на Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null.

Исправление. Удалите компонент, вызывающий эту ошибку, и повторно добавьте в проект.

Ошибка CS0234: тип или имя пространства имен Foundation не существует в пространстве имен MonoTouch. Отсутствует ссылка на сборку?

Исправление. Средство автоматической миграции в Visual Studio для Mac должно обновлять все MonoTouch.Foundation ссылки Foundationна, однако в некоторых случаях их необходимо обновить вручную. Аналогичные ошибки могут отображаться для других пространств имен, содержащихся ранее в MonoTouch, например UIKit.

Ошибка CS0266: неявно преобразовать тип double в System.float

Исправление: изменение типа и приведение nfloatв . Эта ошибка также может возникать для других типов с 64-разрядными эквивалентами (например nint, )

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

Ошибка CS0266: неявно преобразовать тип CoreGraphics.CGRect в System.Drawing.RectangleF. Существует явное преобразование (отсутствует приведение?)

Исправление: измените экземпляры на , на , SizeF на RectangleFCGSizeCGRectи PointFCGPointна . Пространство using System.Drawing; имен должно быть заменено using CoreGraphics; на (если оно еще не присутствует).

ошибка CS1502: лучший перегруженный метод для "CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])" имеет некоторые недопустимые аргументы

Исправление. Измените тип массива на nfloat[] и явно приведение Math.PI.

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

Ошибка CS0115: "WordsTableSource.RowsInSection(UIKit.UITableView, int)" помечается как переопределение, но подходящий метод не найден для переопределения.

Исправление. Измените возвращаемое значение и типы nintпараметров на . Обычно это происходит в переопределениях методов, таких как UITableViewSource, в том числе RowsInSection, , NumberOfSections, GetHeightForRowTitleForHeaderи GetViewForHeaderт. д.

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 "Видео Параметры" на WeakVideoSettings.
  • Измените значение PopViewControllerAnimated PopViewControllerна .
  • Измените coreGraphics "CGBitmapContext.SetRGBFillColor" на SetFillColor.

Ошибка CS0546: не удается переопределить, так как "MapKit.MKAnnotation.Coordinate" не имеет переопределенного метода доступа к набору (CS0546)

При создании пользовательской заметки путем подкласса MKAnnotation поле координат не имеет метода задания, а только метод получения.

Исправление

  • Добавление поля для отслеживания координаты
  • возвращает это поле в методе получения свойства Координата
  • Переопределите метод SetCoordinate и задайте поле
  • Вызов 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);
    }
}