Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException

build 失敗して出ますよね。

意味は、

設定しているリポジトリにそのモジュールのそのバージョンがないよ。

ということです。

今、こういうの出ました。


Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find app.cash.sqldelight:android-paging3-extensions:2.0.0-alpha03.
Searched in the following locations:
  - https://dl.google.com/dl/android/maven2/app/cash/sqldelight/android-paging3-extensions/2.0.0-alpha03/android-paging3-extensions-2.0.0-alpha03.pom
  - https://repo.maven.apache.org/maven2/app/cash/sqldelight/android-paging3-extensions/2.0.0-alpha03/android-paging3-extensions-2.0.0-alpha03.pom

エラーの https から始まるリンクから「バージョン」を含む文字列までを省いてブラウザでアクセスします。

👉 https://dl.google.com/dl/android/maven2/app/cash/sqldelight/android-paging3-extensions/hatena-bookmark

👉 https://repo.maven.apache.org/maven2/app/cash/sqldelight/android-paging3-extensions/hatena-bookmark

maven central にある、android-paging3-extensions の最新バージョンは、「2.0.0-alpha01」ですね!

build.glade のバージョンを変更すれば通りますね!

 

まとめ


Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException

が出たときは、build.gradle に設定したリポジトリに、そのバージョンが存在しません。エラーメッセージそのままですね!

ほぼ、利用してるリポジトリは以下2つのリポジトリであることが多いでしょう。


repositories {
  google()
  mavenCentral()
}

以下の2つをブラウザにブックマークしておくといいですね。

👉 Google's Maven Repository hatena-bookmark
👉 Maven Central Repository Search hatena-bookmark


「データ セーフティ セクション」のポリシー違反は「アプリ アップデート」が公開されたあとに時間を置いて解決する件

数週間やってました。

ずっと解決しないので困ってました「データ セーフティ」の公開部分の申請。

データセーフティセクション の申請を入力すると、

アプリのアップデートが公開されたあと、

大体24時間ぐらい経つと

データセーフティセクションの問題表示も消えました。

我慢できずにデータセーフティセクションを書き換えると

ずっとデータセーフティセクションの問題は解決されていないと表示されたまま


データセーフティセクションの申請内容の更新

↓

アプリアップデートの公開

↓

データセーフティセクションの申請内容の更新

↓

アプリアップデートの公開

↓

(以下ループ)

というような無限ループとなります。

データセーフティセクションの記入内容の審査は

アプリアップデートの公開の審査に含まれてる。

ということなのでしょう。

ハマります、悩みます。


Kotlin スコープ関数 の上手な使い分け その1 - apply

kotlin scope function

使い分けが難しいと言われているスコープ関数ですが。

以下、どれでも同じ結果を取得できます。


val bundle = Bundle()
bundle.putInt("x", 1)
bundle.putInt("y", 2)

val run = Bundle().run {
  putInt("x", 1)
  putInt("y", 2)
  this
}

val let = Bundle().let {
  it.putInt("x", 1)
  it.putInt("y", 2)
  it
}

val with = with(Bundle()) {
  putInt("x", 1)
  putInt("y", 2)
  this
}

val apply = Bundle().apply {
  putInt("x", 1)
  putInt("y", 2)
}

val also = Bundle().also {
  it.putInt("x", 1)
  it.putInt("y", 2)
}

val runNE = run {
  val bundleNE = Bundle()
  bundleNE.putInt("x", 1)
  bundleNE.putInt("y", 2)
  bundleNE
}

println("bundle = $bundle")
println("run    = $run")
println("let    = $let")
println("with   = $with")
println("apply  = $apply")
println("also   = $also")
println("runNE  = $runNE")


I/System.out: bundle = Bundle[{x=1, y=2}]
I/System.out: run    = Bundle[{x=1, y=2}]
I/System.out: let    = Bundle[{x=1, y=2}]
I/System.out: with   = Bundle[{x=1, y=2}]
I/System.out: apply  = Bundle[{x=1, y=2}]
I/System.out: also   = Bundle[{x=1, y=2}]
I/System.out: runNE  = Bundle[{x=1, y=2}]

どれが書きやすいですかね。

どれが分かりやすく管理しやすいですか。

 

■ apply の便利な使い方 (公式)

実装を見てみます。


public inline fun <T> T.apply(block: T.() -> Unit): T {
  contract {...}
  block()
  return this
}

Kotlin 公式リファレンスには使い分けとして以下の説明が書かれてます。

apply executes a block of code on an object and returns the object itself. Inside the block, the object is referenced by this. This function is handy for initializing objects.

apply は、オブジェクトに対してコードのブロックを実行し、そのオブジェクト自身を返します。ブロックの内部では、オブジェクトはthisで参照されます。
この関数は、オブジェクトを初期化するのに便利です。

Object configuration
オブジェクトの設定

Builder-style usage of methods that return Unit
Unitを返すメソッドのBuilder的な使い方


fun arrayOfMinusOnes(size: Int): IntArray {
  return IntArray(size).apply { fill(-1) }
}

Configure properties of an object (apply)
オブジェクトのプロパティを設定する


val myRectangle = Rectangle().apply {
  length = 4
  breadth = 5
  color = 0xFAFAFA
}

👉 Kotlin Examples: Learn Kotlin Programming By Example hatena-bookmark
👉 Scope functions | Kotlin hatena-bookmark
👉 Idioms | Kotlin hatena-bookmark

 

■ まとめ

「apply」は「オブジェクトの初期設定」に使う と良いです。

コンストラクタの引数 や Builder の有無に関係なしに使えます。

使い方のイメージは Builder パターンのスタイルです。


fun newIntent(context: Context, movie: Movie): Intent {
  return Intent(context, PlaybackActivity::class.java)
    .apply {
       putExtra(MOVIE, movie)
    }
}


private val messagesSent = MutableLiveData<Int>().apply { value = 0 }
private val dinosClicked = MutableLiveData<Int>().apply { value = 0 }
private val dropText = MutableLiveData<String>().apply { value = "Drop Things Here!" }


private val paint = Paint().apply {
  color = drawColor
  isAntiAlias = true
  isDither = true
  style = Paint.Style.STROKE // default: FILL
  strokeJoin = Paint.Join.ROUND // default: MITER
  strokeCap = Paint.Cap.ROUND // default: BUTT
  strokeWidth = STROKE_WIDTH // default: Hairline-width (really thin)
}

apply ブロック内に if を使うこともできます。

👉 Kotlin スコープ関数 の上手な使い分け その1 - apply hatena-bookmark
👉 Kotlin スコープ関数 の上手な使い分け その2 - also hatena-bookmark
👉 Kotlin スコープ関数 の上手な使い分け その3 - with hatena-bookmark
👉 Kotlin スコープ関数 の上手な使い分け その4 - let hatena-bookmark
👉 Kotlin スコープ関数 の上手な使い分け その5 - run hatena-bookmark