Советы по обновлению кода в 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
преобразованием .NETDateTime
в локальный или UTC перед приведением вNSDate
.Objective-C Теперь методы категории создаются как методы расширения в едином API. Например, код, который ранее использовался
UIView.DrawString
, будет ссылатьсяNSString.DrawString
на единый API.Код, использующий классы AVFoundation,
VideoSettings
должен измениться для использованияWeakVideoSettings
свойства. Для этого требуетсяDictionary
, который доступен в качестве свойства в классах параметров, например:vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
Конструктор NSObject
.ctor(IntPtr)
был изменен с общедоступного на защищенный (чтобы предотвратить неправильное использование).NSAction
заменен стандартным .NETAction
. Некоторые простые делегаты (один параметр) также были заменены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
на RectangleF
CGSize
CGRect
и PointF
CGPoint
на . Пространство 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
, GetHeightForRow
TitleForHeader
и 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);
}
}