xamarin.ios中引用第三方objective-c的class library

39
Xamarin.iOS 中中中中中中 Objective-C 中 Class Library HappyMan 2015/02/03

Upload: shengwen-chiou

Post on 15-Apr-2017

331 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Xamarin.iOS中引用第三方Objective-C的Class Library

Xamarin.iOS中引用第三方Objective-C的 Class Library

HappyMan2015/02/03

Page 2: Xamarin.iOS中引用第三方Objective-C的Class Library

目標• 在 Xamarin.iOS 中使用第三方套件,透過

在 Xcode中建立 Objective-C Class Library

• 以 AwesomeMenu套件為例https://github.com/levey/AwesomeMenu

Page 3: Xamarin.iOS中引用第三方Objective-C的Class Library

步驟

1. 在 Xcode 中建立 Static Library2. 匯入第三方套件檔案3. 編譯此 Static Library,使它能同時支援 iOS

Device 與 iOS simulator硬體架構4. 使用 Objective Sharpie Tool產生轉換

Objective-C到 C#的程式碼5. 在 Xamarin 中建立 iOS Binding Project6. 在 Xamarin中建立 iOS APP 專案,引用 iOS

Binding Project

Page 4: Xamarin.iOS中引用第三方Objective-C的Class Library

建立 Static Library• 在 Xcode創建新專案,選擇 iOS ->

Framework & Library -> Cocoa Touch Static Library。在此命名為AwesomeMenu

Page 5: Xamarin.iOS中引用第三方Objective-C的Class Library

專案結構

Page 6: Xamarin.iOS中引用第三方Objective-C的Class Library

專案結構• AwesomeMenu檔案群

Page 7: Xamarin.iOS中引用第三方Objective-C的Class Library

專案中的目錄結構• 在命令提示字元介面中以 Xcodebuild編譯這個專案

Page 8: Xamarin.iOS中引用第三方Objective-C的Class Library

產生 iOS Simulator用的檔案• xcodebuild -sdk iphonesimulator -configuration

Debug– Build settings from command line:– SDKROOT = iphonesimulator8.1– === BUILD TARGET AwesomeMenu OF PROJECT

AwesomeMenu WITH CONFIGURATION Debug ===– Check dependencies– Write auxiliary files– …– ** BUILD SUCCEEDED **

Page 9: Xamarin.iOS中引用第三方Objective-C的Class Library

產生 iOS Device 用的檔案armv7

• xcodebuild -sdk iphoneos -arch armv7 -configuration Debug– Build settings from command line:– ARCHS = armv7– SDKROOT = iphoneos8.1– === BUILD TARGET AwesomeMenu OF PROJECT

AwesomeMenu WITH CONFIGURATION Debug ===– Check dependencies– Write auxiliary files– ** BUILD SUCCEEDED **

Page 10: Xamarin.iOS中引用第三方Objective-C的Class Library

產生 iOS Device 用的檔案armv7s

• xcodebuild -sdk iphoneos -arch armv7s -configuration Debug– Build settings from command line:– ARCHS = armv7s– SDKROOT = iphoneos8.1– === BUILD TARGET AwesomeMenu OF PROJECT

AwesomeMenu WITH CONFIGURATION Debug ===– Check dependencies– Write auxiliary files– ** BUILD SUCCEEDED **

Page 11: Xamarin.iOS中引用第三方Objective-C的Class Library

產生 iOS Device 用的檔案arm64

• xcodebuild -sdk iphoneos -arch arm64 -configuration Debug– Build settings from command line:– ARCHS = arm64– SDKROOT = iphoneos8.1– === BUILD TARGET AwesomeMenu OF PROJECT

AwesomeMenu WITH CONFIGURATION Debug ===– Check dependencies– Write auxiliary files– ** BUILD SUCCEEDED **

Page 12: Xamarin.iOS中引用第三方Objective-C的Class Library

專案中的目錄結構• AwesomeMenu -> build• 我在名稱後綴加入 arm7 arm7s

arm64以利分辨

Page 13: Xamarin.iOS中引用第三方Objective-C的Class Library

Static Library• 檔案來源: build -> Debug-

iphoneos_arm*• 重新命名: libAwesomeMenu.a– libAwesomeMenu_arm64.a– libAwesomeMenu_armv7s.a– libAwesomeMenu_armv7.a– libAwesomeMenu_simulator.a

• 轉放至專案資料夾: AwesomeMenu

Page 14: Xamarin.iOS中引用第三方Objective-C的Class Library

合併為一• 使用 lipo指令將 .a檔案包成單一檔案• lipo -create -output AwesomeMenu.a

libAwesomeMenu-arm64.a libAwesomeMenu-armv7s.a libAwesomeMenu-armv7.a libAwesomeMenu-simulator.a

• 於是產生 AwesomeMenu.a

Page 15: Xamarin.iOS中引用第三方Objective-C的Class Library

建立 Xamarin.iOS Binding Project• C# -> iOS -> Unified API -> iOS Binding Project

Page 16: Xamarin.iOS中引用第三方Objective-C的Class Library

檔案結構 (前 )

Page 17: Xamarin.iOS中引用第三方Objective-C的Class Library

加入 Static Library

Page 18: Xamarin.iOS中引用第三方Objective-C的Class Library

加入 Static Library

Page 19: Xamarin.iOS中引用第三方Objective-C的Class Library

加入 Static Library

Page 20: Xamarin.iOS中引用第三方Objective-C的Class Library

檔案結構 (後 )

Page 21: Xamarin.iOS中引用第三方Objective-C的Class Library

ShareCode.linkwith.cs• using System;

using ObjCRuntime;

[assembly: LinkWith (“AwesomeMenu.a”, LinkTarget.Arm64 | LinkTarget.ArmV7s | LinkTarget.ArmV7 | LinkTarget.Simulator, SmartLink = true, ForceLoad = true)]

Page 22: Xamarin.iOS中引用第三方Objective-C的Class Library

使用 Objective Sharpie• Objective Sharpie is a command line

tool (provided by Xamarin) that can assist in creating the definitions required to bind a 3rd party Objective-C library to C#.

• 下載並安裝– http://files.xamarin.com/~abock/Objecti

veSharpie/ObjectiveSharpie-1.1.1.pkg

Page 23: Xamarin.iOS中引用第三方Objective-C的Class Library

查看 Xcode SDK• sharpie xcode -sdks– macosx10.8– macosx10.9– iphoneos7.1– iphonesimulator7.1– macosx10.10– iphoneos8.2– iphonesimulator8.2– iphoneos8.1– iphonesimulator8.1

Page 24: Xamarin.iOS中引用第三方Objective-C的Class Library

轉換 *.h• sharpie bind -output=AwesomeMenu -namespace=AwesomeMenu -

sdk=iphoneos8.2 *.h –unified• Compiler configuration:

– -isysroot /Applications/Xcode-Beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -miphoneos-version-min=8.2 -resource-dir /Library/Frameworks/ObjectiveSharpie.framework/Versions/1.1.1/clang-resources -arch armv7 -ObjC

– Parsing...– [ 0%] parsing /Users/jason/Xcode/AwesomeMenu/AwesomeMenu.h– [ 50%] parsing /Users/jason/Xcode/AwesomeMenu/AwesomeMenuItem.h– [100%] parsing complete– Binding...– [bind] generating AwesomeMenu.cs– Submitting usage data to Xamarin...– Submitted - thank you for helping to improve Objective Sharpie!– Done.

Page 25: Xamarin.iOS中引用第三方Objective-C的Class Library

