Jetpack Compose から SwiftUI に来ましたが今の謎をどうにかしたい 😩

Swift 初心者です。Kotlin からきました。

Apple 公式サンプルコードを3日間 ROM ってました。

👉 sample-backyard-birds/Multiplatform/Birds/BirdsSearchResults.swift at main · apple/sample-backyard-birds hatena-bookmark

どうも納得ができないので書き換えてみました。

動かしてみると3つとも特に問題ないような感じに見えました。

ネットで調べていると、どうもこちらも変化が激しいようで、どの記事を信じたらいいのか分かりません。

コードを見比べながら分からないこと、今後調べたいこと、を洗い出してみます。

 

😩 init()

ここで必要なのですか。なくても引数は同じ。


init(searchText: Binding<String>, @ViewBuilder content: @escaping (Bird) -> Content) {

パフォーマンス的な何か、なのでしょうか。

 

😩 KeyPath


_birds = Query(sort: \.creationDate)

すべて、Xcode 任せなのですが、省略できないんです。Bird が。

「Path」というぐらいなのでどこかに通せばいいと思っているのですが。

 

😩 Property Wrapper

いきなりでてくる _(アンダースコア)付きのこれ ROM 勢としては驚きました。

どこにもないのにいきなり登場してくる。

どこかに何か隠れてますか。


struct BirdsSearchResults<Content: View>: View {
  @Binding var searchText: String

  init(searchText: Binding<String>, ...) {
    _searchText = searchText

以下すべて挙動が同じに見えます。


struct BirdsSearchResults<Content: View>: View {
  @Binding var searchText: String


struct BirdsSearchResults<Content: View>: View {
  private var searchText: String

  init(searchText: Binding<String>, ...) {
    self.searchText = searchText.wrappedValue


struct BirdsSearchResults<Content: View>: View {
  private var searchText: Binding<String>

  init(searchText: Binding<String>, ...) {
    self.searchText = searchText

  var body: some View {
    let searchText = self.searchText.wrappedValue

ここの部分。


_searchText = searchText
_birds = Query(sort: \.creationDate)

以下記事で勉強したのですが。

👉 SwiftUI Property WrappersクラスのwrappedValue・projectedValue一覧表 #Swift - Qiita hatena-bookmark

隠しているものを丸出しに露出させることなどできるのでしょうか。

 

😩 $0

この記述よく見かけます。


birds.filter {
  $0.speciesName.contains(

分かりづらい感じがしますが、なぜ具体的なものに置き換えないのでしょうか。

Kotlin でも同様な記述があり、よく怒られていました。

 

😩 まとめ

対象の Apple サンプルコードは WWDC2023 のものなので約1年前ぐらいで、そんなに古くはないと思っています。

どうかどうかよろしくおねがいします。



【Xcode】Auto-Completion がおかしい 不具合の理由 → DerivedData

なぜか、

通常プロジェクトと Playground では Auto-Completion が違う。

マルチなクロージャーを含む


Button(action:label:)

を Auto-Completion で生成して、全クロージャー展開しようとするとできない。

せっかく Playgorund で Completion の使い方を掴んだような気がしてたのに!


 

🛠️ 症状

クロージャー展開しようとすると以下の感じ。

Playground 側は OK。


// Playground

Button {
  code
} label: {
  code
}

// Button(action: <#T##() -> Void#>, label: <#T##() -> View#>)

フォーカスの当たったままコピーすると設定記述的なものがテキストで取得できる。

これが、既存プロジェクト側では、なぜか、展開できない。


// Project

Button(action: {}, label: {
        Text("Button")
 })

// Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/, label: {
//   /*@START_MENU_TOKEN@*/Text("Button")/*@END_MENU_TOKEN@*/
//    })

なんやこれ。

プロジェクト内に同様な記述があると思って探しみたけど見当たらない。

登録されている Completions を


Editor
  ↓
Show Completions

で確認しても問題はなさそう。

あれこれやっていると、直ることがある。


- Xcode 再起動直後だけ一瞬直る。
- しかし、2回目ぐらいから戻っておかしくなる。

よって、キャッシュか何かを読み込んでいる、と想像。

 

🛠️ 修正・対応方法

これでいけた。


rm -rf ~/Library/Developer/Xcode/DerivedData/*

👉 Xcode Quick Fix - Clear Cache hatena-bookmark

以下でも直ったのかもしれない。


Product

  ↓

Clean Build Folder...

  +

Option


👉 [Xcode][小ネタ] DerivedDataの削除についての備忘録 | DevelopersIO hatena-bookmark

 

🛠️ まとめ

DerivedData を削除することで効果が出る不具合。


- Build Failed
- ストレージが肥大
- Completion がおかしい

キャッシュのようなもので消しても問題ないらしい。

場所はデフォルトで、


~/Library/Developer/Xcode/DerivedData

で以下メニューから確認できる。


File

 ↓

{project name} Settings...

少し前に、Xcode をバージョンアップデートしたのでそれが影響しているのかもしれないです。


【macOS / Android】scrcpy on Mac can't find "… libmbedcrypto.14.dylib" · Genymobile/scrcpy

scrcpy を起動しようとしたら、

何だか厳しそうなエラーが出ました。


dyld[90421]: Library not loaded: '/usr/local/opt/mbedtls/lib/libmbedcrypto.12.dylib'
  Referenced from: '/usr/local/Cellar/librist/0.2.7_1/lib/librist.4.dylib'
  Reason: tried: '/usr/local/opt/mbedtls/lib/libmbedcrypto.12.dylib' (no such file), '/usr/local/lib/libmbedcrypto.12.dylib' (no such file), '/usr/lib/libmbedcrypto.12.dylib' (no such file)
zsh: abort      /usr/local/Cellar/scrcpy/1.24/bin/scrcpy

👉 scrcpy on Mac can't find "…libmbedcrypto.14.dylib" · Issue #4409 · Genymobile/scrcpy hatena-bookmark

みんなが成功しているコメントから以下を実行して再インストールします。


brew uninstall librist --ignore-dependencies
brew uninstall mbedtls --ignore-dependencies
brew reinstall scrcpy

👉 Not working on Mac · Issue #3505 · Genymobile/scrcpy hatena-bookmark

だが、しかし。

 

😅 ERROR: Command not found: [adb], [start-server]


scrcpy

scrcpy v2.2 <https://github.com/Genymobile/scrcpy>
exec: No such file or directory
ERROR: Command not found: [adb], [start-server]
ERROR: (make 'adb' accessible from your PATH or define its fullpath in the ADB environment variable)
INFO: You may install 'adb' by "apt install adb"
ERROR: Could not execute "adb start-server"
ERROR: Could not start adb server
ERROR: Server connection failed

Android Studio インストール済みだったので PATH だけ通していけました!


# .zshrc

# android-tools
export PATH=$PATH:$HOME/Library/Android/sdk/platform-tools

【macOS / Android】scrcpy on Mac can't find "… libmbedcrypto.14.dylib" · Genymobile/scrcpy

 

😅 まとめ

macOS 新規インストールしてから、スクリプトツールたちがエラーを吐きまくってるのだが。


Hilt で KSP の依存関係の設定 (build.gradle.kts)

kapt から KSP に移行しようとしてハマる。

 

🚀 Dagger + KSP

今回は使わなったが動く。


plugins {
  id("org.jetbrains.kotlin.android") version "1.9.0"
  id("com.google.devtools.ksp") version "1.9.0-1.0.12"
}

dependencies {
  ksp("com.google.dagger:dagger-compiler:2.48") // Dagger compiler
  ksp("com.google.dagger:hilt-compiler:2.48")   // Hilt compiler
}

👉 Dagger KSP hatena-bookmark

 

🚀 Hilt + kapt


// build.gradle.kts (Project)

plugins {
  id("com.google.dagger.hilt.android") version "2.44" apply false
}


// build.gradle.kts (Module)

plugins {
  kotlin("kapt")
  id("com.google.dagger.hilt.android")
}

dependencies {
  implementation("com.google.dagger:hilt-android:2.44")
  kapt("com.google.dagger:hilt-android-compiler:2.44")
}

kapt {
  correctErrorTypes = true
}

👉 Hilt を使用した依存関係の注入  |  Android デベロッパー  |  Android Developers hatena-bookmark

 

🚀 Hilt + KSP


// build.gradle.kts (Project)

plugins {
  id("com.google.devtools.ksp") version "1.8.10-1.0.9" apply false
  id("com.google.dagger.hilt.android") version "2.44" apply false
}


// build.gradle.kts (Module)

plugins {
  id("com.google.devtools.ksp")
  id("com.google.dagger.hilt.android")
}

dependencies {
  implementation("com.google.dagger:hilt-android:2.44")
  ksp("com.google.dagger:hilt-android-compiler:2.44")
}

👉 kapt から KSP に移行する  |  Android デベロッパー  |  Android Developers hatena-bookmark

👉 Revisions · Hilt + kapt → KSP hatena-bookmark

 

🚀 まとめ

Hilt で公式リファレンスを見ながら、kapt → KSP と順番に変化させていけばスムーズに対応できたのに、Dagger KSP ページを見ながら進んだのがハマった原因。

Version Catalog を使っていくことになりそうなので、抜粋しておく。




AndroidX が minSdkVersion 19 に移行

AndroidX ライブラリは、2023 年 10 月のリリースから、サポートされるデフォルトの最小 Android API レベル 19 (以前は 14) に移行します。Play ストアのチェックイン データによると、ほぼすべての Android ユーザーが API 19 以降のデバイスを使用しているため、API レベル 19 ではなくなりました。レガシーバージョンをサポートするために必要です。この変更は、AndroidX ライブラリがアプリ開発者の潜在的なユーザー数を最大化し、Google Play ServicesおよびAndroid NDKと連携するのに役立ちます。

現在、より低い minSdkVersion をサポートしている場合は、その値を 19 に増やし、以前のバージョンをサポートするようにコードをクリーンアップすることをお勧めします。ビジネス上の理由でそれができない場合は、AndroidX の以前のバージョンを使用し続けることをお勧めします。


👉 Android Developers Blog: AndroidX moving to minSdkVersion 19 hatena-bookmark

「API レベル 19」てのは、「Android OS 4.4 / Kitkat」です。

10年前ぐらいにリリースされました。


2023-10-17
+-----+------+--------------+-------+-------+----------+----------+
| API |   OS | CODE_NAME    |  WW % |  JP % | WW SUM % | JP SUM % |
+=====+======+==============+=======+=======+==========+==========+
|  19 |  4.4 | KITKAT       |  0.31 |  0.27 |    99.70 |    99.63 |
+-----+------+--------------+-------+-------+----------+----------+
|  21 |  5.0 | LOLLIPOP     |  0.43 |  0.22 |    99.39 |    99.36 |
+-----+------+--------------+-------+-------+----------+----------+
|  22 |  5.1 | LOLLIPOP_MR1 |  0.89 |  1.73 |    98.96 |    99.14 |
+-----+------+--------------+-------+-------+----------+----------+
|  23 |  6.0 | M            |  1.48 |  1.07 |    98.07 |    97.41 |
+-----+------+--------------+-------+-------+----------+----------+
|  24 |  7.0 | N            |  1.81 |  1.78 |    96.59 |    96.34 |
+-----+------+--------------+-------+-------+----------+----------+
|  25 |  7.1 | N_MR1        |  0.52 |  0.50 |    94.78 |    94.56 |
+-----+------+--------------+-------+-------+----------+----------+
|  26 |  8.0 | O            |  3.07 |  2.94 |    94.26 |    94.06 |
+-----+------+--------------+-------+-------+----------+----------+
|  27 |  8.1 | O_MR1        |  2.50 |  0.78 |    91.19 |    91.12 |
+-----+------+--------------+-------+-------+----------+----------+
|  28 |  9.0 | P            |  7.01 | 10.43 |    88.69 |    90.34 |
+-----+------+--------------+-------+-------+----------+----------+
|  29 | 10.0 | Q            |  9.07 |  9.95 |    81.68 |    79.91 |
+-----+------+--------------+-------+-------+----------+----------+
|  30 | 11.0 | R            | 18.73 | 13.09 |    72.61 |    69.96 |
+-----+------+--------------+-------+-------+----------+----------+
|  31 | 12.0 | S            | 18.93 | 19.03 |    53.88 |    56.87 |
+-----+------+--------------+-------+-------+----------+----------+
|  33 | 13.0 | T            | 34.92 | 37.75 |    34.95 |    37.84 |
+-----+------+--------------+-------+-------+----------+----------+
|  34 | 14.0 | U            |  0.03 |  0.09 |     0.03 |     0.09 |
+-----+------+--------------+-------+-------+----------+----------+

👉 Android OS version market share hatena-bookmark

もういいわな、世界でも、日本でも1%に満たないんだから。