Skip to content

Feature/central manager init options#51

Merged
teach310 merged 16 commits intodevelopfrom
feature/central_manager_init_options
Oct 26, 2023
Merged

Feature/central manager init options#51
teach310 merged 16 commits intodevelopfrom
feature/central_manager_init_options

Conversation

@teach310
Copy link
Copy Markdown
Owner

@teach310 teach310 commented Oct 25, 2023

PRs

add Foundation NSNumber #50
add Foundation NSString #52
add Foundation NSMutableDictionary #53
add CBCentralInitOptions #54

teach310 and others added 3 commits October 26, 2023 00:06
Nativeの数値、boolをcsharp側で生成するために作成
swiftのint, boolは値型だが、NSNumberはクラス。
teach310 and others added 13 commits October 26, 2023 00:28
## NSStringクラスを追加した理由

汎用的な文字列取得実装のため。

MicrosoftのドキュメントでStringBuilderは非推奨と書かれていたためにStringBuilderを使い続けることに抵抗があった。
https://learn.microsoft.com/ja-jp/dotnet/standard/native-interop/best-practices

そして、NSDictionaryに文字列を登録するため

## NSString.HandleToStringについて

流れに関してはXamarinの実装を参考にしている。
https://github.com/xamarin/xamarin-macios/blob/main/src/CoreFoundation/CFString.cs#L190-L224

ここではFromHandleという関数名だが、NSString.FromHandleという名前であればNSStringを返した方が自然だと思うためHandleToStringという名前にした。
引数のreleaseHandleに関してはSafeNSStringHandleをusingで破棄する方が書き心地よいと感じるため不要と判断した。

## NSStringを使用している理由

swiftのStringは値型のためUnmanaged.passRetainedの引数にすることができない。
したがって、csharp側にポインタを渡すためにはCFStringまたはNSString等のクラスを用いる必要があった。

そして、CFStringよりもNSStringのほうが扱いやすかったためNSStringを使用している。
NSStringを参照型のクラスとして使用することはswiftの公式ドキュメントにも書かれている。

> They provide reference semantics instead of value semantics, which is a useful tool to have in the toolbox.

https://github.com/apple/swift-corelibs-foundation

## NSStringのcstringからのコピーをcsharp側で行っている理由

char配列を渡してそこにswiftで文字列を入れたところ文字化けしたから。
StringBuilderの場合は文字化けしないが前述の理由により避けた。
byte配列を渡せば文字化けしないかもしれないが、ArrayPoolが遅いかもしれず、最適な方法がわからなかったため
中身のコード見た感じ問題なさそうで一番楽なMarshal.PtrToStringUTF8を使用した。

https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.cs,80

## LengthOfBytesUtf8について
使ってないけど、テストで活用できるため残している。
良い。NSStringを解放したらこれも解放される(内部だから)。

> This C string is a pointer to a structure inside the string object, which may have a lifetime shorter than the string object and will certainly not have a longer lifetime.

https://developer.apple.com/documentation/foundation/nsstring/1411189-utf8string

## utf8StringはNSStringの中身だがこれをコピーしなくてよいのか?
NSStringはヒープなため別の場所にコピーするメリットはlifetimeをNSStringと分離することだと思う。
同じでいいためしなくて良いと判断

## cstringの文字列の長さの測り方

ここにstrlenを使った例がある
https://developer.apple.com/documentation/swift/string/utf8cstring
## NSMutableDictionaryが必要な理由

swiftのDictionaryはクラスじゃないから。
https://developer.apple.com/documentation/swift/dictionary

Unmanaged.passRetainの引数にするためにはクラスである必要がある。

## NSMutableDictionaryからswift Dictionaryへの変換

基本的には as でできる。
ただしbool値に関してはNSNumberのため変換後に入るのが数値。
0,1 ではなく false, trueの値が必要な場合には変換用の関数を自前で作る必要がある。
今回はなかった。
## クラス名
https://learn.microsoft.com/en-us/dotnet/api/corebluetooth.cbcentralinitoptions?view=xamarin-ios-sdk-12
xamarinのをそのまま踏襲

## キー名について
「kCBInitOptionShowPowerAlert」という値はswift側のprintで出力したもの。

https://developer.apple.com/documentation/corebluetooth/cbcentralmanageroptionshowpoweralertkey

appleのドキュメントでは定数の中身については書かれていないため、この定数を取得するNativeMethodsを定義するのが無難ではあると思う。
xamarinではおそらく定数を取ってきている。

https://github.com/xamarin/xamarin-macios/blob/a0eec0c265eeb3ad5b3e01e08793e326d890a647/src/corebluetooth.cs#L33

が、定数取ってくるためにNativeMethods書いたりするのが手間だったため一番楽で処理速度も当然最速なcsharp側に直書きという方法に一旦している。

## ToNativeDictionaryについて
xamarinではDictionaryContainerを継承して、オプションをセットすると同時にNativeのDictionaryを更新しているようだった。
https://learn.microsoft.com/en-us/dotnet/api/foundation.dictionarycontainer?view=xamarin-ios-sdk-12

でもこれだと options が持ってるNSMutableDictionaryのDisposeが手間。
xamarinだとやっていないっぽかった。

そのため使う時にだけ作って使い捨てるという実装にしている。
## なぜIntPtrなのか
SafeHandleはクラスだが、nullを渡したらエラーがでた。
SafeHandleをnullとして渡すドキュメントが見つからなかったためIntPtrを引数にとるようにした。

また、別の箇所でもSafeHandleにnullはいれないようにしている
@teach310 teach310 merged commit da2e67b into develop Oct 26, 2023
@teach310 teach310 deleted the feature/central_manager_init_options branch October 26, 2023 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant