【Retorofit】コピペで使える NetworkModule【Dagger Hilt】

もうこれはテンプレ化しておきます。

Retrofit の話が中心となります。

👉 Retrofit 

 

Converter

Retrofit-Converters

JSON 形式のレスポンスをパースして変換するのは、Gson か Moshi が人気のように思います。


var retrofit = Retrofit.Builder()
  .baseUrl("https://api.example.com")
  .addConverterFactory(GsonConverterFactory.create())
  .build()


var retrofit = Retrofit.Builder()
  .baseUrl("https://api.example.com")
  .addConverterFactory(MoshiConverterFactory.create())
  .build()

👉 retrofit/retrofit-converters at master · square/retrofit 

今回は、Kotlin Serialization を利用した「Kotlin Serialization Converter」を使います。

ExperimentalSerializationApi なのですがね。


val contentType = "application/json".toMediaType()
val retrofit = Retrofit.Builder()
    .baseUrl("https://example.com/")
    .addConverterFactory(Json.asConverterFactory(contentType))
    .build()

👉 JakeWharton/retrofit2-kotlinx-serialization-converter: A Retrofit 2 Converter.Factory for Kotlin serialization. 

 

Call Adapter

Retrofit CallAdapters

通信の非同期処理はどれに任せるか。


var retrofit = Retrofit.Builder()
  .baseUrl("https://api.example.com")
  .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  .build()

👉 retrofit/retrofit-adapters at master · square/retrofit 

Coroutine を使った Jake製の「Kotlin Coroutine Adapter」は 今では DEPRECATED。

👉 JakeWharton/retrofit2-kotlin-coroutines-adapter: A Retrofit 2 adapter for Kotlin coroutine's Deferred type. 

Retrofit は 2.6.0+ で、内部に suspend function をサポートしてるので、特に、.addCallAdapterFactory() を使わなくてもよい。


@GET("users/{id}")
suspend fun user(@Path("id") id: Long): User

👉 retrofit/CHANGELOG.md at master · square/retrofit 

 

HttpLoggingInterceptor

OkHttpClient に HTTP関連のログを吐かせます。


--> POST /greeting http/1.1
Host: example.com
Content-Type: plain/text
Content-Length: 3

Hi?
--> END POST

<-- 200 OK (22ms)
Content-Type: plain/text
Content-Length: 6

Hello!
<-- END HTTP

👉 HttpLoggingInterceptor.Level (OkHttp Logging Interceptor 3.14.0 API) 


val logging = HttpLoggingInterceptor()
logging.setLevel(Level.BASIC)
val client = OkHttpClient.Builder()
  .addInterceptor(logging)
  .build()

👉 okhttp/okhttp-logging-interceptor at master · square/okhttp 

 

まとめ

Dagger の Module にしておきます。

テンプレート化してください、と言わんばかりに

よく似たものをあちこちで見かけますよね。

見通しも良くなります。

コピペでどうぞ。

(おわり)



iOS App Store の最も使えるアプリURLはどれ?

👉 iPhoneアプリ ランキング まとめ【2022】 

iOS App Store の最も使えるアプリURLはどれ?

https://itunes.apple.com/jp/app/id658511662?mt=8
https://apps.apple.com/jp/app/id658511662
https://apps.apple.com/app/id658511662

テスト用に書いて見ましたけど、WEBで見ていくとバラバラですよね?

Redditアプリで試す。

reddit iphone app

https://itunes.apple.com/jp/app/id1064216828

https://itunes.apple.com/app/id1064216828

https://apps.apple.com/jp/app/id1064216828

https://apps.apple.com/app/id1064216828

https://apps.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200

itunes.apple.com はリダイレクトされる。


% curl -sS -I -L https://itunes.apple.com/jp/app/id1064216828

HTTP/2 301
server: 4.0.0
content-type: text/html; charset=UTF-8
content-length: 0
last-modified: Mon, 07 Mar 2022 08:16:33 GMT
access-control-allow-origin: *
strict-transport-security: max-age=31536000; includeSubDomains
location: https://apps.apple.com/jp/app/id1064216828
cache-control: max-age=0
date: Mon, 07 Mar 2022 08:16:33 GMT
...

HTTP/2 200
server: daiquiri/3.0.0
content-type: text/html; charset=utf-8
content-length: 330377
strict-transport-security: max-age=31536000; includeSubDomains
cache-control: public, max-age=60
expires: Mon, 07 Mar 2022 08:17:34 GMT
date: Mon, 07 Mar 2022 08:16:34 GMT
...


% curl -sS -I -L https://itunes.apple.com/app/id1064216828

HTTP/2 301
server: 4.0.0
content-type: text/html; charset=UTF-8
content-length: 0
last-modified: Mon, 07 Mar 2022 08:18:10 GMT
access-control-allow-origin: *
strict-transport-security: max-age=31536000; includeSubDomains
location: https://apps.apple.com/app/id1064216828
cache-control: max-age=0
date: Mon, 07 Mar 2022 08:18:10 GMT
...

