Tips untuk Memperbarui Kode ke API Terpadu
Saat memperbarui solusi Xamarin yang lebih lama ke API Terpadu, kesalahan berikut mungkin terjadi.
NSInvalidArgumentException Tidak Dapat Menemukan Kesalahan Papan Cerita
Ada bug di versi Visual Studio untuk Mac saat ini yang dapat terjadi setelah menggunakan alat migrasi otomatis untuk mengonversi proyek Anda ke API Terpadu. Setelah pembaruan, jika Anda mendapatkan pesan kesalahan dalam formulir:
Objective-C exception thrown. Name: NSInvalidArgumentException Reason: Could not find a storyboard named 'xxx' in bundle NSBundle...
Anda dapat melakukan hal berikut untuk menyelesaikan masalah ini, menemukan file target build berikut:
/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/2.1/Xamarin.iOS.Common.targets
Dalam file ini Anda perlu menemukan deklarasi target berikut:
<Target Name="_CopyContentToBundle"
Inputs = "@(_BundleResourceWithLogicalName)"
Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >
Dan tambahkan atribut ke DependsOnTargets="_CollectBundleResources"
dalamnya. Seperti ini:
<Target Name="_CopyContentToBundle"
DependsOnTargets="_CollectBundleResources"
Inputs = "@(_BundleResourceWithLogicalName)"
Outputs = "@(_BundleResourceWithLogicalName -> '$(_AppBundlePath)%(LogicalName)')" >
Simpan file, boot ulang Visual Studio untuk Mac, dan lakukan pembersihan & pembangunan ulang proyek Anda. Perbaikan untuk masalah ini harus segera dirilis oleh Xamarin.
Tips Berguna
Setelah menggunakan alat migrasi, Anda mungkin masih mendapatkan beberapa kesalahan kompilator yang memerlukan intervensi manual. Beberapa hal yang mungkin perlu diperbaiki secara manual meliputi:
Membandingkan
enum
mungkin memerlukan pemeran(int)
.NSDictionary.IntValue
sekarang mengembalikannint
, ada yangInt32Value
dapat digunakan sebagai gantinya.nfloat
jenis dannint
tidak dapat ditandaiconst
;static readonly nint
adalah alternatif yang wajar.Hal-hal yang dulunya langsung di
MonoTouch.
namespace sekarang umumnya berada diObjCRuntime.
namespace (misalnya:MonoTouch.Constants.Version
sekarangObjCRuntime.Constants.Version
).Kode yang menserialisasikan objek dapat rusak saat mencoba membuat serialisasi
nint
dannfloat
jenis. Pastikan untuk memeriksa kode serialisasi Anda berfungsi seperti yang diharapkan setelah migrasi.Terkadang alat otomatis melewatkan kode di dalam
#if #else
arahan kompilator bersyar. Dalam hal ini, Anda harus melakukan perbaikan secara manual (lihat kesalahan umum di bawah).Metode yang diekspor secara manual menggunakan
[Export]
mungkin tidak secara otomatis diperbaiki oleh alat migrasi, misalnya dalam snippert kode ini, Anda harus memperbarui jenis pengembalian secara manual kenfloat
:[Export("tableView:heightForRowAtIndexPath:")] public nfloat HeightForRow(UITableView tableView, NSIndexPath indexPath)
API Terpadu tidak menyediakan konversi implisit antara NSDate dan .NET DateTime karena bukan konversi tanpa kerugian. Untuk mencegah kesalahan yang terkait dengan
DateTimeKind.Unspecified
konversi .NETDateTime
ke lokal atau UTC sebelum mentransmisikan keNSDate
.Objective-C metode kategori sekarang dihasilkan sebagai metode ekstensi di API Terpadu. Misalnya, kode yang sebelumnya digunakan
UIView.DrawString
sekarang akan dirujukNSString.DrawString
di API Terpadu.Kode menggunakan kelas AVFoundation dengan
VideoSettings
harus berubah untuk menggunakanWeakVideoSettings
properti . Ini memerlukanDictionary
, yang tersedia sebagai properti pada kelas pengaturan, misalnya:vidrec.WeakVideoSettings = new AVVideoSettings() { ... }.Dictionary;
Konstruktor NSObject
.ctor(IntPtr)
telah diubah dari publik ke dilindungi (untuk mencegah penggunaan yang tidak tepat).NSAction
telah diganti dengan standar .NETAction
. Beberapa delegasi sederhana (parameter tunggal) juga telah diganti denganAction<T>
.
Terakhir, lihat perbedaan CLASSIC v Unified API untuk mencari perubahan pada API dalam kode Anda. Mencari halaman ini akan membantu menemukan API Klasik dan apa yang telah diperbarui.
Catatan
Namespace MonoTouch.Dialog
tetap sama setelah migrasi. Jika kode Anda menggunakan MonoTouch.Dialog, Anda harus terus menggunakan namespace layanan tersebut - jangan ubah MonoTouch.Dialog
menjadi Dialog
!
Kesalahan Kompilator Umum
Contoh lain dari kesalahan umum tercantum di bawah ini, bersama dengan solusinya:
Kesalahan CS0012: Jenis 'MonoTouch.UIKit.UIView' didefinisikan dalam rakitan yang tidak dirujuk.
Perbaikan: Ini biasanya berarti proyek mereferensikan komponen atau paket NuGet yang belum dibangun dengan API Terpadu. Anda harus menghapus dan menambahkan kembali semua komponen dan paket NuGet. Jika ini tidak memperbaiki kesalahan, pustaka eksternal mungkin belum mendukung API Terpadu.
Kesalahan MT0034: Tidak dapat menyertakan 'monotouch.dll' dan 'Xamarin.iOS.dll' dalam proyek Xamarin.iOS yang sama - 'Xamarin.iOS.dll' dirujuk secara eksplisit, sementara 'monotouch.dll' dirujuk oleh 'Xamarin.Mobile, Version=0.6.3.0, Culture=netral, PublicKeyToken=null'.
Perbaikan: Hapus komponen yang menyebabkan kesalahan ini dan tambahkan kembali ke proyek.
Kesalahan CS0234: Tipe atau nama namespace 'Foundation' tidak ada di namespace 'MonoTouch'. Apakah Anda kehilangan referensi perakitan?
Perbaikan: Alat migrasi otomatis di Visual Studio untuk Mac harus memperbarui semua MonoTouch.Foundation
referensi ke Foundation
, namun dalam beberapa instans ini perlu diperbarui secara manual. Kesalahan serupa mungkin muncul untuk namespace layanan lain yang sebelumnya terkandung dalam MonoTouch
, seperti UIKit
.
Kesalahan CS0266: Tidak dapat mengonversi tipe 'ganda' secara implisit ke 'System.float'
Perbaikan: ubah jenis dan transmisi ke nfloat
. Kesalahan ini juga dapat terjadi untuk jenis lain dengan setara 64-bit (seperti nint
, )
nfloat scale = (nfloat)Math.Min(rect.Width, rect.Height);
Kesalahan CS0266: Tidak dapat mengonversi tipe 'CoreGraphics.CGRect' secara implisit ke 'System.Drawing.RectangleF'. Konversi eksplisit ada (apakah Anda kehilangan pemeran?)
Perbaikan: Ubah instans menjadi RectangleF
, ke , dan PointF
ke CGPoint
.CGSize
SizeF
CGRect
Namespace using System.Drawing;
harus diganti dengan using CoreGraphics;
(jika belum ada).
kesalahan CS1502: Metode kelebihan beban terbaik cocok untuk 'CoreGraphics.CGContext.SetLineDash(System.nfloat, System.nfloat[])' memiliki beberapa argumen yang tidak valid
Perbaikan: Ubah jenis array ke nfloat[]
dan secara eksplisit transmisi Math.PI
.
grphc.SetLineDash (0, new nfloat[] { 0, 3 * (nfloat)Math.PI });
Kesalahan CS0115: 'WordsTableSource.RowsInSection(UIKit.UITableView, int)' ditandai sebagai penimpaan tetapi tidak ada metode yang cocok yang ditemukan untuk menimpa
Perbaikan: Ubah nilai pengembalian dan jenis parameter menjadi nint
. Ini biasanya terjadi dalam penimpaan metode seperti pada UITableViewSource
, termasuk RowsInSection
, , NumberOfSections
GetHeightForRow
, TitleForHeader
, GetViewForHeader
, dll.
public override nint RowsInSection (UITableView tableview, nint section) {
Kesalahan CS0508: WordsTableSource.NumberOfSections(UIKit.UITableView)
: jenis pengembalian harus 'System.nint' agar sesuai dengan anggota yang ditimpa UIKit.UITableViewSource.NumberOfSections(UIKit.UITableView)
Perbaiki: Ketika jenis pengembalian diubah menjadi nint
, transmisikan nilai yang dikembalikan ke nint
.
public override nint NumberOfSections (UITableView tableView)
{
return (nint)navItems.Count;
}
Kesalahan CS1061: Ketik 'CoreGraphics.CGPath' tidak berisi definisi untuk 'AddElipseInRect'
Perbaikan: Perbaiki ejaan ke AddEllipseInRect
. Perubahan nama lainnya meliputi:
- Ubah 'Color.Black' menjadi
NSColor.Black
. - Ubah MapKit 'AddAnnotation' menjadi
AddAnnotations
. - Ubah AVFoundation 'DataUsingEncoding' menjadi
Encode
. - Ubah AVFoundation 'AVMetadataObject.TypeQRCode' menjadi
AVMetadataObjectType.QRCode
. - Ubah AVFoundation 'Video Pengaturan' menjadi
WeakVideoSettings
. - Ubah PopViewControllerAnimated menjadi
PopViewController
. - Ubah CoreGraphics 'CGBitmapContext.SetRGBFillColor' menjadi
SetFillColor
.
Kesalahan CS0546: tidak dapat mengambil alih karena 'MapKit.MKAnnotation.Coordinate' tidak memiliki aksesor set yang dapat diganti (CS0546)
Saat membuat anotasi kustom dengan subkelas MKAnnotation, bidang Koordinat tidak memiliki setter, hanya getter.
Perbaikan
- Menambahkan bidang untuk melacak koordinat
- kembalikan bidang ini di getter properti Koordinat
- Ambil alih metode SetCoordinate dan atur bidang Anda
- Panggil SetCoordinate di ctor Anda dengan parameter koordinat yang diteruskan
Tampilannya akan terlihat seperti berikut:
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);
}
}