💬

ゆめみ社のAndroidインターンに参加してきたので学んだことをまとめておく(サーバと通信編)

2022/09/06に公開約3,600字

ゆめみ社のAndroidインターンに参加しました。
なかなかにありがたい経験をさせてもらえたので、アウトプットします👍

  • 基本的には課題を進めていく🚶
  • 課題はAndroidViewで開発する前提になっていたが、Jetpack Composeの方が得意という旨を伝えると、Composeを使ってUIを作っていくことに。柔軟に対応していただくことができた。感謝😊

サーバと通信

参考:
なかなかリアルタイムに更新された記事

https://qiita.com/hiesiea/items/d1d8fff1d4a4ed12fbfb
公式ドキュメント
https://square.github.io/retrofit/

インターンでは途中までは実際には通信はしないメソッドを使って開発を進め、ある程度開発が進んだところで実際にモックサーバに対して通信を行うといった手順で実装しました。

Androidの通信処理

Androidの通信といえばRetrofitです。OkHttpというライブラリのラッパーでインターフェースを定義するだけでいい感じにサーバにアクセスしてくれる優れものです。

記事を参考にコピペ

こちらを参考に進めていきます。

サーバからは以下のようなレスポンスが返ってきます。

サーバからのレスポンス例
{
  "weather":"sunny",
  "maxTemp":10,
  "minTemp":-5,
  "date":"2022-08-31"
}

これをRetrofitで受け取るためには主に以下のステップが必要です。

  1. サーバに何を渡して何を受け取るかを定義するサービスインターフェースを定義
  2. サービスインスタンスを作成
  3. サービスインスタンス.メソッド()でAPIを呼び出し

なおせっかくDIについて学んだばっかだったのでクライアントインスタンスをDIで取得してこようと言うことになりました。(学んだことが早速実践できて嬉しいかった😊)

1. 天気を取得できるサービスインターフェース

interface WeatherService {
  @GET("weather")
  suspend fun getUserInfo(): Response<FetchWeatherResult>
}

// レスポンスデータを表すクラス
data class FetchWeatherResult(
  val weather: String,
  val maxTemp: Int,
  val minTemp: Int,
  val date: String,
)

2. クライアントインスタンスをDIで取得
@Module
@InstallIn(SingletonComponent:class)
object RetrofitModule{
  @Singleton
  @Provides
  fun provideWeatherService(
    retrofit: Retrofit,
  ):WeatherService{
    return retrofit.create(WeatherService::class)
  }
      @Singleton
    @Provides
    fun provideRetrofit(
        client: OkHttpClient,
        moshi: Moshi,
    ): Retrofit {
        return Retrofit.Builder()
            .baseUrl(/* モックサーバのURL */)
            .client(client)
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build()
    }
        @Singleton
    @Provides
    fun provideOkHttpClient(): OkHttpClient {
        val logging = HttpLoggingInterceptor {
            // Timber.tag("OkHttp").d(it)
            Log.d("http-log", "$it")
        }
        logging.setLevel(HttpLoggingInterceptor.Level.BASIC)
        return OkHttpClient.Builder()
            .addInterceptor(logging)
            .addInterceptor(
                Interceptor { chain ->
                    val request = chain.request()
                    val response: Response = chain.proceed(request)
                    if (response.code == 500) {
                        throw UnexpectedResponseException()
                    }
                    return@Interceptor response
                }
            )
            .build()
    }

    @Singleton
    @Provides
    fun provideMoshi(): Moshi {
        return Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
    }
}

インターフェースを渡したらそれを実装したクラスが返ってくる(retrofit.create(WeatherService::class))のは中身どうなってるんだろうとか思ったりしました。

あと、反省としては、これ以前の課題でJSONのパースにKotlinSerializationを使っていたのでMoshiではなくKotlinSerializationを使ってみたらもっといい感じになったのかもってことです😔

3. サービスインスタンスを呼び出す
val fetchRes = withContext(Dispatchers.IO){
  weatherService.getWeather()
}

Retrofit自体はあっさりとおわって使いやすい印象でした。

また今まで学んできたDIやアーキテクチャ周りの話を実感できました!

インターンアウトプットシリーズ一覧

Discussion

ログインするとコメントできます