どちらが好きですか、以下2つのコード。
■ 1つ目
import SwiftUI
public extension Image {
#if canImport(AppKit)
init(image: NSImage) {
self = Image(nsImage: image)
}
#endif
#if canImport(UIKit)
init(image: UIImage) {
self = Image(uiImage: image)
}
#endif
}
特徴:
- 拡張機能 (extension) を使って、Imageに新しいinitイニシャライザを追加しています。
- プラットフォームごとに異なる型 (NSImageやUIImage) を直接引数に取ります。
- プラットフォーム依存の条件付きで、NSImage(macOS)またはUIImage(iOS)を使用してImageを初期化しています。
メリット:
- 各プラットフォームに対応したイニシャライザが個別に用意されており、Imageの初期化が直感的です。
デメリット:
- プラットフォームごとにinitメソッドが別々に定義されているため、共通の型を扱うのが難しい。
■ 2つ目
#if canImport(AppKit)
import AppKit
public typealias PlatformImage = NSImage
#elseif canImport(UIKit)
import UIKit
public typealias PlatformImage = UIImage
#endif
import SwiftUI
extension Image {
init(platformImage: PlatformImage) {
#if canImport(UIKit)
self = Image(uiImage: platformImage)
#elseif canImport(AppKit)
self = Image(nsImage: platformImage)
#endif
}
}
特徴:
- PlatformImageという型エイリアスを使って、macOSのNSImageとiOSのUIImageを抽象化しています。
- platformImageという共通の引数型を持つイニシャライザを追加しています。これにより、プラットフォームごとにImageを初期化しますが、型エイリアスによって共通化されています。
メリット:
- 抽象化されているため、呼び出し側のコードがプラットフォームに依存しません。つまり、共通のコードでPlatformImage型を使えば、iOSでもmacOSでも同じコードで動作します。
- 可読性が高く、メンテナンスが容易です。プラットフォームごとにメソッドを分ける必要がなく、1つのメソッドで対応しています。
デメリット:
- プラットフォームごとに異なる処理を追加する際に、多少複雑になる可能性があります。
■ まとめ
AIによると、
結論:どちらが良いか?
2つ目のコードの方が一般的に推奨されます。理由は、コードの抽象化によって、呼び出し側がプラットフォームに依存しない形でImageを扱うことができるためです。メンテナンス性が高く、同じコードベースで複数のプラットフォームをサポートしやすくなります。
ただし、プラットフォームごとに異なる処理が必要なケースでは、1つ目のコードの方が直感的に分かりやすい場合もあるので、状況に応じて選択が変わることがあります。
ということです。
私的には、どっちも勉強になります、としか。
【SwiftUI】 iOS / macOS の レイアウト記述を typealias で切り替える
👉 https://t.co/v8jLxKzCGk#プログラミング #ios #swift #macos— chanzmao (@maochanz) January 29, 2024