-
Notifications
You must be signed in to change notification settings - Fork 34
Network layer refactoring #262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
kvld
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В качестве небольшого вброса: может быть заюзать Codable из Swift 4 и повыпиливать SwiftyJSON?
Stepic/APIEndpoint.swift
Outdated
| } | ||
|
|
||
| func getObjectsByIds<T: JSONInitializable>(ids: [T.idType], updating: [T], headers: [String: String] = AuthInfo.shared.initialHTTPHeaders, printOutput: Bool = false) -> Promise<([T])> { | ||
| func getObjectsByIds<T: JSONSerializable>(ids: [T.idType], updating: [T], printOutput: Bool = false) -> Promise<([T])> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
В этом методе мы и дёргаем API, и работаем с CoreData. Может вынести работу с кордатой в отдельный слой?
То есть, я предлагаю на этом уровне только работать с сетью и получать JSON, а мердж и создание сущностей делать в отдельном классе.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Конкретно про этот метод - думаю это просто в RetrieveRequestRetrier запилить.
Вынести работу с кордатой в отдельный слой обязательно надо, но на данном этапе это пока сложно и долго реализовывать. Думаю, постепенно будем переделывать все на работу с Plain Object-ами, да.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
На самом деле, вообще во всех местах, которые относятся к работе с сетью.
Stepic/ApiRequestRetrier.swift
Outdated
| if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 && request.retryCount == 0 { | ||
| checkToken().then { | ||
| completion(true, 0.0) | ||
| }.catch { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Сломалось форматирование. Может нам завезти какой-нибудь code formatter перед коммитом?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SwiftLint есть, он просто на это не реагирует
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ок, но давай поправим всё же?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
да, пропустил
Stepic/AuthAPI.swift
Outdated
| } else { | ||
| failure(SignInError.other(error: error, code: nil, message: nil)) | ||
| } | ||
| }.catch { error in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тоже беда с форматированием (здесь и ниже).
Stepic/Notification.swift
Outdated
| } | ||
|
|
||
| static func fetchAsync(ids: [Int]) -> Promise<[Notification]> { | ||
| return DatabaseFetchService.fetchAsync(entityName: "Notification", ids: ids) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Если правда, что реализация fetchAsync в разных сущностях отличается только разными entityName, то можно сделать дефолтную реализацию и передавать туда String(describing: self)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
отличная идея!
| reject(error) | ||
| } | ||
| ) | ||
| // This is a correct replacement after CoreData duplicates fix for this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Пока не очень понятно, бага это или нет, и на что она влияет. Если бага, то надо будет заменить то, что выше, на то, что сейчас закомменчено
|
Осталось только выпилить все ненужные вызовы checkToken() из не-network слоя и все готово |
kvld
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Некоторые вещи не стал комментировать по несколько раз, обрати внимание (force try, форматирование, обращение по несуществующему индексу, ...).
Stepic/Assignment.swift
Outdated
| } | ||
|
|
||
| var json: JSON { | ||
| return [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А почему здесь []? Assignment не сериализуется по-другому?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Так в очень многих сущностях. Будем переделывать по мере необходимости (нужно только для create и update запросов)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Сейчас добавлю дефолтную реализацию
| import SwiftyJSON | ||
| import CoreData | ||
|
|
||
| class DatabaseFetchService { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Файл AsyncFetchService.swift, а класс DatabaseFetchService.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Спасибо, подловил, я проверял твою внимательность ![]()
Stepic/AsyncFetchService.swift
Outdated
| let descriptor = NSSortDescriptor(key: "managedId", ascending: false) | ||
|
|
||
| let idPredicates = ids.map { | ||
| NSPredicate(format: "managedId == %@", $0 as? NSNumber ?? $0 as! String) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вот это какая-то странная запись, особенно "хвост" с nil-coalescing. Почему мы значение типа T.idType force-кастуем в String, если нам вообще не известно, что это за тип и может ли он кастоваться?
Может в объявлении associatedtype idType стоит обозначить, что этот тип должен конвертиться в строку, реализуя какой-то протокол?
idType, кстати, неплохо бы переименовать во всех местах в IdType
| func create(stepName: String, stepId: Int) -> Promise<Attempt> { | ||
| let attempt = Attempt(step: stepId) | ||
| return Promise { fulfill, reject in | ||
| create.request(requestEndpoint: "attempts", paramName: "attempt", creatingObject: attempt, withManager: manager).then { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А зачем нам name, если мы передаем отдельно эндпойнт?
paramName может быть тоже стоит вынести в APIEndpoint (это ведь просто название сущности)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Да, от name надо избавляться, но пока есть проблемные классы с этим повременим
Stepic/Certificate.swift
Outdated
| return id == json["id"].int | ||
| } | ||
|
|
||
| var json: JSON { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Аналогично Assignment (и может быть дальше тоже есть такие места).
Stepic/QuizPresenter.swift
Outdated
|
|
||
| private func submit(reply: Reply, completion: @escaping (() -> Void), error errorHandler: @escaping ((String) -> Void)) { | ||
| let id = attempt!.id! | ||
| let id = attempt!.id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional attempt, на котором делаем force-unwrapping.
| if updatingObject != nil { | ||
| updatingObject?.update(json: json[paramName].arrayValue[0]) | ||
| } else { | ||
| fulfill(T(json: json[paramName].arrayValue[0])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А arrayValue может быть пустым?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Возможно. Надо будет это убрать при рефакторинге ошибок
| import Foundation | ||
| import SwiftyJSON | ||
|
|
||
| class StepikModelView: JSONSerializable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А что раньше было вместо View? Ничего не было?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Да, ничего не было
Stepic/User.swift
Outdated
| lastName = json["last_name"].stringValue | ||
| } | ||
|
|
||
| init(sample: Bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
старая фигня, надо убрать
Stepic/UserActivitiesAPI.swift
Outdated
| } | ||
|
|
||
| //TODO: Add parameters | ||
| //TODO: This is never used, remove |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай удалим?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
неплохая идея
kvld
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Теперь хорошо, но нужно починить тесты падающие и после можно мерджить.
Stepic/UserActivitiesAPI.swift
Outdated
| } | ||
| let response = response.response | ||
| retrieve(user: userId).then { | ||
| UserActivity in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UserActivity -> userActivity
Задача: #APPS-1830
Коротко для Release Notes, в формате «Сделали/Добавили/Исправили N»:
Рефакторинг слоя работы с сетью
Описание:
Для того, чтобы перестать использовать параметр
headersв запросах, теперь используется классApiRequestRetrier, который отвечает за повторение запроса в случае, если мы поймали error, а также подставляет нужные авторизационные хедеры в запросы.В
APIEndpointдобавлены поляupdate: UpdateRequestMaker,delete: DeleteRequestMaker,create: CreateRequestMakerиretrieve: RetrieveRequestMaker, отвечающие за различные запросы к серверу.Все
checkToken()вызовы делаются теперь при запросах внутриRequestMakerклассов.Для фетча данных из БД добавлен класс
DatabaseFetchServicec generic методомfetchAsync<T: IDFetchable>(), который асинхронно фетчит нужные объекты из базы данных.Протокол
JSONInitializableпереименован вJSONSerializable. Добавлен протоколIDFetchableдля моделей, обновляющихся из базы данных при загрузке.Некоторые API-классы пока не трогаем, так как там есть различные моменты, требующие большего дополнительного вмешательства.
Добавилось больше deprecated методов. Где была возможность, подменял реализацию методов на новую.
Еще много где есть комментарии, которые хорошо бы учесть при дальнейших попытках рефакторить все, что связано с Network слоем.
Остались еще классы, которые я не успел поменять, но я работаю над этим в поте лица.