Sugerencias para actualizar el código a Unified API

Al actualizar las soluciones anteriores de Xamarin a la API unificada, es posible que se produzcan los errores siguientes.

NSInvalidArgumentException no pudo encontrar el error del guión gráfico

Hay un error en la versión actual de Visual Studio para Mac que puede producirse después de usar la herramienta de migración automatizada para convertir el proyecto en las API unificadas. Después de la actualización, si recibe un mensaje de error en el formulario:

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

Puede hacer lo siguiente para resolver este problema, busque el siguiente archivo de destino de compilación:

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

En este archivo, debe encontrar la siguiente declaración de destino:

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

Y agregue el DependsOnTargets="_CollectBundleResources" atributo a él. Por ejemplo:

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

Guarde el archivo, reinicie Visual Studio para Mac y realice una limpieza y recompilación del proyecto. Xamarin debe publicar una corrección para este problema en breve.

Recomendaciones útiles

Después de usar la herramienta de migración, es posible que siga recibiendo algunos errores del compilador que requieren intervención manual. Algunos aspectos que pueden necesitar corregirse manualmente incluyen:

  • enumLa comparación de s puede requerir una (int) conversión.

  • NSDictionary.IntValue ahora devuelve un nint, hay un Int32Value que se puede usar en su lugar.

  • nfloat y nint los tipos no se pueden marcar const; static readonly nint es una alternativa razonable.

  • Los elementos que solían estar directamente en el MonoTouch. espacio de nombres ahora están generalmente en el ObjCRuntime. espacio de nombres (por ejemplo: MonoTouch.Constants.Version ahora ObjCRuntime.Constants.Versiones ).

  • El código que serializa los objetos puede interrumpirse al intentar serializar nint y nfloat tipos. Asegúrese de comprobar que el código de serialización funciona según lo previsto después de la migración.

  • A veces, la herramienta automatizada pierde el código dentro de #if #else las directivas del compilador condicional. En este caso, deberá realizar las correcciones manualmente (consulte los errores comunes a continuación).

  • Es posible que la herramienta de migración no corriga automáticamente los métodos exportados [Export] manualmente, por ejemplo, en este snippert de código, debe actualizar manualmente el tipo de valor devuelto a nfloat:

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • La API unificada no proporciona una conversión implícita entre NSDate y .NET DateTime porque no es una conversión sin pérdida. Para evitar errores relacionados con DateTimeKind.Unspecified la conversión de .NET DateTime a local o UTC antes de realizar la conversión a NSDate.

  • Objective-C Los métodos de categoría ahora se generan como métodos de extensión en la API unificada. Por ejemplo, el código que usó UIView.DrawString anteriormente ahora haría referencia NSString.DrawString a en la API unificada.

  • El código que usa las clases AVFoundation con VideoSettings debe cambiar para usar la WeakVideoSettings propiedad . Esto requiere un Dictionary, que está disponible como una propiedad en las clases de configuración, por ejemplo:

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • El constructor NSObject .ctor(IntPtr) se ha cambiado de público a protegido (para evitar un uso incorrecto).

  • NSAction se ha reemplazado por .NET Actionestándar. Algunos delegados simples (únicos parámetros) también se han reemplazado por Action<T>.

Por último, consulte las diferencias de LA API unificada clásica v para buscar cambios en las API del código. La búsqueda en esta página le ayudará a encontrar las API clásicas y a lo que se han actualizado.

Nota:

El MonoTouch.Dialog espacio de nombres sigue siendo el mismo después de la migración. Si el código usa MonoTouch.Dialog , debe seguir usando ese espacio de nombres: no cambie MonoTouch.Dialog a Dialog!

Errores comunes del compilador

A continuación se enumeran otros ejemplos de errores comunes, junto con la solución:

Error CS0012: El tipo "MonoTouch.UIKit.UIView" se define en un ensamblado al que no se hace referencia.

