使いにくく品質の不安定な MAC / Xcode / Swift を避け、安定したWindow / Visual Stduio (Xamarin もしくは MAUI) で開発できれば効率向上します。appleの基本APIクラスライブラリは、Xamarinソリューション下の project名_iOS の中で、C#インターフェイスで呼び出せるようになっています。(apple一辺倒の方はこれをあまり知らないようです)
しかし、Swiftサードパーティライブラリ はこれに含まれていません。これを解決する方法は Microsoftサイト 「iOS Swift ライブラリのバインド」 で説明されています。これを試してみました。結論としては、調査時間制限もあり上手くいきませんでした。どこまで何を確認したかの記録、ぜひ試したい方へのヒントになればと思います。海外含め「iOS Swift ライブラリのバインド」は情報がほとんどないのが実情でした。
1.記事iOS Swift ライブラリのバインドについて
記事は2、3年前に作られた記事のようですが、たまに更新されていたりします。現時点は ‘24.4月更新です。自動翻訳のせいで、Xcode の画面語句が日本語になってしまっていて難解さを増しています。Xamarinの後継MAUIについては取り立て説明はありませんでした。
2. 実施環境
Xcode15.2、Visual Stdiuo 2019 For Mac
3. 手順
iOSバインド記事メインページからリンクされている 「チュートリアル: iOS Swift ライブラリをバインドする」に従い進めます。ザックリとした手順は以下の通りです。
(1) Xcode にて サードパーティライブラリのframeworkプロジェクトを作成する。ここでTerm名はnoneにしないと後々ビルドでエラーがでます。
(2) 上記プロジェクトに、サードパーティライブラリを追加する。
(3) Geberal -> Framework and Liblaries にてサードパーティライブラリを”Do Not Embed” にします。
(4) BuildSetting -> All -> Build Options -> Allways Embed Swift Standard が no であることを確認。MS記事の bitcode は古い記述の模様。
(5) BuildSetting -> All -> Swift Compiler General -> General Header name が project名-swift.h であることを確認します。
(6)公開したいクラスとメソッド定義を新規Swiftコードfileで作成します。引数型はSwitfとc#の型の互換性を確認し記述します。
import Foundation
import UIKit
import サードパーティライブラリ名
import CoreLocation
@objc(プロジェクト名)
public class プロジェクト名 : NSObject {
@objc
public func サードパーティメソッド名( メソッド引数 )
{
サードパーティインスタンス.メソッド( 引数 )
return
}
}
( 7) メニュー Product -> Schema -> Edit Schema からダイアログを開き、Run > Build Configration でを release に変更します。
(8) MAC で、xodebuild コマンドを使ってビルドします。iOSシュミレータと実機用をビルドしxcframeworkに統合します。弊方は以下shスクリプトにまとめました。
#!/bin/sh
TARGET_IOS=16.2
TARGET_PRJ=プロジェクト名
xcodebuild -project $TARGET_PRJ.xcodeproj archive \
-scheme $TARGET_PRJ \
-configuration Release \
-archivePath "build/$TARGET_PRJ-simulator.xcarchive" \
-destination "generic/platform=iOS Simulator" \
-derivedDataPath "build" \
-IDECustomBuildProductsPath="" -IDECustomBuildIntermediatesPath="" \
ENABLE_BITCODE=NO \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
if [ $? -ne 0 ]; then
echo "######## S T A G E 1 E R R O R ! ! ! ########"
exit
fi
xcodebuild -project $TARGET_PRJ.xcodeproj archive \
-scheme $TARGET_PRJ \
-configuration Release \
-archivePath "build/$TARGET_PRJ-ios.xcarchive" \
-destination "generic/platform=iOS" \
-derivedDataPath "build" \
-IDECustomBuildProductsPath="" -IDECustomBuildIntermediatesPath="" \
ENABLE_BITCODE=NO \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
if [ $? -ne 0 ]; then
echo "######## S T A G E 2 E R R O R ! ! ! ########"
exit
fi
xcodebuild -create-xcframework \
-framework build/$TARGET_PRJ-simulator.xcarchive/Products/Library/Frameworks/$TARGET_PRJ.framework \
-framework build/$TARGET_PRJ-ios.xcarchive/Products/Library/Frameworks/$TARGET_PRJ.framework \
-output build/$TARGET_PRJ.xcframework
if [ $? -ne 0 ]; then
echo "######## S T A G E 3 E R R O R ! ! ! ########"
extt
fi
以下の folder ができました。
(9) 古いMS記事では、lipo コマンドを使う記述がありました。同コマンドは実行バイナリコードの統合を行うものだそうです。 この統合は xcodebuild でも行えるようです。
(10) MACで、Objective Sharpie ツール をダウンロードし、MACにインストールします。これはMicrosoftがMAC用に作ったもののようです。これでC#とのリンク情報を作成する模様です。
(11) Objective Sharpie ツール を実行します。弊方は以下shスクリプトにまとめました。
#!/bin/sh
#メタデータを準備する
TARGET_IOS=16.2
TARGET_PRJ=プロジェクト名
HEADER_PATH=$TARGET_PRJ.xcframework/ios-arm64/$TARGET_PRJ.framework/Headers
HEADER_NAME=$TARGET_PRJ.h
HEADER_PATH2=/Users/ログインアカウント名/Desktop/プロジェクトパス/サードパーティライブラリ名s.xcframework/ios-arm64/サードパーティライブラリ.framework/Headers
HEADER_NAME2=サードパーティライブラリs-Swift.h
sharpie -v
sharpie bind \
--sdk=iphoneos$TARGET_IOS \
--output="XamarinApiDef" \
--namespace="Binding" \
--scope=$HEADER_PATH \
$HEADER_PATH/$HEADER_NAME
以下の folder 下に .cs が生成されるようです。
(12) Visual Stduio 側でXamarinソリューションを作成し、iOSバインドライブラリのprojectを作成します。これ以降の操作はWindows版でも出来たと思います。
(13)上記(11)で生成された2つのfileを、ネイティブ参照にインポートします。コピー先はバインドライブラリの直下だったかもしれません。
(14)上記(1) のXcodeプロジェクトをネイティブ参照に設定します。
(15)Xcodeプロジェクトの設定を変更します。リンカーフラグの設定もしましたが最新情報ではないかもしれません。
(16)Xcodeプロジェクトの以下file設定を変更します。
(17)バインドライブラリを、アプリ本体側で参照設定します。
いちおうこれでMS記事の手順はできました。C#用インターフェイスを定義して、サードパーティライブラリを紐づけすればよいという感じのようです。バインドしたライブラリに対して、VS2022側でメソッド自動表示か応答するようになりました。
4. 問題
XamarinのiOSプロジェクトをビルドすると「Microsoft.iOS が無いというエラー」が発生します。下記CCLocationはiOSの位置情報クラスですので、Microsoft.iOS とはiOSライブラリのラッパーか何かのようです。
以下のようなエラーも出ます。
Microsoft.iOS を探してきて無理くり参照させると、
Apple側でなにか支障が生じるのではと予想していましたが、Visual Studio側で色々な矛盾が生じているようです。おそらくMAC OS、Xcode、Visual StudioとXamarinと周辺ライブラリのバージョンの組合せを一致させる必要があるのかなと思います。しかしその組み合わせはどこにも記載がありません。