Condividi tramite


Suggerimenti per l'aggiornamento del codice per l'API unificata

Quando si aggiornano le soluzioni Xamarin meno recenti all'API unificata, potrebbero verificarsi gli errori seguenti.

Errore NSInvalidArgumentException non è stato possibile trovare lo storyboard

È presente un bug nella versione corrente di Visual Studio per Mac che può verificarsi dopo l'uso dello strumento di migrazione automatizzato per convertire il progetto nelle API unificate. Dopo l'aggiornamento, se viene visualizzato un messaggio di errore nel formato :

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

Per risolvere questo problema, è possibile eseguire le operazioni seguenti, individuare il file di destinazione di compilazione seguente:

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

In questo file è necessario trovare la dichiarazione di destinazione seguente:

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

E aggiungervi l'attributo DependsOnTargets="_CollectBundleResources" . nel modo seguente:

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

Salvare il file, riavviare Visual Studio per Mac ed eseguire una pulizia e ricompilazione del progetto. Una correzione per questo problema dovrebbe essere rilasciata a breve da Xamarin.

Suggerimenti utili

Dopo aver usato lo strumento di migrazione, è comunque possibile che vengano visualizzati alcuni errori del compilatore che richiedono un intervento manuale. Alcuni elementi che potrebbero essere necessari per essere corretti manualmente includono:

  • Il confronto enumdi s potrebbe richiedere un (int) cast.

  • NSDictionary.IntValue restituisce ora un oggetto nint, che può Int32Value essere usato.

  • nfloat i tipi e nint non possono essere contrassegnati constcome ; static readonly nint è un'alternativa ragionevole.

  • Gli elementi usati per essere direttamente nello MonoTouch. spazio dei nomi sono in genere nello ObjCRuntime. spazio dei nomi (ad esempio, MonoTouch.Constants.Version è ora ObjCRuntime.Constants.Version).

  • Il codice che serializza gli oggetti può interrompere quando si tenta di serializzare nint e nfloat tipi. Assicurarsi di controllare che il codice di serializzazione funzioni come previsto dopo la migrazione.

  • A volte lo strumento automatizzato perde codice all'interno #if #else delle direttive del compilatore condizionale. In questo caso è necessario apportare manualmente le correzioni (vedere gli errori comuni riportati di seguito).

  • I metodi esportati manualmente che usano [Export] potrebbero non essere corretti automaticamente dallo strumento di migrazione, ad esempio in questo snippert di codice è necessario aggiornare manualmente il tipo restituito in nfloat:

    [Export("tableView:heightForRowAtIndexPath:")]
    public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
    
  • L'API unificata non fornisce una conversione implicita tra NSDate e .NET DateTime perché non è una conversione senza perdita di dati. Per evitare errori correlati alla DateTimeKind.Unspecified conversione di .NET DateTime in formato LOCALE o UTC prima del cast in NSDate.

  • Objective-C I metodi di categoria vengono ora generati come metodi di estensione nell'API unificata. Ad esempio, il codice usato UIView.DrawString in precedenza fa riferimento NSString.DrawString all'API unificata.

  • Il codice che usa le classi AVFoundation con VideoSettings deve cambiare per usare la WeakVideoSettings proprietà . È necessario un Dictionaryoggetto , disponibile come proprietà nelle classi di impostazioni, ad esempio:

    vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
    
  • Il costruttore NSObject .ctor(IntPtr) è stato modificato da pubblico a protetto (per evitare usi non appropriati).

  • NSAction è stato sostituito con .NET Actionstandard. Alcuni delegati semplici (singoli parametri) sono stati sostituiti anche con Action<T>.

Infine, fare riferimento alle differenze dell'API classica v Unified per cercare le modifiche apportate alle API nel codice. La ricerca in questa pagina consentirà di trovare le API classiche e le informazioni a cui sono state aggiornate.

Nota

Lo MonoTouch.Dialog spazio dei nomi rimane invariato dopo la migrazione. Se il codice usa MonoTouch.Dialog , è consigliabile continuare a usare tale spazio dei nomi, senza passare MonoTouch.Dialog a Dialog!

Errori comuni del compilatore

Di seguito sono elencati altri esempi di errori comuni, insieme alla soluzione:

Errore CS0012: il tipo 'MonoTouch.UIKit.UIView' è definito in un assembly a cui non viene fatto riferimento.

Correzione: in genere il progetto fa riferimento a un componente o a un pacchetto NuGet che non è stato compilato con l'API unificata. È consigliabile eliminare e riaggiungere tutti i componenti e i pacchetti NuGet. Se l'errore non viene risolto, la libreria esterna potrebbe non supportare ancora l'API unificata.

Errore MT0034: non è possibile includere 'monotouch.dll' e 'Xamarin.iOS.dll' nello stesso progetto Xamarin.iOS - 'Xamarin.iOS.dll' viene fatto riferimento in modo esplicito, mentre 'monotouch.dll' viene fatto riferimento da 'Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null'.

Correzione: eliminare il componente che causa questo errore e aggiungerlo nuovamente al progetto.

Errore CS0234: il tipo o il nome dello spazio dei nomi 'Foundation' non esiste nello spazio dei nomi 'MonoTouch'. Probabilmente manca un riferimento a un assembly.

Correzione: lo strumento di migrazione automatizzato in Visual Studio per Mac deve aggiornare tutti i MonoTouch.Foundation riferimenti a Foundation, tuttavia in alcuni casi è necessario aggiornarli manualmente. È possibile che vengano visualizzati errori simili per gli altri spazi dei nomi contenuti in precedenza in MonoTouch, ad esempio UIKit.

Errore CS0266: Impossibile convertire in modo implicito il tipo 'double' in 'System.float'

Correzione: modificare il tipo ed eseguire il cast in nfloat. Questo errore può verificarsi anche per gli altri tipi con equivalenti a 64 bit (ad esempio nint, )

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

Errore CS0266: impossibile convertire in modo implicito il tipo 'CoreGraphics.CGRect' in 'System.Drawing.RectangleF'. Esiste una conversione esplicita (probabilmente manca un cast).

Correzione: modificare le istanze in in RectangleFCGRect, SizeF in CGSizee PointF in CGPoint. Lo spazio dei nomi using System.Drawing; deve essere sostituito con using CoreGraphics; (se non è già presente).

errore CS1502: la corrispondenza migliore del metodo di overload per 'CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])' contiene alcuni argomenti non validi

Correzione: modificare il tipo di matrice in nfloat[] e eseguire il cast Math.PIesplicito di .

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

Errore CS0115: 'WordsTableSource.RowsInSection(UIKit.UITableView, int)' è contrassegnato come override ma non è stato trovato alcun metodo appropriato per eseguire l'override

Correzione: modificare il valore restituito e i tipi di parametro in nint. Questo problema si verifica in genere negli override dei metodi, ad esempio quelli in UITableViewSource, tra cui RowsInSection, TitleForHeaderNumberOfSectionsGetHeightForRow, GetViewForHeader, e così via.

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

Errore CS0508: : WordsTableSource.NumberOfSections(UIKit.UITableView)il tipo restituito deve essere 'System.nint' per trovare la corrispondenza del membro sottoposto a override UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)

Correzione: quando il tipo restituito viene modificato in nint, eseguire il cast del valore restituito in nint.

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

Errore CS1061: il tipo 'CoreGraphics.CGPath' non contiene una definizione per 'AddElipseInRect'

Correzione: correggere l'ortografia in AddEllipseInRect. Altre modifiche al nome includono:

  • Impostare 'Color.Black' su NSColor.Black.
  • Impostare MapKit 'AddAnnotation' su AddAnnotations.
  • Modificare AVFoundation 'DataUsingEncoding' in Encode.
  • Modificare AVFoundation 'AVMetadataObject.TypeQRCode' in AVMetadataObjectType.QRCode.
  • Impostare AVFoundation 'Video Impostazioni' su WeakVideoSettings.
  • Impostare PopViewControllerAnimated su PopViewController.
  • Modificare CoreGraphics 'CGBitmapContext.SetRGBFillColor' in SetFillColor.

Errore CS0546: impossibile eseguire l'override perché 'MapKit.MKAnnotation.Coordinate' non dispone di una funzione di accesso set sostituibile (CS0546)

Quando si crea un'annotazione personalizzata sottoclassando MKAnnotation, il campo Coordinate non ha setter, ma solo un getter.

Correzione

  • Aggiungere un campo per tenere traccia della coordinata
  • restituire questo campo nel getter della proprietà Coordinate
  • Eseguire l'override del metodo SetCoordinate e impostare il campo
  • Chiamare SetCoordinate nel ctor con il parametro di coordinate passato

La voce deve essere simile alla seguente:

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