Xamarin.iOS中引用第三方Objective-C的Class Library
-
Upload
shengwen-chiou -
Category
Software
-
view
331 -
download
0
Transcript of Xamarin.iOS中引用第三方Objective-C的Class Library
Xamarin.iOS中引用第三方Objective-C的 Class Library
HappyMan2015/02/03
目標• 在 Xamarin.iOS 中使用第三方套件,透過
在 Xcode中建立 Objective-C Class Library
• 以 AwesomeMenu套件為例https://github.com/levey/AwesomeMenu
步驟
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
建立 Static Library• 在 Xcode創建新專案,選擇 iOS ->
Framework & Library -> Cocoa Touch Static Library。在此命名為AwesomeMenu
專案結構
專案結構• AwesomeMenu檔案群
專案中的目錄結構• 在命令提示字元介面中以 Xcodebuild編譯這個專案
產生 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 **
產生 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 **
產生 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 **
產生 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 **
專案中的目錄結構• AwesomeMenu -> build• 我在名稱後綴加入 arm7 arm7s
arm64以利分辨
Static Library• 檔案來源: build -> Debug-
iphoneos_arm*• 重新命名: libAwesomeMenu.a– libAwesomeMenu_arm64.a– libAwesomeMenu_armv7s.a– libAwesomeMenu_armv7.a– libAwesomeMenu_simulator.a
• 轉放至專案資料夾: AwesomeMenu
合併為一• 使用 lipo指令將 .a檔案包成單一檔案• lipo -create -output AwesomeMenu.a
libAwesomeMenu-arm64.a libAwesomeMenu-armv7s.a libAwesomeMenu-armv7.a libAwesomeMenu-simulator.a
• 於是產生 AwesomeMenu.a
建立 Xamarin.iOS Binding Project• C# -> iOS -> Unified API -> iOS Binding Project
檔案結構 (前 )
加入 Static Library
加入 Static Library
加入 Static Library
檔案結構 (後 )
ShareCode.linkwith.cs• using System;
using ObjCRuntime;
[assembly: LinkWith (“AwesomeMenu.a”, LinkTarget.Arm64 | LinkTarget.ArmV7s | LinkTarget.ArmV7 | LinkTarget.Simulator, SmartLink = true, ForceLoad = true)]
使用 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
查看 Xcode SDK• sharpie xcode -sdks– macosx10.8– macosx10.9– iphoneos7.1– iphonesimulator7.1– macosx10.10– iphoneos8.2– iphonesimulator8.2– iphoneos8.1– iphonesimulator8.1
轉換 *.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.
生成 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
刪除轉換多餘的程式碼• // @protocol
AwesomeMenuItemDelegate <NSObject> [Protocol, Model][BaseType (typeof (NSObject))] interface AwesomeMenuItemDelegate { }
• // @protocol AwesomeMenuDelegate <NSObject> [Protocol, Model][BaseType (typeof (NSObject))] interface AwesomeMenuDelegate { }
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 {
…後面還有
編譯釋出
產生 BindingProjectTest2.dll• BindingAwesomeMenu ▸
BindingAwesomeMenu bin Release▸ ▸ ▸AwesomeMenu.dll
建立 Xamarin.iOS Project
引用 BindingAwesomeMenu產生的檔• Project -> Edit References
引用 BindingAwesomeMenu產生的檔• Browse -> BindingAwesomeMenu ▸
BindingAwesomeMenu bin Release ▸ ▸ ▸AwesomeMenu.dll
匯入第三方套件的圖片
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);
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);}
編譯執行• iOS Simulator (iPhone 6)
OK• iOS Device (iPhone 6)
Failed!!Xamarin bug…
後續• 實作 C#的 Strong Delegate或Weak
Delegate
結論• 使用 Objective-C Library轉到 C#
Library角色有三個專案,範例:– ShareCode (Xcode)– BindingProjectTest (Xamarin)– BindingSample (Xamarin)
• https://github.com/happymanx/Binding-Library-from-ObjC-to-CSharp.git
參考• [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/