Corrección: normalmente significa que el proyecto hace referencia a un componente o paquete NuGet que no se ha compilado con la API unificada. Debe eliminar y volver a agregar todos los componentes y paquetes NuGet. Si esto no corrige el error, es posible que la biblioteca externa aún no admita la API unificada.

Error MT0034: No se puede incluir "monotouch.dll" y "Xamarin.iOS.dll" en el mismo proyecto de Xamarin.iOS: "Xamarin.iOS.dll" se hace referencia explícitamente, mientras que "monotouch.dll" hace referencia a "Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null".

Corrección: elimine el componente que está causando este error y vuelva a agregar al proyecto.

Error CS0234: El nombre de tipo o espacio de nombres "Foundation" no existe en el espacio de nombres "MonoTouch". ¿Falta una referencia de ensamblado?

Corrección: la herramienta de migración automatizada en Visual Studio para Mac debe actualizar todas las MonoTouch.Foundation referencias a Foundation, pero en algunos casos, deberá actualizarse manualmente. Pueden aparecer errores similares para los otros espacios de nombres contenidos anteriormente en MonoTouch, como UIKit.

Error CS0266: No se puede convertir implícitamente el tipo "double" en "System.float".

Corrección: cambie el tipo y convierta en nfloat. Este error también puede producirse para los otros tipos con equivalentes de 64 bits (como nint, ).

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

Error CS0266: No se puede convertir implícitamente el tipo "CoreGraphics.CGRect" a "System.Drawing.RectangleF". Existe una conversión explícita (compruebe si le falta una conversión)

Corrección: cambie las instancias a RectangleFCGRect, SizeF a CGSizey PointF a CGPoint. El espacio de nombres using System.Drawing; debe reemplazarse por using CoreGraphics; (si aún no está presente).

error CS1502: La mejor coincidencia de método sobrecargado para "CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])" tiene algunos argumentos no válidos

Corrección: cambie el tipo de matriz a nfloat[] y convierta Math.PIexplícitamente .

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

Error CS0115: "WordsTableSource.RowsInSection(UIKit.UITableView, int)" está marcado como invalidación, pero no se encontró ningún método adecuado para invalidar

Corrección: cambie el valor devuelto y los tipos de parámetro a nint. Esto suele ocurrir en invalidaciones de método como las UITableViewSourcede , incluidos RowsInSection, NumberOfSections, GetHeightForRow, TitleForHeader, , GetViewForHeaderetc.

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

Error CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView): el tipo de valor devuelto debe ser "System.nint" para que coincida con el miembro invalidado. UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)

Corrección: cuando se cambia el tipo de valor devuelto a nint, convierta el valor devuelto en nint.

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

Error CS1061: El tipo "CoreGraphics.CGPath" no contiene una definición para "AddElipseInRect".

Corrección: Corrija la ortografía a AddEllipseInRect. Otros cambios de nombre incluyen:

  • Cambie "Color.Negro" a NSColor.Black.
  • Cambie MapKit "AddAnnotation" a AddAnnotations.
  • Cambie AVFoundation "DataUsingEncoding" a Encode.
  • Cambie AVFoundation "AVMetadataObject.TypeQRCode" a AVMetadataObjectType.QRCode.
  • Cambie AVFoundation "Video Configuración" a WeakVideoSettings.
  • Cambie PopViewControllerAnimated a PopViewController.
  • Cambie CoreGraphics 'CGBitmapContext.SetRGBFillColor' a SetFillColor.

Error CS0546: no se puede invalidar porque "MapKit.MKAnnotation.Coordinate" no tiene un descriptor de acceso set reemplazable (CS0546)

Al crear una anotación personalizada mediante subclases MKAnnotation, el campo Coordenada no tiene establecedor, solo un captador.

La solución

  • Agregar un campo para realizar un seguimiento de la coordenada
  • devuelve este campo en el captador de la propiedad Coordinate.
  • Invalide el método SetCoordinate y establezca el campo.
  • Llame a SetCoordinate en el ctor con el parámetro de coordenada pasado.

Debería tener un aspecto similar al siguiente:

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);
    }
}