HTTP/2 200
server: daiquiri/3.0.0
content-type: text/html; charset=utf-8
content-length: 334515
strict-transport-security: max-age=31536000; includeSubDomains
cache-control: public, max-age=60
expires: Mon, 07 Mar 2022 08:19:11 GMT
date: Mon, 07 Mar 2022 08:18:11 GMT
...

itunes.apple.com は apps.apple.com へ301リダイレクトされる。

昔の名残りか。

2019年06月14日
App Store上のApp用のリンクが、apps.apple.com で始まるように変更されました。itunes.apple.com で始まる既存のリンクは引き続き機能し、自動的に apps.apple.com ドメインにリダイレクトされます。

👉 【Apple公式】 App Storeリンクのアップデート - ニュース - Apple Developer 

公式のツールが公開されていますのでこれでも推奨されるURLを確認しておきます。

Market with App Store
👉 Market with App Store 

考えられるURLをすべて書き出す

Reddit の場合。


% echo {https,itms-apps,itms}://{itunes,apps}.apple.com{,/us,/jp}/app{,/reddit}/id1064216828{,\?itsct=apps_box_link\&itscg=30200} | sed 's/ /\n/g'

https://itunes.apple.com/app/id1064216828
https://itunes.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/app/reddit/id1064216828
https://itunes.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/us/app/id1064216828
https://itunes.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/us/app/reddit/id1064216828
https://itunes.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/jp/app/id1064216828
https://itunes.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/jp/app/reddit/id1064216828
https://itunes.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
https://apps.apple.com/app/id1064216828
https://apps.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
https://apps.apple.com/app/reddit/id1064216828
https://apps.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
https://apps.apple.com/us/app/id1064216828
https://apps.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
https://apps.apple.com/us/app/reddit/id1064216828
https://apps.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
https://apps.apple.com/jp/app/id1064216828
https://apps.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
https://apps.apple.com/jp/app/reddit/id1064216828
https://apps.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/app/id1064216828
itms-apps://itunes.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/app/reddit/id1064216828
itms-apps://itunes.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/us/app/id1064216828
itms-apps://itunes.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/us/app/reddit/id1064216828
itms-apps://itunes.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/jp/app/id1064216828
itms-apps://itunes.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/jp/app/reddit/id1064216828
itms-apps://itunes.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/app/id1064216828
itms-apps://apps.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/app/reddit/id1064216828
itms-apps://apps.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/us/app/id1064216828
itms-apps://apps.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/us/app/reddit/id1064216828
itms-apps://apps.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/jp/app/id1064216828
itms-apps://apps.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/jp/app/reddit/id1064216828
itms-apps://apps.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/app/id1064216828
itms://itunes.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/app/reddit/id1064216828
itms://itunes.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/us/app/id1064216828
itms://itunes.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/us/app/reddit/id1064216828
itms://itunes.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/jp/app/id1064216828
itms://itunes.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/jp/app/reddit/id1064216828
itms://itunes.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/app/id1064216828
itms://apps.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/app/reddit/id1064216828
itms://apps.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/us/app/id1064216828
itms://apps.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/us/app/reddit/id1064216828
itms://apps.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/jp/app/id1064216828
itms://apps.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/jp/app/reddit/id1064216828
itms://apps.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200

そして、リクエストしてみる。


% echo https://{itunes,apps}.apple.com{,/us,/jp}/app{,/reddit}/id1064216828{,\?itsct=apps_box_link\&itscg=30200} | xargs -t -n1 curl -sSIL | grep -E '^(HTTP|server|content-length|location)'

curl -sSIL https://itunes.apple.com/app/id1064216828
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334513

curl -sSIL https://itunes.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/id1064216828?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334657

curl -sSIL https://itunes.apple.com/app/reddit/id1064216828
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/reddit/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334534

curl -sSIL https://itunes.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/reddit/id1064216828?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334678

curl -sSIL https://itunes.apple.com/us/app/id1064216828
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334522

curl -sSIL https://itunes.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/id1064216828?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334396

curl -sSIL https://itunes.apple.com/us/app/reddit/id1064216828
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/reddit/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334543

curl -sSIL https://itunes.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/reddit/id1064216828?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334687

curl -sSIL https://itunes.apple.com/jp/app/id1064216828
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330247

curl -sSIL https://itunes.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/id1064216828?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330399

curl -sSIL https://itunes.apple.com/jp/app/reddit/id1064216828
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/reddit/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330274

curl -sSIL https://itunes.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/reddit/id1064216828?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330418

curl -sSIL https://apps.apple.com/app/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334243

curl -sSIL https://apps.apple.com/app/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334243

