MonoTouch綁定CocoaTouch類庫


綁定概述

在 Windows/Linux 平台上, .Net/Mono 可以通過平台調用 (P/Invoke) 技術調用本地類庫, 通過互操作 (Interop) 技術調用 COM 組件, 在 iOS 平台上, MonoTouch 也有類似的技術, 可以調用 iOS 的 CocoaTouch 類庫, 這種技術在 MonoTouch 叫做綁定 (Binding) , 整個 monotouch.dll 就是用綁定技術完成的。

互聯網上有很多熱心網友提供的 CacoaTouch 類庫, 如果想使用這些類庫, 完全用 C# 重寫是不可取的, 所以就要用到 MonoTouch 的綁定技術。

綁定技術聽起來高深, 其實仔細研究起來, 其實並不難。 接下來, 以 KKGridView 為例, 說明怎樣綁定 CocoaTouch 類庫項目。

准備 MonoTouch 綁定項目

新建一個名稱為 KKGridView 的空白解決方案, 作為工作區, 再新建一個綁定項目, 名稱為 Binding , 項目建好之后, 設置綁定項目的默認命名空間為 MonoTouch.KKGrid , 並設置項目的輸出為 KKGridView , 相關截圖如下:

clip_image001

綁定項目默認結構如下, 包含兩個文件: ApiDeginition.cs 和 StructsAndEnums.cs , 其中 ApiDefinition 用於綁定 CacoaTouch 類庫定義的 interface 、 delegate 與 protocol 及其成員, 而 StructsAndEnums 用於綁定 ApiDefinition 所需的結構、 枚舉以及其它。 這兩個文件的編譯方式是不同的, 所以對應的 C# 類型必須對號入座才行。

clip_image002

獲取 KKGridView 源代碼並編譯

KKGridView 在 GitHub 上的主頁是 https://github.com/kolinkrewinkel/KKGridView.git , 使用 git 可以輕松獲取其源代碼。 打開一個命令行窗口, 切換到綁定項目目錄, 輸入下面的命令:

git clone https://github.com/kolinkrewinkel/KKGridView.git

等命令行運行完畢, 源代碼就獲取好了, 接下來要編譯 KKGridView , 接着輸入下面的命令:

cd KKGridView
xcodebuild -project KKGridView.xcodeproj -target KKGridView -sdk iphonesimulator -configuration Release clean build
xcodebuild -project KKGridView.xcodeproj -target KKGridView -sdk iphoneos -configuration Release clean build
lipo -create -output libKKGridView.a build/Release-iphonesimulator/libKKGridView.a build/Release-iphoneos/libKKGridView.a

現在打開 MonoDevelop 將最終生成的 libKKGridView.a 添加到綁定項目 , 現在可以開始進行綁定了。

綁定 Objective-C 類型至 C#

綁定的語法定義為:

[BaseType(typeof(TypeBase))]
interface MyType [: Prodocol1, Protocol2] {
   IntPtr Constructor(string foo);
}

MyType 與 ObjC 的類型對應, TypeBase 與 ObjC 的基類對應, Protocol1 、 Prodocol2 與 ObjC 類型實現的協議對應。

interface

ObjC 的 interface 定義如下:

@interface KKGridView : UIScrollView
@end

對應的綁定語法如下:

[BaseType(typeof(UIScrollView))]
interface KKGridView {
}

protocol

ObjC 的 protocol 定義語法如下:

@protocol KKGridViewDataSource <NSObject>
@end

或者

@protocol KKGridViewDelegate <NSObject , UIScrollViewDelegate>
@end

ObjC 的 protocol 與 C# 的 interface 有些類似, 但是 protocol 中定義的方法有兩種, optional 和 required , 又有點兒像抽象類, MonoTouch 將其綁定為類, 並添加 ModelAttribute 標記, 對應的綁定語法分別為:

[Model, BaseType(typeof(NSObject))]
interface KKGridViewDataSource {
}

[Model, BaseType(typeof(UIScrollViewDelegate))]
interface KKGridViewDelegate {
}

instance method

實例方法綁定為對應的 C# 實例方法:

- (NSString *)gridView:(KKGridView *)gridView titleForHeaderInSection:(NSUInteger)section;
[Export("gridView:titleForHeaderInSection:")]
string GridViewTitleFoHeaderInSection(KKGridView gridView, uint section);

