GithubHelp home page GithubHelp logo

contacts's People

Contributors

clmct avatar

Watchers

 avatar

contacts's Issues

Замечания v2

  1. На темной теме выглядит коряво, лучше ее вообще выключить для всего window

  2. UIScrollView+TPKeyboardAvoidingAdditions
    это либо через менеджер зависимостей подключать, либо свой нотификатор написать и вручную менять inset у таблицы/скролла
    вставлять так просто исходники, еще и на обж-си - очень неудобно в поддержке потом

  3. TableViewDataSource
    typealias TitleClosure = (inout String) -> Void
    передавать inout параметры в замыканиях - коварно. Очень легко ошибиться, если далеко передается замыкание
    Лучше передавать как есть и обновлять значение явно

  4. SectionedTableViewDataSource
    typealias DeleteClosure = (Int, Int) -> Void
    лучше в таких случаях именовать параметры в замыкании: (_ section: Int, _ row: Int) -> Void
    а конкретно в этом случае еще лучше просто передавать IndexPath, тк он уже из этого состоит

  5. По папкам: непонятно, почему ComponentsView вынесено на общий уровень, а не находится в модулях, учитывая, что вне модулей оно вроде и не нужно

  6. ContactsListViewController

navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add,
                                                        target: self ,
                                                        action: #selector(addContact))

работу с навбаром лучше выносить в координатор. Пускай контроллер будет создавать кнопку, но задававать навбару ее будет координатор, это избавит контроллер от необходимости париться о том, в каком виде он презентуется

func fetchContacts() {
	coreDataService.fetchContacts { [weak self] result in
	  switch result {
	  case .success(let contacts):
	    self?.contacts = contacts
	    self?.filteredContacts = contacts
	    self?.updateDataSource()
	  case .failure(let error):
	    print(error)
	  }
	}
}

тут хоть и не сетевой запрос, но асинхронный, так что можно добавить крутилку для показа состояния загрузки

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  self?.fetchContacts()
  self?.didUpdateDataSource?()
}

вот это опасно вообще. А если операция будет дольше 0.5с? Раз операция асинхронная, она должна возвращать completion блок, в котором уже точно знаем, что данные поменялись

  1. ContactDetailViewModel
    ImageCreator.imageInitials(name: contact.firstName + " " + (contact.lastName ?? ""))

такие вещи лучше писать через [contact.firstName, contact.lastName].compactMap { $0 }.joined(separator: " ")

  1. ContactAddEditViewController
    func textFieldShouldReturn(_ textField: UITextField) -> Bool

if/else лучше заменить на switch textField

if textField !== contactPhotoView.phoneNumberComponentView.titleTextField { return true }
если делаешь return - нужно делать guard (это форсит return и тогда точно не забудешь)

  1. ContactAddEditViewModel
DispatchQueue.global(qos: .userInteractive).async {
  self.loadImageFromFileSystem(urlString: self.contact.id.uuidString)
  DispatchQueue.main.async {
    if let photo = self.contact.photo {
      self.contactPhotoViewModel.updatePhoto(photo: photo)
    }
  }
}

не нужно отдавать асинхронность таких операций на откуп вызывающего. fileManagerService должен сам иметь свою бэкграунд очередь и сохранять/грузить изображения на ней, отдавать уже в главной очереди

isRequiredInformation - не оч удачное название переменной, обычно такое называют func checkValidity() и переменную isValid

  1. CoreDataStack
    Тут на самом деле достаточно сложный кейс работы с тредами. Общее правило работы с Core Data: читай объекты с главной очреди, записывай объекты в бжкграунд очереди (тк операции записи дороже и могут заблокировать главный тред)
    Тут можно почитать https://duncsand.medium.com/threading-43a9081284e5
    в любом случае надо сделать операцию saveContext асинхронной и на бэкграунд треде
    Обрати внимание: объекты CoreData нельзя передавать между тредами. Если они сохраняются в бэкграунд контексте, они там же и должны создаваться (тут приходит на помощь наша двухслойная модель! Мы можем конвертировать модели в кор датовые уже в бэкграунд контексте)

Замечания #1

Замечания по UI:

  • при создании контакта нету возможности добавить фото/картинку
  • поиск работает только по имени (по фамилии или номеру телефона найти нельзя)
  • при анимации показа экрана добавления контакта под статус баром почему-то появляется таблица
  • переход из режима просмотра в режим редактирования происходит некорректно - в момент перехода экран на секунду переходит в "дефолтный" режим (как при создании профиля)
  • нету подтверждения на удаление контакта (если случайно нажал)
  • хорошо было бы добавить возможность удалять контакт свайпом из списка
  • нету форматирования номера телефона (можно было посмотреть какие сторонние решения есть для этого)

Замечания по коду (общие):

  • стоит поработать с наименованием классов/функций/переменных

TableViewDataSource

  • cellConfigurator и titleConfigurator замыканияя, но названы как модели, лучше придерживаться общих правил наименований и обозвать их как обычно именуют замыкания
  • static func make(for contacts... выглядит как фабрика. Лучше вынести в отдельный фабричный класс.

PickerDataSource

  • функции и переменные возвращающие значения должны иметь ключевое слово return. Исключением являются только inline-замыкания

ContactPhotoView

  • mergeImages(bottomImage: .... такие вещи лучше выносить в утилиты
  • imagePhotoView.backgroundColor - цвета лучше выносить в константы (как это сделано в других местах)

ContactsListCoordinator

  • contactAddCoordinatorDidFinishAndDeleteContact если метод делегата не нужен, лучше сделать его опциональным (есть несколько способов - самый простой через экстеншн)

В целом по коду все хорошо, есть еще минорные замечания по разным моментам, но их можно не брать в расчет.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.