curl -sSIL https://apps.apple.com/app/reddit/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334264

curl -sSIL https://apps.apple.com/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 404
server: daiquiri/3.0.0
content-length: 131919

curl -sSIL https://apps.apple.com/us/app/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 333982

curl -sSIL https://apps.apple.com/us/app/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334788

curl -sSIL https://apps.apple.com/us/app/reddit/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334543

curl -sSIL https://apps.apple.com/us/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 334543

curl -sSIL https://apps.apple.com/jp/app/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330253

curl -sSIL https://apps.apple.com/jp/app/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 329989

curl -sSIL https://apps.apple.com/jp/app/reddit/id1064216828
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330274

curl -sSIL https://apps.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 330548


% echo https://tools.applemediaservices.com/app/1064216828\?country={,us,jp} |  xargs -t -n1 curl -sSIL | grep -E '^(HTTP|server|content-length|location)'

curl -sSIL https://tools.applemediaservices.com/app/1064216828?country=
HTTP/2 200

curl -sSIL https://tools.applemediaservices.com/app/1064216828?country=us
HTTP/2 200

curl -sSIL https://tools.applemediaservices.com/app/1064216828?country=jp
HTTP/2 200

Redditアプリは、世界のほとんどの言語に対応しており、AppStoreの説明文も各言語で作成されています。

にゃんこ大戦争の場合。


echo {https,itms-apps,itms}://{itunes,apps}.apple.com{,/us,/jp}/app{,/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89}/id547145938{,\?itsct=apps_box_link\&itscg=30200}  | sed 's/ /\n/g'

https://itunes.apple.com/app/id547145938
https://itunes.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
https://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/us/app/id547145938
https://itunes.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
https://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/jp/app/id547145938
https://itunes.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
https://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
https://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
https://apps.apple.com/app/id547145938
https://apps.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
https://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
https://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
https://apps.apple.com/us/app/id547145938
https://apps.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
https://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
https://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
https://apps.apple.com/jp/app/id547145938
https://apps.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/app/id547145938
itms-apps://itunes.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms-apps://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/us/app/id547145938
itms-apps://itunes.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms-apps://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/jp/app/id547145938
itms-apps://itunes.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms-apps://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/app/id547145938
itms-apps://apps.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms-apps://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/us/app/id547145938
itms-apps://apps.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms-apps://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/jp/app/id547145938
itms-apps://apps.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
itms-apps://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms-apps://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/app/id547145938
itms://itunes.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/us/app/id547145938
itms://itunes.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/jp/app/id547145938
itms://itunes.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
itms://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/app/id547145938
itms://apps.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/us/app/id547145938
itms://apps.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/jp/app/id547145938
itms://apps.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
itms://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
itms://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200


echo https://{itunes,apps}.apple.com{,/us,/jp}/app{,/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89}/id547145938{,\?itsct=apps_box_link\&itscg=30200} | xargs -t -n1 curl -sSIL | grep -E '^(HTTP|server|content-length|location)'

curl -sSIL https://itunes.apple.com/app/id547145938
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/id547145938?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/us/app/id547145938
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/id547145938?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://itunes.apple.com/jp/app/id547145938
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/id547145938
HTTP/2 200
server: daiquiri/3.0.0
content-length: 448990

curl -sSIL https://itunes.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/id547145938?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 460281

curl -sSIL https://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 200
server: daiquiri/3.0.0
content-length: 449483

curl -sSIL https://itunes.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 301
server: 4.0.0
content-length: 0
location: https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?ign-itscg=30200&ign-itsct=apps_box_link
HTTP/2 200
server: daiquiri/3.0.0
content-length: 451464

curl -sSIL https://apps.apple.com/app/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/app/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/us/app/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/us/app/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/us/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 404
server: daiquiri/3.0.0
content-length: 73701

curl -sSIL https://apps.apple.com/jp/app/id547145938
HTTP/2 200
server: daiquiri/3.0.0
content-length: 449355

curl -sSIL https://apps.apple.com/jp/app/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 448990

curl -sSIL https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938
HTTP/2 200
server: daiquiri/3.0.0
content-length: 449483

curl -sSIL https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200
HTTP/2 200
server: daiquiri/3.0.0
content-length: 449483


echo https://tools.applemediaservices.com/app/547145938\?country={,us,jp} |  xargs -t -n1 curl -sSIL | grep -E '^(HTTP|server|content-length|location)'

curl -sSIL https://tools.applemediaservices.com/app/547145938?country=
HTTP/2 404

curl -sSIL https://tools.applemediaservices.com/app/547145938?country=us
HTTP/2 404

curl -sSIL https://tools.applemediaservices.com/app/547145938?country=jp
HTTP/2 200

にゃんこ大戦争アプリは、日本語のみに対応しており、AppStoreの説明も日本語でしか公開されていません。

