clmct / contacts Goto Github PK
View Code? Open in Web Editor NEWSwift iOS application based on MVVM-C (non-reactive) pattern
Swift iOS application based on MVVM-C (non-reactive) pattern
Замечания по UI:
Замечания по коду (общие):
TableViewDataSource
PickerDataSource
ContactPhotoView
ContactsListCoordinator
В целом по коду все хорошо, есть еще минорные замечания по разным моментам, но их можно не брать в расчет.
На темной теме выглядит коряво, лучше ее вообще выключить для всего window
UIScrollView+TPKeyboardAvoidingAdditions
это либо через менеджер зависимостей подключать, либо свой нотификатор написать и вручную менять inset у таблицы/скролла
вставлять так просто исходники, еще и на обж-си - очень неудобно в поддержке потом
TableViewDataSource
typealias TitleClosure = (inout String) -> Void
передавать inout параметры в замыканиях - коварно. Очень легко ошибиться, если далеко передается замыкание
Лучше передавать как есть и обновлять значение явно
SectionedTableViewDataSource
typealias DeleteClosure = (Int, Int) -> Void
лучше в таких случаях именовать параметры в замыкании: (_ section: Int, _ row: Int) -> Void
а конкретно в этом случае еще лучше просто передавать IndexPath, тк он уже из этого состоит
По папкам: непонятно, почему ComponentsView вынесено на общий уровень, а не находится в модулях, учитывая, что вне модулей оно вроде и не нужно
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 блок, в котором уже точно знаем, что данные поменялись
ContactDetailViewModel
ImageCreator.imageInitials(name: contact.firstName + " " + (contact.lastName ?? ""))
такие вещи лучше писать через [contact.firstName, contact.lastName].compactMap { $0 }.joined(separator: " ")
ContactAddEditViewController
func textFieldShouldReturn(_ textField: UITextField) -> Bool
if/else лучше заменить на switch textField
if textField !== contactPhotoView.phoneNumberComponentView.titleTextField { return true }
если делаешь return - нужно делать guard (это форсит return и тогда точно не забудешь)
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.