如果是 protocol 的 required 方法, 則在對應的 C# 方法上添加 Abstract 標記, 例如:

- (NSUInteger)gridView:(KKGridView *)gridView numberOfItemsInSection:(NSUInteger)section;
[Abstract, Export("gridView:numberOfItemsInSection:")]
uint GridViewNumberOfItemsInSection(KKGridView gridView, uint section);

class method

ObjC 中的 class method 與 C# 中的靜態方法概念一致, 因此綁定為 C# 的靜態方法, 例如:

+ (id)cellForGridView:(KKGridView *)gridView;
[Static, Export("cellForGridView:")]
KKGridViewCell CellFroGridView(KKGridView gridView);

property

ObjC 的屬性通常由 setPropertyName 、 propertyName 兩個方法組成, 綁定為 C# 的屬性:

@property (nonatomic) BOOL allowsMultipleSelection; 
[Export("allowsMultipleSelection")]
bool AllowsMultipleSelection { get; set; }

如果不是由默認的兩個方法組成, 例如:

@property (nonatomic, getter = isSelected) BOOL selected;

對應的綁定為:

[Export("selected")]
bool Selected { [Bind("isSelected")]get; set; }

enum

枚舉的綁定是最容易的, 不過要放在 enums.cs 文件中, 例如:

typedef enum {
   KKGridViewAnimationFade,
   KKGridViewAnimationResize,
   KKGridViewAnimationSlideLeft,
   KKGridViewAnimationSlideTop,
   KKGridViewAnimationSlideRight,
   KKGridViewAnimationSlideBottom,
   KKGridViewAnimationExplode,
   KKGridViewAnimationImplode,
   KKGridViewAnimationNone
} KKGridViewAnimation;
public enum KKGridViewAnimation {
   Fade,
   Resize,
   SlideLeft,
   SlideTop,
   SlideRight,
   SlideBottom,
   Explode,
   Implode,
   None
}

添加 Makefile

# 定義一些常量
PROJECT_ROOT=KKGridView
PROJECT=$(PROJECT_ROOT)/$(PROJECT_ROOT).xcodeproj
BUILD_ROOT=$(PROJECT_ROOT)/Build
TARGET=$(PROJECT_ROOT)
SDK=lib$(TARGET).a
BTOUCH=/Developer/MonoTouch/usr/bin/btouch
SMCS=/Developer/MonoTouch/usr/bin/smcs
XBUILD=/Developer/usr/bin/xcodebuild

# 從github獲取源代碼
$(PROJECT_ROOT):
   git clone https://github.com/kolinkrewinkel/$(PROJECT_ROOT).git
   cd $(PROJECT_ROOT) && git pull

# 編譯模擬器版本
simulator: $(PROJECT_ROOT)
   mkdir -p libs
   $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator -configuration Release clean build
   mv -f $(BUILD_ROOT)/Release-iphoneSimulator/lib$(TARGET).a ./libs/lib$(TARGET)-simulator.a

# 編譯設備版本
iphoneos: $(PROJECT_ROOT)
   mkdir -p libs
   $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -configuration Release clean build
   mv -f $(BUILD_ROOT)/Release-iphoneos/lib$(TARGET).a ./libs/lib$(TARGET)-iphoneos.a

# 講兩個版本合成為一個
sdk:
   lipo -create -output $(SDK) libs/lib$(TARGET)-simulator.a libs/lib$(TARGET)-iphoneos.a

# 編譯 MonoTouch 組件
asm:
   # 使用 btouch 編譯出的 dll 文件總是無法運行, 不知是怎么回事, 只能用 MonoDevelop 進行編譯, 所以把這里注釋掉了。
   #$(BTOUCH) -d=MONOTOUCH -out:bin/$(TARGET).dll api.cs -s:enum.cs --link-with=$(SDK),$(SDK)

# 清理
clean:
   rm -rf $(PROJECT_ROOT) libs ios *.a *.dll *.stamp

# 全部任務
all: clean simulator iphoneos sdk asm

綁定項目源代碼

KKGridView 的全部綁定源代碼放在 GitHub , 地址為 https://github.com/beginor/MonoTouch.KKGridView , 有興趣的可以圍觀。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM