Bağlamalara Objective-C Genel Bakış

Bağlama işleminin nasıl çalıştığına ilişkin ayrıntılar

Xamarin ile kullanmak üzere bir Objective-C kitaplığı bağlama üç adımdan oluşur:

  1. Yerel API'nin .NET'te nasıl kullanıma sunulduğu ve temel Objective-Calınan ile nasıl eşlendiğinden söz etmek için bir C# "API tanımı" yazın. Bu, ve gibi interface standart C# yapıları ve çeşitli bağlama öznitelikleri kullanılarak yapılır (bu basit örneğe bakın).

  2. C# dilinde "API tanımını" yazdıktan sonra, "bağlama" derlemesi oluşturmak için derlersiniz. Bu işlem komut satırında veya Mac için Visual Studio veya Visual Studio'da bağlama projesi kullanılarak yapılabilir.

  3. Bu "bağlama" derlemesi daha sonra Xamarin uygulama projenize eklenir, böylece tanımladığınız API'yi kullanarak yerel işlevselliğe erişebilirsiniz. Bağlama projesi, uygulama projelerinizden tamamen ayrıdır.

    Not

    1. Adım, Objective Sharpie'nin yardımıyla otomatikleştirilebilir. API'yi Objective-C inceler ve önerilen bir C# "API tanımı" oluşturur. Objective Sharpie tarafından oluşturulan dosyaları özelleştirebilir ve bağlama derlemenizi oluşturmak için bağlama projesinde (veya komut satırında) kullanabilirsiniz. Objective Sharpie bağlamaları tek başına oluşturmaz, yalnızca daha büyük sürecin isteğe bağlı bir parçasıdır.

Bağlamalarınızı yazmanıza yardımcı olacak şekilde nasıl çalıştığına ilişkin daha fazla teknik ayrıntı da okuyabilirsiniz.

Komut Satırı Bağlamaları

Bağlamaları doğrudan oluşturmak için Xamarin.iOS için (veya bmac-native Xamarin.Mac kullanıyorsanız) kullanabilirsinizbtouch-native. El ile oluşturduğunuz C# API tanımlarını komut satırı aracına (iOS bmac-native veya Mac için) geçirerek (btouch-nativeveya Objective Sharpie kullanarak) çalışır.

Bu araçları çağırmak için genel söz dizimi şunlardır:

# Use this for Xamarin.iOS:
bash$ /Developer/MonoTouch/usr/bin/btouch-native -e cocos2d.cs -s:enums.cs -x:extensions.cs
# Use this for Xamarin.Mac:
bash$ bmac-native -e cocos2d.cs -s:enums.cs -x:extensions.cs

Yukarıdaki komut dosyayı cocos2d.dll geçerli dizinde oluşturur ve projenizde kullanabileceğiniz tam olarak bağlı kitaplığı içerir. Bu, Mac için Visual Studio bağlama projesini kullanıyorsanız bağlamalarınızı oluşturmak için kullandığı araçtır (aşağıda açıklanmıştır).

Projeyi Bağlama

Bağlama projesi Mac için Visual Studio veya Visual Studio'da oluşturulabilir (Visual Studio yalnızca iOS bağlamalarını destekler) ve bağlama için API tanımlarını düzenlemeyi ve derlemeyi kolaylaştırır (komut satırını kullanmak yerine).

Bağlama oluşturmak için bağlama projesi oluşturma ve kullanma hakkında bilgi edinmek için bu başlangıç kılavuzunu izleyin.

Objective Sharpie

Objective Sharpie, bağlama oluşturmanın ilk aşamalarında yardımcı olan ayrı bir komut satırı aracıdır. Tek başına bağlama oluşturmaz, bunun yerine hedef yerel kitaplık için BIR API tanımı oluşturmanın ilk adımını otomatikleştirir.

Yerel kitaplıkları, yerel çerçeveleri ve CocoaPod'ları bağlamalarda yerleşik olarak bulunabilecek API tanımlarında ayrıştırmayı öğrenmek için Objective Sharpie belgelerini okuyun.

Bağlama Nasıl Çalışır?

Yeni (daha önce ilişkisiz) Objective-C türleri el ile bağlamak için [Register] özniteliğini, [Export] özniteliğini ve el ile Objective-C seçici çağrısını birlikte kullanmak mümkündür.

