Size: a a a

Flutter Developers — русскоговорящее сообщество

2021 March 26

T

Temurxon in Flutter Developers — русскоговорящее сообщество
например
источник

D

Dagba  in Flutter Developers — русскоговорящее сообщество
Sergey Hottabych
Переслано от Sergey Hottabych
Посоветуйте по рефакторингу.
Сетевой запрос к GraphQL, если приходит Maintenance, кидать на экран "технические работы на сервере", если приходит Unautheticated, пытаться рефрешнуть токен.
Проблема в том, что сетевой код не должен знать ни про навигацию, ни про Auth, его задача — только отправлять запросы. Как это лучше переделать?
передать в колбеке?
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
Dagba 
передать в колбеке?
При каждом запросе это делать?
Предполагается, что на любой запрос может ни с того ни с сего прилететь "MAINTENANCE"
источник

D

Dagba  in Flutter Developers — русскоговорящее сообщество
можно создать стрим который будет слушать эти ивенты
источник

D

Dagba  in Flutter Developers — русскоговорящее сообщество
на стрим подписывваешься
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
Да вот я тоже к стриму склоняюсь.
источник
2021 March 27

M

MiT in Flutter Developers — русскоговорящее сообщество
Sergey Hottabych
Переслано от Sergey Hottabych
Посоветуйте по рефакторингу.
Сетевой запрос к GraphQL, если приходит Maintenance, кидать на экран "технические работы на сервере", если приходит Unautheticated, пытаться рефрешнуть токен.
Проблема в том, что сетевой код не должен знать ни про навигацию, ни про Auth, его задача — только отправлять запросы. Как это лучше переделать?
Передавай ошибки в бизнес логику и там работай с ними. Это бизнес задача
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
MiT
Передавай ошибки в бизнес логику и там работай с ними. Это бизнес задача
Вот где именно их обрабатывать?
Наивное решение — при прилете 'UNAUTHENTICATED' делать throw UnathenticatedError, а в контроллере каждый запрос оборачивать в try-catch и ловить on UnathenticatedError. Но это получается дофига бойлерплейта, каждый запрос так оборачивать.
А с Maintenance так еще хуже — делать rethrow в виджет, откуда обратились к контроллеру, и там уже дергать навигатор, и так тоже на каждом запросе.
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
Тот, кто это писал, видно, поэтому и сделал это прямо в runQuery, чтобы не расползалось.
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
Вот со стримом хорошая мысль — если пришло UNAUTHENTICATED, просто кидать событие в глобальный eventBus, а в authController его ловить и обновлять токен.
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
А вот где глобальное перепуливание по навигации на MaintenanceScreen сделать, чего-то не могу придумать.
источник

PK

Pavel K in Flutter Developers — русскоговорящее сообщество
Sergey Hottabych
Вот со стримом хорошая мысль — если пришло UNAUTHENTICATED, просто кидать событие в глобальный eventBus, а в authController его ловить и обновлять токен.
На мой взгляд, это две ситуации с абсолютно разных слоев и, соответственно, обработка у них должна быть разная
Первый кейс с Maintenance
Здесь это нормальное состояние приложения (не эксепшн), поэтому должно прокидываться до экрана
Я, к сожалению, не в курсе твоей архитектуры, но как пример - если у тебя есть некий AppState, который слушает один из виджетов, допустим через bloc, то это могло бы быть следующее

Widget build(BuildContext context) {
AppStateBloc bloc = Provider.of<AppStateBloc>(context);
return StreamBuilder(
 stream: bloc.appState,
 builder: (_, snapshot) {
  ... // разбор состояний snapshot опустим
  final AppState state = snapshot.data;
  if (state is MaintenanceState)
   return MaintenanceScreen(state) // можно передать state если там есть полезные данные для отображения на экране
  ...
  return HomeScreen()
 }
);
}


Случай с Unauthorized - это Service Layer. Допустим у тебя есть некий абстрактный класс Query и есть NetworkClient который умеет их выполнять

abstract class Query<T> {
...
}

abstract class NetworkClient {

Future<dynamic> execute(Query<dynamic> query);

}

Ну и соответственно, уровнем выше, скажем, есть у тебя Repository, который работает с этим клиентом и запросами
Так вот обработку Unathorized можно сделать централизованно внутри NetworkClient
То есть при запуске каждого Query он слушает результат - если прилетает нормальное значение - передаем в ответ
если прилетел Unauthorized - пытаемся отрефрешить токен и дергаем счетчик
если, скажем, три раза были неуспешными - тогда уже прокидываем какое-нибудь специальное состояние до Presentation Layer
где пользователю уже покажем соотв экран
источник

РИ

Руслан Исланбеков... in Flutter Developers — русскоговорящее сообщество
Всем привет
источник

РИ

Руслан Исланбеков... in Flutter Developers — русскоговорящее сообщество
у меня проблема с иконкой на local notification
источник

РИ

Руслан Исланбеков... in Flutter Developers — русскоговорящее сообщество
оно есть но все равно не видит
источник

РИ

Руслан Исланбеков... in Flutter Developers — русскоговорящее сообщество
подскажите в чем моя проблема?
источник

РИ

Руслан Исланбеков... in Flutter Developers — русскоговорящее сообщество
поменять имя тоже пробовал
источник

T

Tim in Flutter Developers — русскоговорящее сообщество
Руслан Исланбеков
у меня проблема с иконкой на local notification
иконка приложения в самом пуш уведомлении?
источник

РИ

Руслан Исланбеков... in Flutter Developers — русскоговорящее сообщество
Да
источник

SH

Sergey Hottabych in Flutter Developers — русскоговорящее сообщество
Pavel K
На мой взгляд, это две ситуации с абсолютно разных слоев и, соответственно, обработка у них должна быть разная
Первый кейс с Maintenance
Здесь это нормальное состояние приложения (не эксепшн), поэтому должно прокидываться до экрана
Я, к сожалению, не в курсе твоей архитектуры, но как пример - если у тебя есть некий AppState, который слушает один из виджетов, допустим через bloc, то это могло бы быть следующее

Widget build(BuildContext context) {
AppStateBloc bloc = Provider.of<AppStateBloc>(context);
return StreamBuilder(
 stream: bloc.appState,
 builder: (_, snapshot) {
  ... // разбор состояний snapshot опустим
  final AppState state = snapshot.data;
  if (state is MaintenanceState)
   return MaintenanceScreen(state) // можно передать state если там есть полезные данные для отображения на экране
  ...
  return HomeScreen()
 }
);
}


Случай с Unauthorized - это Service Layer. Допустим у тебя есть некий абстрактный класс Query и есть NetworkClient который умеет их выполнять

abstract class Query<T> {
...
}

abstract class NetworkClient {

Future<dynamic> execute(Query<dynamic> query);

}

Ну и соответственно, уровнем выше, скажем, есть у тебя Repository, который работает с этим клиентом и запросами
Так вот обработку Unathorized можно сделать централизованно внутри NetworkClient
То есть при запуске каждого Query он слушает результат - если прилетает нормальное значение - передаем в ответ
если прилетел Unauthorized - пытаемся отрефрешить токен и дергаем счетчик
если, скажем, три раза были неуспешными - тогда уже прокидываем какое-нибудь специальное состояние до Presentation Layer
где пользователю уже покажем соотв экран
В этом проекте не bloc, а Provider+ChangeNotifier, к которому я хочу прикрутить MobX. Но суть та же.
У нас нет глобального AppState, но думаю, не проблема запилить.
источник