77
88import UIKit
99import MapKit
10- import CoreLocation
1110import MessageUI
1211
13- final class CatalogsObjectViewController : UIViewController {
14- private var objectId : String ?
15- private var email : String ?
16- private var phoneNumber : String ?
12+ final class CatalogsObjectViewController : UIViewController , CatalogsObjectViewControllerProtocol {
13+ private var presenter : CatalogsObjectViewPresenterProtocol
1714
1815 private let scrollView : UIScrollView = {
1916 let scrollView = UIScrollView ( )
@@ -120,12 +117,8 @@ final class CatalogsObjectViewController: UIViewController {
120117 return map
121118 } ( )
122119
123- private let catalogsObjectNetworkService = CatalogsObjectNetworkService . shared
124- private var catalogsObjectNetworkServiceObserverData : NSObjectProtocol ?
125- private var catalogsObjectNetworkServiceObserverError : NSObjectProtocol ?
126-
127- init ( objectId: String ) {
128- self . objectId = objectId
120+ init ( presenter: CatalogsObjectViewPresenterProtocol ) {
121+ self . presenter = presenter
129122 super. init ( nibName: nil , bundle: nil )
130123 }
131124
@@ -139,44 +132,47 @@ final class CatalogsObjectViewController: UIViewController {
139132 view. backgroundColor = . systemBackground
140133 configureNavigationBar ( )
141134
142- catalogsObjectNetworkServiceObserverData = NotificationCenter . default
143- . addObserver (
144- forName: CatalogsObjectNetworkService . dataReceivedNotification,
145- object: nil ,
146- queue: . main
147- ) { [ weak self] _ in
148- self ? . configureView ( )
149- }
150- catalogsObjectNetworkServiceObserverError = NotificationCenter . default
151- . addObserver (
152- forName: CatalogsObjectNetworkService . errorNotification,
153- object: nil ,
154- queue: . main
155- ) { [ weak self] _ in
156- self ? . showAlert ( )
157- }
158- loadData ( )
135+ presenter. viewDidLoad ( )
159136 }
160137
161- private func configureNavigationBar ( ) {
162- navigationItem . leftBarButtonItem = UIBarButtonItem ( image : . backArrow , style : . plain , target : self , action : #selector ( backButtonTap ) )
138+ func showHud ( ) {
139+ UIBlockingProgressHUD . show ( )
163140 }
164141
165- private func configureView( ) {
166- guard let model = catalogsObjectNetworkService. catalogsObjectModel else { showAlert ( ) ; return }
142+ func removeHud( ) {
167143 UIBlockingProgressHUD . dismiss ( )
144+ }
145+
146+ func configureView( model: CatalogsObjectModel ) {
168147 configureConstraints ( )
169148 configureImage ( link: URL ( string: model. imageURL) )
170- let adress = " г. " + model. location + " , " + model. address
171149 configureLabels (
172150 name: model. title,
173151 cost: model. price,
174152 date: model. createdDate,
175153 description: model. description,
176- adress: adress)
177- geocodeCity ( cityName: adress)
178- email = model. email
179- phoneNumber = model. phoneNumber
154+ adress: presenter. adress)
155+ }
156+
157+ func showAlert( alert: UIAlertController ) {
158+ present ( alert, animated: true )
159+ }
160+
161+ func showMailComposer( mailComposer: MFMailComposeViewController ) {
162+ present ( mailComposer, animated: true , completion: nil )
163+ }
164+
165+ func showCallAction( phoneURL: URL ) {
166+ UIApplication . shared. open ( phoneURL, options: [ : ] , completionHandler: nil )
167+ }
168+
169+ func setupMap( annotation: MKPointAnnotation , region: MKCoordinateRegion ) {
170+ mapView. addAnnotation ( annotation)
171+ mapView. setRegion ( region, animated: true )
172+ }
173+
174+ private func configureNavigationBar( ) {
175+ navigationItem. leftBarButtonItem = UIBarButtonItem ( image: . backArrow, style: . plain, target: self , action: #selector( backButtonTap) )
180176 }
181177
182178 private func configureConstraints( ) {
@@ -246,90 +242,16 @@ final class CatalogsObjectViewController: UIViewController {
246242 adressLabel. text = adress
247243 }
248244
249- private func showAlert( ) {
250- UIBlockingProgressHUD . dismiss ( )
251- let alertTitle = NSLocalizedString ( " alert.title " , comment: " Название алерта " )
252- let alertMessage = NSLocalizedString ( " alert.message " , comment: " Сообщение в алерте " )
253- let alertActionRetryTitle = NSLocalizedString ( " alert.action.again " , comment: " Название действия повторения в алерте " )
254- let alertActionLeaveTitle = NSLocalizedString ( " alert.action.leave " , comment: " Название действия выхода в алерте " )
255-
256- let actionRetry = UIAlertAction ( title: alertActionRetryTitle, style: . default) { [ weak self] _ in
257- self ? . loadData ( )
258- }
259- let actionLeave = UIAlertAction ( title: alertActionLeaveTitle, style: . default) { [ weak self] _ in
260- self ? . dismiss ( animated: true )
261- self ? . backButtonTap ( )
262- }
263-
264- let alert = UIAlertController ( title: alertTitle, message: alertMessage, preferredStyle: . alert)
265- alert. addAction ( actionRetry)
266- alert. addAction ( actionLeave)
267- present ( alert, animated: true )
268- }
269-
270- private func loadData( ) {
271- guard let objectId = objectId else { return }
272- UIBlockingProgressHUD . show ( )
273- catalogsObjectNetworkService. fetch ( id: objectId)
245+ @objc func backButtonTap( ) {
246+ navigationController? . popViewController ( animated: true )
274247 }
275248
276249 @objc private func callButtonTap( ) {
277- guard let phoneNumber = phoneNumber else { return }
278- if let phoneURL = URL ( string: " tel:// \( phoneNumber. replacingOccurrences ( of: " " , with: " " ) ) " ) {
279- if UIApplication . shared. canOpenURL ( phoneURL) {
280- UIApplication . shared. open ( phoneURL, options: [ : ] , completionHandler: nil )
281- } else {
282- // На симуляторе этот вариант будет срабатывать
283- print ( " Невозможно совершить звонок " )
284- }
285- }
250+ presenter. viewDidTapCallButton ( )
286251 }
287252
288253 @objc private func mailButtonTap( ) {
289- guard let email = email else { return }
290- if MFMailComposeViewController . canSendMail ( ) {
291- let mailComposer = MFMailComposeViewController ( )
292- mailComposer. mailComposeDelegate = self
293- mailComposer. setToRecipients ( [ email] )
294- present ( mailComposer, animated: true , completion: nil )
295- } else {
296- // На симуляторе этот вариант будет срабатывать
297- print ( " Почтовый клиент недоступен " )
298- }
299- }
300-
301- @objc private func backButtonTap( ) {
302- navigationController? . popViewController ( animated: true )
303- }
304- }
305-
306- extension CatalogsObjectViewController {
307- func geocodeCity( cityName: String ) {
308- guard !cityName. isEmpty else { return }
309- let geocoder = CLGeocoder ( )
310- geocoder. geocodeAddressString ( cityName) { placemarks, error in
311- if let error = error {
312- print ( " Координаты не найдены: \( error. localizedDescription) " )
313- self . geocodeCity ( cityName: cityName. split ( separator: " , " ) . first? . description ?? " " )
314- return
315- }
316-
317- if let location = placemarks? . first? . location? . coordinate {
318- self . setupMapWithCoordinate ( coordinate: location, title: cityName)
319- } else {
320- print ( " Координаты не найдены. " )
321- }
322- }
323- }
324-
325- func setupMapWithCoordinate( coordinate: CLLocationCoordinate2D , title: String ) {
326- let annotation = MKPointAnnotation ( )
327- annotation. coordinate = coordinate
328- annotation. title = title
329-
330- mapView. addAnnotation ( annotation)
331- let region = MKCoordinateRegion ( center: coordinate, latitudinalMeters: 10000 , longitudinalMeters: 10000 )
332- mapView. setRegion ( region, animated: true )
254+ presenter. viewDidTapMailButton ( )
333255 }
334256}
335257
0 commit comments