İlk olarak, bağlamak istediğiniz türü bulun. Tartışma amacıyla (ve basitlik) için NSEnumerator türünü bağlayacağız (zaten Foundation.NSEnumerator'a bağlı olan türü; aşağıdaki uygulama yalnızca örnek amaçlar içindir).

İkincisi, C# türünü oluşturmamız gerekir. Bunu büyük olasılıkla bir ad alanına yerleştirmek isteriz; Objective-C ad alanlarını desteklemediğinden, Xamarin.iOS'un çalışma zamanına kaydedeceği tür adını değiştirmek için özniteliğini Objective-C kullanmamız [Register] gerekir. C# türünün Foundation.NSObject dosyasından da devralması gerekir:

namespace Example.Binding {
    [Register("NSEnumerator")]
    class NSEnumerator : NSObject
    {
        // see steps 3-5
    }
}

Üçüncüsü, belgeleri gözden geçirin Objective-C ve kullanmak istediğiniz her seçici için ObjCRuntime.Selector örnekleri oluşturun. Bunları sınıf gövdesine yerleştirin:

static Selector selInit       = new Selector("init");
static Selector selAllObjects = new Selector("allObjects");
static Selector selNextObject = new Selector("nextObject");

Dördüncüsü, türünüzün oluşturucular sağlaması gerekir. Oluşturucu çağrınızı temel sınıf oluşturucusunda zincirlemeniz gerekir . Öznitelikler, [Export] kodun belirtilen seçici adına sahip oluşturucuları çağırmasına izin verir Objective-C :

[Export("init")]
public NSEnumerator()
    : base(NSObjectFlag.Empty)
{
    Handle = Messaging.IntPtr_objc_msgSend(this.Handle, selInit.Handle);
}
// This constructor must be present so that Xamarin.iOS
// can create instances of your type from Objective-C code.
public NSEnumerator(IntPtr handle)
    : base(handle)
{
}

Beşinci olarak, Adım 3'te bildirilen seçicilerin her biri için yöntemler sağlayın. Bunlar, yerel nesnede seçiciyi çağırmak için kullanır objc_msgSend() . Runtime.GetNSObject() kullanarak bir IntPtr öğesini uygun şekilde yazılan NSObject (alt) bir türe dönüştürdüğünü unutmayın. Yönteminin koddan Objective-C çağrılabilmesini istiyorsanız üyenin sanal olması gerekir.

[Export("nextObject")]
public virtual NSObject NextObject()
{
    return Runtime.GetNSObject(
        Messaging.IntPtr_objc_msgSend(this.Handle, selNextObject.Handle));
}
// Note that for properties, [Export] goes on the get/set method:
public virtual NSArray AllObjects {
    [Export("allObjects")]
    get {
        return (NSArray) Runtime.GetNSObject(
            Messaging.IntPtr_objc_msgSend(this.Handle, selAllObjects.Handle));
    }
}

Hepsini bir araya getirmek:

using System;
using Foundation;
using ObjCRuntime;

namespace Example.Binding {
    [Register("NSEnumerator")]
    class NSEnumerator : NSObject
    {
        static Selector selInit       = new Selector("init");
        static Selector selAllObjects = new Selector("allObjects");
        static Selector selNextObject = new Selector("nextObject");

        [Export("init")]
        public NSEnumerator()
            : base(NSObjectFlag.Empty)
        {
            Handle = Messaging.IntPtr_objc_msgSend(this.Handle,
                selInit.Handle);
        }

        public NSEnumerator(IntPtr handle)
            : base(handle)
        {
        }

        [Export("nextObject")]
        public virtual NSObject NextObject()
        {
            return Runtime.GetNSObject(
                Messaging.IntPtr_objc_msgSend(this.Handle,
                    selNextObject.Handle));
        }

        // Note that for properties, [Export] goes on the get/set method:
        public virtual NSArray AllObjects {
            [Export("allObjects")]
            get {
                return (NSArray) Runtime.GetNSObject(
                    Messaging.IntPtr_objc_msgSend(this.Handle,
                        selAllObjects.Handle));
            }
        }
    }
}