Conseils pour la mise à jour du code vers l’API unifiée
Lors de la mise à jour d’anciennes solutions Xamarin vers l’API unifiée, les erreurs suivantes peuvent être rencontrées.
NSInvalidArgumentException impossible de trouver une erreur de storyboard
Il existe un bogue dans la version actuelle de Visual Studio pour Mac qui peut se produire après l’utilisation de l’outil de migration automatisée pour convertir votre projet en API unifiées. Après la mise à jour, si vous recevez un message d’erreur dans le formulaire :
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Could not find a storyboard named 'xxx' in bundle NSBundle...
Pour résoudre ce problème, recherchez le fichier cible de build suivant :
/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/2.1/Xamarin.iOS.Common.targets
Dans ce fichier, vous devez trouver la déclaration cible suivante :
<Target Name="_CopyContentToBundle"
Inputs = "@(_BundleResourceWithLogicalName)"
Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >
Ajoutez l’attribut DependsOnTargets="_CollectBundleResources"
à celui-ci. Comme ceci :
<Target Name="_CopyContentToBundle"
DependsOnTargets="_CollectBundleResources"
Inputs = "@(_BundleResourceWithLogicalName)"
Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >
Enregistrez le fichier, redémarrez Visual Studio pour Mac et effectuez une propre et régénérez votre projet. Un correctif pour ce problème doit être publié par Xamarin sous peu.
Astuces utiles
Après avoir utilisé l’outil de migration, vous pouvez toujours obtenir certaines erreurs du compilateur nécessitant une intervention manuelle. Voici quelques éléments qui doivent être corrigés manuellement :
La comparaison
enum
de s peut nécessiter un(int)
cast.NSDictionary.IntValue
retourne maintenant unnint
, il existe unInt32Value
qui peut être utilisé à la place.nfloat
etnint
les types ne peuvent pas être marquésconst
;static readonly nint
est une alternative raisonnable.Les éléments utilisés directement dans l’espace
MonoTouch.
de noms sont désormais généralement dans l’espaceObjCRuntime.
de noms (par exemple :MonoTouch.Constants.Version
est maintenantObjCRuntime.Constants.Version
).Le code qui sérialise les objets peut s’interrompre lors de la tentative de sérialisation
nint
etnfloat
de types. Veillez à case activée votre code de sérialisation fonctionne comme prévu après la migration.Parfois, l’outil automatisé manque du code dans
#if #else
les directives du compilateur conditionnel. Dans ce cas, vous devez effectuer les correctifs manuellement (voir les erreurs courantes ci-dessous).Les méthodes exportées manuellement à l’aide
[Export]
de l’outil de migration peuvent ne pas être corrigées automatiquement par l’outil de migration, par exemple dans ce code snippert, vous devez mettre à jour manuellement le type de retour versnfloat
:[Export("tableView:heightForRowAtIndexPath:")] public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
L’API unifiée ne fournit pas de conversion implicite entre NSDate et .NET DateTime, car elle n’est pas une conversion sans perte. Pour éviter les erreurs liées à
DateTimeKind.Unspecified
la conversion du .NETDateTime
en local ou UTC avant la conversion enNSDate
.Objective-C Les méthodes de catégorie sont désormais générées en tant que méthodes d’extension dans l’API unifiée. Par exemple, le code utilisé précédemment
UIView.DrawString
référenceraitNSString.DrawString
désormais dans l’API unifiée.Le code utilisant des classes AVFoundation avec
VideoSettings
doit changer pour utiliser laWeakVideoSettings
propriété. Cela nécessite unDictionary
, qui est disponible en tant que propriété sur les classes de paramètres, par exemple :vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
Le constructeur NSObject
.ctor(IntPtr)
a été remplacé par public par protégé (pour empêcher une utilisation incorrecte).NSAction
a été remplacé par le .NETAction
standard . Certains délégués simples (paramètre unique) ont également été remplacés parAction<T>
.
Pour finir, reportez-vous aux différences d’API unifiée v Classic pour rechercher les modifications apportées aux API dans votre code. La recherche de cette page vous aidera à trouver les API classiques et à ce qu’elles ont été mises à jour.
Remarque
L’espace MonoTouch.Dialog
de noms reste le même après la migration. Si votre code utilise MonoTouch.Dialog, vous devez continuer à utiliser cet espace de noms - ne changez MonoTouch.Dialog
pas à Dialog
!
Erreurs courantes du compilateur
D’autres exemples d’erreurs courantes sont répertoriés ci-dessous, ainsi que la solution :
Erreur CS0012 : Le type « MonoTouch.UIKit.UIView » est défini dans un assembly qui n’est pas référencé.
Correctif : cela signifie généralement que le projet fait référence à un composant ou un package NuGet qui n’a pas été généré avec l’API unifiée. Vous devez supprimer et rajouter tous les composants et packages NuGet. Si cela ne résout pas l’erreur, la bibliothèque externe peut ne pas encore prendre en charge l’API unifiée.
Erreur MT0034 : Impossible d’inclure « monotouch.dll » et « Xamarin.iOS.dll » dans le même projet Xamarin.iOS : « Xamarin.iOS.dll » est référencé explicitement, tandis que « monotouch.dll » est référencé par « Xamarin.Mobile, Version=0.6.3.0, Culture=neutral, PublicKeyToken=null ».
Correctif : supprimez le composant qui provoque cette erreur et réinscrire le projet.
Erreur CS0234 : Le type ou le nom de l’espace de noms « Foundation » n’existe pas dans l’espace de noms « MonoTouch ». Vérifiez qu'il ne manque aucune référence d'assembly.
Correctif : L’outil de migration automatisée dans Visual Studio pour Mac doit mettre à jour toutes les MonoTouch.Foundation
références, Foundation
mais dans certains cas, ces derniers devront être mis à jour manuellement. Des erreurs similaires peuvent apparaître pour les autres espaces de noms précédemment contenus dans MonoTouch
, par UIKit
exemple .
Erreur CS0266 : Impossible de convertir implicitement le type 'double' en 'System.float'
Correctif : modifier le type et effectuer un cast sur nfloat
. Cette erreur peut également se produire pour les autres types avec des équivalents 64 bits (par nint
exemple, , )
nfloat scale = (nfloat)Math.Min(rect.Width, rect.Height);
Erreur CS0266 : Impossible de convertir implicitement le type « CoreGraphics.CGRect » en « System.Drawing.RectangleF ». Une conversion explicite existe (un cast est-il manquant ?)
Correctif : remplacez les instances RectangleF
CGRect
par , SizeF
par CGSize
et PointF
par CGPoint
. L’espace de noms using System.Drawing;
doit être remplacé using CoreGraphics;
par (s’il n’est pas déjà présent).
erreur CS1502 : La meilleure correspondance de méthode surchargée pour « CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[]) » contient certains arguments non valides
Correctif : Modifiez le type de tableau en nfloat[]
cas de conversion Math.PI
explicite et explicite.
grphc.SetLineDash (0, new nfloat[] { 0, 3 * (nfloat)Math.PI });
Erreur CS0115 : « WordsTableSource.RowsInSection(UIKit.UITableView, int) » est marquée comme remplacement, mais aucune méthode appropriée n’est trouvée pour remplacer
Correctif : remplacez la valeur de retour et les types de nint
paramètres par . Cela se produit généralement dans les remplacements de méthode tels que ceux sur UITableViewSource
, y compris RowsInSection
, NumberOfSections
, GetHeightForRow
, TitleForHeader
, GetViewForHeader
etc.
public override nint RowsInSection (UITableView tableview, nint section) {
Erreur CS0508 : : WordsTableSource.NumberOfSections(UIKit.UITableView)
le type de retour doit être « System.nint » pour correspondre au membre substitué UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)
Correction : Lorsque le type de retour est modifié nint
, convertissez la valeur de retour en nint
.
public override nint NumberOfSections (UITableView tableView)
{
return (nint)navItems.Count;
}
Erreur CS1061 : Le type « CoreGraphics.CGPath » ne contient pas de définition pour « AddElipseInRect »
Correctif : Correction de l’orthographe à AddEllipseInRect
. Les autres modifications de nom sont les suivantes :
- Remplacez « Color.Black » par
NSColor.Black
. - Remplacez MapKit « AddAnnotation » par
AddAnnotations
. - Remplacez AVFoundation « DataUsingEncoding » par
Encode
. - Remplacez AVFoundation « AVMetadataObject.TypeQRCode » par
AVMetadataObjectType.QRCode
. - Remplacez AVFoundation « Video Paramètres » par
WeakVideoSettings
. - Remplacez PopViewControllerAnimated par
PopViewController
. - Remplacez CoreGraphics « CGBitmapContext.SetRGBFillColor » par
SetFillColor
.
Erreur CS0546 : impossible de remplacer, car « MapKit.MKAnnotation.Coordinate » n’a pas d’accesseur set substituable (CS0546)
Lors de la création d’une annotation personnalisée en sous-classe MKAnnotation, le champ De coordonnées n’a pas de setter, seul un getter.
Correctif
- Ajouter un champ pour effectuer le suivi de la coordonnée
- renvoyer ce champ dans le getter de la propriété Coordinate
- Remplacer la méthode SetCoordinate et définir votre champ
- Appeler SetCoordinate dans votre ctor avec le paramètre de coordonnées transmis
Celui-ci doit se présenter comme suit :
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);
}
}