Xamarin.Forms 繫結原生程式庫

吳宗彥(Cliff) 2022/01/05 10:12:25
1525

C:\Projects\digicy_api\AndroidAAR\MagicTool\build\outputs\aar

 

 

1. Android 繫結

 

1.1

Android Archive (.AAR)是 Android 程式庫的檔案格式。 以.AAR 檔案是包含下列各項的 .ZIP 封存:

.已編譯的 JAVA 程式碼

.資源識別碼

.資源

.中繼資料 (例如,活動聲明、許可權)

 

 

 

1.2用Android Stdio建立AAR

 

1.3 增加三個方法

回傳字串

陣列加總

文字轉成base64

  public String GetString() {
        return "Hello Xamarin!";
    }

    // 會傳陣列加總
    public int MathIntAdditionWithIntArray(int[] intArray) {
        int sum = 0;
        for (int i : intArray) {
            sum += i;
        }
        return sum;
    }

    // 回傳base64
   public String StringToBase64WithStr(String str){

       byte[] bdata = str.getBytes(StandardCharsets.UTF_8);
       String b64 = Base64.encodeToString(bdata, Base64.DEFAULT);
       return  b64;
   }

 

1.4 編譯出AAR

到MagicTool\build\outputs\aar 找尋編譯出的AAR檔

1.5  新增Android繫結程式庫,將建立的aar放入jar資料夾中

1.6 Android專案加入繫結程式庫參考

 

1.7 Xamarin.Forms DependencyService 

    public interface IExtensionService
    {
        string FunctionGetString();

        int SumArray(int[] intArray);

        string ToBase64(string str);
    }

 

1.8 Android實作介面

[assembly: Dependency(typeof(ExtensionService))]
namespace BindingNative.Droid
{
    public class ExtensionService : IExtensionService
    {
        public string FunctionGetString()
        {
            var magic = new MagicTool();

            return magic.String;
        }

        public int SumArray(int[] intArray)
        {
            var magic = new MagicTool();
            return magic.MathIntAdditionWithIntArray(intArray);
        }

        public string ToBase64(string str)
        {
            var magic = new MagicTool();
            return magic.StringToBase64WithStr(str);
        }
    }
}

2. iOS 繫結

2.1 建立原生程式庫 (Framework)

2.2 建立swift程式

import Foundation
@objc(MagicTool)
public class MagicTool:NSObject{
    
    // 回傳文字
    @objc
    public func GetString()->String{
        
        return "Hello Magic!";
    }
    
    // 陣列加總
    @objc
    public func MathIntAddition(intArray:[Int])->Int{
        
        var resp:Int = 0;
        for i in intArray
        {
            resp+=i;
        }
        return resp;
    }
    
    // 轉換成base64
    @objc
    public func StringToBase64(str:String)->String{
        
        let resp=Data(str.utf8).base64EncodedString();
        return resp;
    }
}

2.3 將編譯改為 Release

 

2.4 編譯

Product/Build For/Running  or command+ b 進行編譯

模擬器和any device都要,編譯後會產生

Release-iphoneos Release-iphonesimulator

 

兩個資料夾,並將資料夾放在同個路徑

2.5 建立command指令 (也可以在終端機下指令)

2.5.1 合併檔案Release-iphoneos  和  Release-iphonesimulator

FrameworkProjectName=framework名稱;

Echo ====== 合併Framework ======; 
		
cd $(dirname $0);
				
cp -R "Release-iphoneos" "Release-fat";
		
cp -R "Release-iphonesimulator/$FrameworkProjectName.framework/Modules/$FrameworkProjectName.swiftmodule/" "Release-fat/$FrameworkProjectName.framework/Modules/$FrameworkProjectName.swiftmodule/";
		
lipo -create -output "Release-fat/$FrameworkProjectName.framework/$FrameworkProjectName" "Release-iphoneos/$FrameworkProjectName.framework/$FrameworkProjectName" "Release-iphonesimulator/$FrameworkProjectName.framework/$FrameworkProjectName";
				
Echo ====== 合併結束======;
Echo ====== INFO=====;

2.5.2 匯出cs中繼層

Echo ====== 確認安裝sharpie=====;

sharpie -v;
		
echo =====產生中繼層======;
		
sharpie bind --sdk=iphoneos15.0 --output="XamarinApiDef" --namespace="Binding" --scope="Release-fat/$FrameworkProjectName.framework/Headers/" "Release-fat/$FrameworkProjectName.framework/Headers/$FrameworkProjectName-Swift.h";

 

 

 

2.6 新增專案選擇iOS 繫節程式庫

將編譯出的framework加入iOS 繫節程式庫

 

將ApiDefinitions.cs的內容改為上一步指令產生的中繼資料

 

namespace Binding
{
	// @interface MagicTool : NSObject
	[BaseType (typeof(NSObject))]
	interface MagicTool
	{
		// -(NSString * _Nonnull)GetString __attribute__((warn_unused_result("")));
		[Export ("GetString")]
		[Verify (MethodToProperty)]
		string String { get; }

		// -(NSInteger)MathIntAdditionWithIntArray:(NSArray<NSNumber *> * _Nonnull)intArray __attribute__((warn_unused_result("")));
		[Export ("MathIntAdditionWithIntArray:")]
		nint MathIntAdditionWithIntArray (NSNumber[] intArray);

		// -(NSString * _Nonnull)StringToBase64WithStr:(NSString * _Nonnull)str __attribute__((warn_unused_result("")));
		[Export ("StringToBase64WithStr:")]
		string StringToBase64WithStr (string str);
	}
}

2.7  Xamarin.iOS 專案加入繫結程式庫參考

 

2.8 Xamarin.iOS實作介面

[assembly: Dependency(typeof(ExtensionService))]
namespace BindingNative.iOS
{
    public class ExtensionService : IExtensionService
    {
        public string FunctionGetString()
        {

            var magic = new MagicTool();


            return magic.GetString;
        }

        public int SumArray(int[] intArray)
        {
            var magic = new MagicTool();


            var nsArray = new NSNumber[intArray.Length];
            for(int i = 0; i <= intArray.Length - 1; i++)
            {
                nsArray[i] =(NSNumber) intArray[i];
            }

            var sum = (int)magic.MathIntAdditionWithIntArray(nsArray);

            return sum;
        }

        public string ToBase64(string str)
        {
            var magic = new MagicTool();
            return magic.StringToBase64WithStr(str);
        }
    }
}

 

3. Xamarin.Foms專案

使用DependencyService

public IExtensionService extensionService =>DependencyService.Get<IExtensionService>();

呼叫DependencyService中的方法

 ShowText = extensionService.FunctionGetString();

            var intArray = new int[] { 1, 2, 3, 4, 5 };
            ShowNumberOfSum = extensionService.SumArray(intArray).ToString();

            ShowBase64 = extensionService.ToBase64(this.ShowText);

吳宗彥(Cliff)