Bagikan melalui


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 enummungkin memerlukan pemeran (int) .

  • NSDictionary.IntValue sekarang mengembalikan nint, ada yang Int32Value dapat digunakan sebagai gantinya.

  • nfloat jenis dan nint tidak dapat ditandai const; static readonly nint adalah alternatif yang wajar.

  • Hal-hal yang dulunya langsung di MonoTouch. namespace sekarang umumnya berada di ObjCRuntime. namespace (misalnya: MonoTouch.Constants.Version sekarang ObjCRuntime.Constants.Version).

  • Kode yang menserialisasikan objek dapat rusak saat mencoba membuat serialisasi nint dan nfloat 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 ke nfloat:

    [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 .NET DateTime ke lokal atau UTC sebelum mentransmisikan ke NSDate.

  • Objective-C metode kategori sekarang dihasilkan sebagai metode ekstensi di API Terpadu. Misalnya, kode yang sebelumnya digunakan UIView.DrawString sekarang akan dirujuk NSString.DrawString di API Terpadu.

  • Kode menggunakan kelas AVFoundation dengan VideoSettings harus berubah untuk menggunakan WeakVideoSettings properti . Ini memerlukan Dictionary, 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 .NET Action. Beberapa delegasi sederhana (parameter tunggal) juga telah diganti dengan Action<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.CGSizeSizeFCGRect 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, , NumberOfSectionsGetHeightForRow, 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);
    }
}