まとめ


形式

{scheme}://{host}[/{country}]/app[/{slug}]/id{id}[?{query}]

■ scheme

https : WEBハイパーリンク
itms-apps : AppStoreアプリ
itms : iTuneStoreアプリ

「https」が、一般的にWEBサイト向き。

■ host

itunes.apple.com はすべて apps.apple.com にリダイレクトされるので 「apps.apple.com」

■ county

その国を開発者側が設定していない場合は、404で itms-apps にリダイレクトされる。
省略できるが、日本語サイトであれば「jp」とすべき。

■ slug

省略可。
各社クローラーに向けて使うように指導している。検索結果などがわかりやすく表示されるようになる。

■ id

アプリのID。必須。「id」という文字列に続く数字9桁。

■ query

「?itsct=apps_box_link&itscg=30200」

The ITSCT parameter is a partner-level token for the Apple Services Performance Partners Program. This value is static and should not be changed unless you are a partner who has been provided your own distinct token. If so, you may override the default ITSCT value with your own assigned value.

ITSCTパラメータは、Apple Services Performance Partners Programのパートナーレベルトークンです。この値は静的なもので、独自のトークンを提供されているパートナーでない限り、変更するべきではありません。その場合、デフォルトのITSCTの値を独自の値で上書きすることができます。

ITSCG parameter is a group-level token for the Apple Services Performance Partners Program. This value can never be changed and must always remain the same in your affiliate links.

ITSCGパラメータは、Apple Services Performance Partners Programのグループレベルトークンです。この値は決して変更することができず、アフィリエイトリンクでは常に同じ値である必要があります。

👉 Apple Newsでマーケティング 

以上、使いやすさと公式の説明から、これくらいの形式がいいでしょうかね。日本語サイトに貼るリンクの場合。


https://apps.apple.com/jp/app[/{slug}]/id{id}[?itsct=apps_box_link&itscg=30200]

最初の書き出し例から抜き出すと、Reddit や にゃんこ大戦争 のリンク記述は以下ぐらいがベストかなと。


https://apps.apple.com/jp/app/id1064216828

https://apps.apple.com/jp/app/reddit/id1064216828?itsct=apps_box_link&itscg=30200


https://apps.apple.com/jp/app/id547145938

https://apps.apple.com/jp/app/%E3%81%AB%E3%82%83%E3%82%93%E3%81%93%E5%A4%A7%E6%88%A6%E4%BA%89/id547145938?itsct=apps_box_link&itscg=30200

公式ツールの

Market with App Store 

で、まずは検索することがスタートになるでしょう。

GooglePlayに比べるとアクセスできるパターンが多いのが混乱させます。

👉 Google Play に変わっての、リンクURLはどう書くのがいいのか。 
👉 iPhoneアプリ ランキング まとめ【2022】 


iPhone連絡先アプリ だけが iCloud連絡先 のデータをエクスポートできない件

iPhone連絡先アプリ だけが  iCloud連絡先 のデータをエクスポートできない件

図からわかるように

iCloud 連絡先は、非Appleデバイスではアクセスできない。

iPhone連絡先アプリ だけが  iCloud連絡先 のデータをエクスポートできない件

Mac などパソコンがない場合は、iCloud 連絡先は iPhone 上では、連絡先アプリしかアクセスできない。

Android OS 上で iCloud 連絡先のデータを利用したい場合は、

iCloud 連絡先のデータをエクスポートして、Google コンタクトへインポートする。

しかないのだが、

iPhone連絡先アプリ だけが  iCloud連絡先 のデータをエクスポートできない件

iOS連絡先 アプリだけ iCloud連絡先 のデータをエクスポートできない。

Mac などパソコンがない状況では、iCloud 連絡先データは、エクスポートして、Googleコンタクトへインポートできないということになる。

まとめ

Apple、Google以外サードパーティツールを使えば状況は変わるが、そもそもは、

「iCloud連絡先 は、Appleデバイス間でのデータ共有クラウドツール。」

「Googleコンタクト は、あらゆるデバイスでのデータ共有クラウドツール。」

というそれぞれインターネットジャイアントのポリシー。

Googleコンタクト のが幅広く自在に使える。

👉 連絡先をクラウド上に保存する - 連絡先 / コンタクトの使い方まとめ その1【Android / iPhone】 
👉 Google コンタクト データをAndroid と iPhone で共有する - 連絡先 / コンタクトの使い方まとめ その2【Android / iPhone】 
👉 連絡先アプリ 必ず把握しておくべき全設定画面別使い方メモ- 連絡先 / コンタクトの使い方まとめ その3【Android → iPhone】 
👉 Googleコンタクト から iCloud連絡先 へ完全移行する手順 - 連絡先 / コンタクトの使い方まとめ その4 【Android → iPhone】