生成 AwesomeMenu.cs• namespace AwesomeMenu {

// @interface AwesomeMenuItem : UIImageView[BaseType (typeof (UIImageView))]interface AwesomeMenuItem {// -(id)initWithImage:(UIImage *)img highlightedImage:(UIImage *)himg

ContentImage:(UIImage *)cimg highlightedContentImage:(UIImage *)hcimg;[Export

(“initWithImage:highlightedImage:ContentImage:highlightedContentImage:”)]IntPtr Constructor (UIImage img, UIImage himg, UIImage cimg, UIImage

hcimg);// @property (readonly, nonatomic, strong) UIImageView *

contentImageView;[Export (“contentImageView”, ArgumentSemantic.Retain)]UIImageView ContentImageView { get; }// @property (nonatomic) CGPoint startPoint;[Export (“startPoint”)]CGPoint StartPoint { get; set; }

…後面還有• 將它複製到ApiDefinition.cs

Page 26: Xamarin.iOS中引用第三方Objective-C的Class Library

刪除轉換多餘的程式碼• // @protocol

AwesomeMenuItemDelegate <NSObject> [Protocol, Model][BaseType (typeof (NSObject))] interface AwesomeMenuItemDelegate { }

• // @protocol AwesomeMenuDelegate <NSObject> [Protocol, Model][BaseType (typeof (NSObject))] interface AwesomeMenuDelegate { }

Page 27: Xamarin.iOS中引用第三方Objective-C的Class Library

ApiDefinition.cs• using System;

using System.Drawing;

using ObjCRuntime;using Foundation;using UIKit;

using CoreGraphics;

namespace AwesomeMenu {

// @interface AwesomeMenuItem : UIImageView[BaseType (typeof (UIImageView))]interface AwesomeMenuItem {

…後面還有

Page 28: Xamarin.iOS中引用第三方Objective-C的Class Library

編譯釋出

Page 29: Xamarin.iOS中引用第三方Objective-C的Class Library

產生 BindingProjectTest2.dll• BindingAwesomeMenu ▸

BindingAwesomeMenu bin Release▸ ▸ ▸AwesomeMenu.dll

Page 30: Xamarin.iOS中引用第三方Objective-C的Class Library

建立 Xamarin.iOS Project

Page 31: Xamarin.iOS中引用第三方Objective-C的Class Library

引用 BindingAwesomeMenu產生的檔• Project -> Edit References

Page 32: Xamarin.iOS中引用第三方Objective-C的Class Library

引用 BindingAwesomeMenu產生的檔• Browse -> BindingAwesomeMenu ▸

BindingAwesomeMenu bin Release ▸ ▸ ▸AwesomeMenu.dll

Page 33: Xamarin.iOS中引用第三方Objective-C的Class Library

匯入第三方套件的圖片

Page 34: Xamarin.iOS中引用第三方Objective-C的Class Library

AwesomeMenuProjectViewController.cs

• public override void ViewDidLoad (){

base.ViewDidLoad ();

UIImage storyMenuItemImage = UIImage.FromFile ("images/bg-menuitem.png");UIImage storyMenuItemImagePressed = UIImage.FromFile ("images/bg-menuitem-

highlighted.png");

UIImage starImage = UIImage.FromFile ("images/icon-star.png");

AwesomeMenu.AwesomeMenuItem starMenuItem1 = new AwesomeMenu.AwesomeMenuItem (storyMenuItemImage, storyMenuItemImagePressed, starImage, starImage);

AwesomeMenu.AwesomeMenuItem starMenuItem2 = new AwesomeMenu.AwesomeMenuItem (storyMenuItemImage, storyMenuItemImagePressed, starImage, starImage);

AwesomeMenu.AwesomeMenuItem starMenuItem3 = new AwesomeMenu.AwesomeMenuItem (storyMenuItemImage, storyMenuItemImagePressed, starImage, starImage);

AwesomeMenu.AwesomeMenuItem starMenuItem4 = new AwesomeMenu.AwesomeMenuItem (storyMenuItemImage, storyMenuItemImagePressed, starImage, starImage);

AwesomeMenu.AwesomeMenuItem starMenuItem5 = new AwesomeMenu.AwesomeMenuItem (storyMenuItemImage, storyMenuItemImagePressed, starImage, starImage);

Page 35: Xamarin.iOS中引用第三方Objective-C的Class Library

AwesomeMenuProjectViewController.cs

• AwesomeMenu.AwesomeMenuItem[] menus = new AwesomeMenu.AwesomeMenuItem[] {starMenuItem1,starMenuItem2,starMenuItem3,starMenuItem4,starMenuItem5} ;

AwesomeMenu.AwesomeMenuItem startItem = new AwesomeMenu.AwesomeMenuItem (UIImage.FromFile ("images/bg-addbutton.png"), UIImage.FromFile ("images/bg-addbutton-highlighted.png"), UIImage.FromFile ("images/icon-plus.png"), UIImage.FromFile ("images/icon-plus-highlighted.png") );

AwesomeMenu.AwesomeMenu menu = new AwesomeMenu.AwesomeMenu (View.Frame, startItem, menus);

menu.MenuWholeAngle = (float)-Math.PI/2;menu.FarRadius = 110.0f;menu.EndRadius = 100.0f;menu.NearRadius = 90.0f;menu.AnimationDuration = 0.3f;menu.StartPoint = new CoreGraphics.CGPoint (250.0f, 410.0f);

View.Add (menu);}

Page 36: Xamarin.iOS中引用第三方Objective-C的Class Library

編譯執行• iOS Simulator (iPhone 6)

OK• iOS Device (iPhone 6)

Failed!!Xamarin bug…

Page 37: Xamarin.iOS中引用第三方Objective-C的Class Library

後續• 實作 C#的 Strong Delegate或Weak

Delegate

Page 38: Xamarin.iOS中引用第三方Objective-C的Class Library

結論• 使用 Objective-C Library轉到 C#

Library角色有三個專案,範例:– ShareCode (Xcode)– BindingProjectTest (Xamarin)– BindingSample (Xamarin)

• https://github.com/happymanx/Binding-Library-from-ObjC-to-CSharp.git

Page 39: Xamarin.iOS中引用第三方Objective-C的Class Library

參考• [Xamarin.iOS] 如何引用 Objective-C 寫

的 Class Libraryhttp://www.dotblogs.com.tw/toysboy21/archive/2013/08/27/115697.aspx

• Xamarin - Walkthrough: Binding an Objective-C Libraryhttp://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/Walkthrough_Binding_objective-c_library/