Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How We Work Offline

How We Work Offline

Un recorrido por las distintas soluciones para trabajar cuando no hay conexion y sincronizar datos que hemos implementado, no solo para lidiar con la falta de conectividad sino tambien con la mala conectividad. Desde utilizar Receivers hasta Work Manager, analizando el porque necesitamos este tipo de soluciones para mejorar nuestras apps.

Juan Carlos Garcia

December 21, 2019
Tweet

Transcript

  1. sealed class NetworkError : Errors() data class NoInternetConnection( val request:

    String, val type: OfflineRequestType ) : Errors() object AlreadyCreated : NetworkError() object BadRequest : NetworkError() object Forbidden : NetworkError()
  2. fun NetworkError.mapToDomainError(): DomainError = when (this) { is NoInternetConnection ->

    { repository?.save(this.request, this.type) DomainError } AlreadyCreated -> DomainError BadRequest -> DomainError Forbidden -> DomainError }
  3. fun initSync() { val myIntent = Intent(this, SyncService::class.java) val pendingIntent

    = PendingIntent.getService(this, 0, myIntent, 0) getSystemService(Context.ALARM_SERVICE) .setRepeating( AlarmManager.RTC_WAKEUP, 0, frequency, pendingIntent) }
  4. class SyncService : IntentService(SyncService::class.java.name) { lateinit var repository : OfflineRepository

    lateinit var salesSync : SalesSyncUseCase lateinit var accessSync : AccessControlSyncUseCase lateinit var refundSync : RefundSyncUseCase override fun onHandleIntent(intent: Intent) { if (hasConnection()) { repository.getAll().map{ offlineRequest -> when(offlineRequest.type){ OfflineRequestType.SALES -> salesSync(offlineRequest.request) OfflineRequestType.REFUND -> refundSync(offlineRequest.request) OfflineRequestType.ACCESS_CONTROL -> accessSync(offlineRequest.request) } } } } }
  5. class RemoveLocalCopy( context: Context, params: WorkerParameters ) : Worker(context, params)

    { private val use case = UseCase() override fun doWork(): Result = usecase(inputData.keyValueMap[PARAM] as String).fold( { when (it) { IOError -> Result.retry() ForbiddenOperationError, FatalError, ResourceNotFound -> Result.failure() } }, { Result.success(workDataOf(PARAM to it)) } ) }
  6. fun OneTimeWorkRequest.Builder.requireInternetWork(data: Data, retry: Long) : OneTimeWorkRequest = this.setConstraints( Constraints.Builder()

    .setRequiredNetworkType(NetworkType.CONNECTED) .build() ) .setBackoffCriteria(BackoffPolicy.LINEAR, retry, TimeUnit.SECONDS) .setInputData(data) .build()
  7. CREDITS AND RESOURCES ▸ Saúl Díaz: Offline Second ▸ Android

    Dev Podcast: Offline First ▸ Android Dev Podcast: Workers & Room ▸ Android Developers: https://developer.android.com/topic/ libraries/architecture/workmanager ▸ Working with WorkManager (Android Dev Summit ’18): https://www.youtube.com/watch?v=83a4rYXsDs0
  8. IMAGES ▸ Barrier Photo: https://www.flickr.com/photos/48603151@N00/ ▸ Box-Office Photos: https://www.flickr.com/photos/incinema/ ▸

    Train Photos: https://www.flickr.com/photos/jtcurses9/ ▸ Vader Photo: https://www.flickr.com/photos/jdhancock/ ▸ Offline Photo: https://www.flickr.com/photos/no-luogo/