Git Product home page Git Product logo

contacts's People

Contributors

clmct avatar

Watchers

 avatar

contacts's Issues

Замечания #1

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

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

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

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

TableViewDataSource

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

PickerDataSource

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

ContactPhotoView

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

ContactsListCoordinator

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

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

Замечания 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 нельзя передавать между тредами. Если они сохраняются в бэкграунд контексте, они там же и должны создаваться (тут приходит на помощь наша двухслойная модель! Мы можем конвертировать модели в кор датовые уже в бэкграунд контексте)

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.