@@ -79,18 +79,19 @@ final class MapViewController: BaseViewController {
79
79
}
80
80
81
81
override func viewWillAppear( _: Bool ) {
82
- fetchPartnerships ( )
83
- setInitialSegmentedControlSetting ( )
82
+ fetchAllPartnershipsAndDisplay ( )
83
+ resetSegmentedControlToDefault ( )
84
84
}
85
+ }
85
86
86
- // MARK: - UI 설정
87
-
87
+ // MARK: - UI Configuration
88
+ private extension MapViewController {
88
89
/**
89
90
네비게이션 바 스타일을 설정합니다.
90
91
91
92
- Note: 배경색, 타이틀 폰트, 스크롤 시의 Appearance 등을 지정합니다.
92
93
*/
93
- private func configureNavigationBar( ) {
94
+ func configureNavigationBar( ) {
94
95
navigationItem. title = ESTextLiteral . Map. mapNavTitle
95
96
navigationController? . isNavigationBarHidden = false
96
97
@@ -113,11 +114,11 @@ final class MapViewController: BaseViewController {
113
114
- Note: 지도에서 터치 이벤트를 수신하기 위해 `touchDelegate`를 `self`로 설정합니다.
114
115
- SeeAlso: `moveCamera(to:zoomLevel:)`
115
116
*/
116
- private func configureMapView( ) {
117
+ func configureMapView( ) {
117
118
mapView = NMFMapView ( frame: view. frame)
118
119
view. addSubview ( mapView)
119
120
mapView. touchDelegate = self
120
- moveCamera ( to : soongsilUniversityLocation, zoomLevel: 15.0 )
121
+ moveCameraToLocation ( soongsilUniversityLocation, zoomLevel: 15.0 )
121
122
}
122
123
123
124
/**
@@ -127,7 +128,7 @@ final class MapViewController: BaseViewController {
127
128
- location: 이동할 위치의 위도 및 경도 (`NMGLatLng`)
128
129
- zoomLevel: 줌 레벨 (`Double`)
129
130
*/
130
- private func moveCamera ( to location: NMGLatLng , zoomLevel: Double ) {
131
+ func moveCameraToLocation ( _ location: NMGLatLng , zoomLevel: Double ) {
131
132
let cameraUpdate = NMFCameraUpdate ( position: NMFCameraPosition ( location, zoom: zoomLevel) )
132
133
mapView. moveCamera ( cameraUpdate)
133
134
}
@@ -139,7 +140,7 @@ final class MapViewController: BaseViewController {
139
140
140
141
- Note: Segmented Control 클릭 시 `segmentedControlChanged(_:)`를 통해 새로운 데이터를 불러오거나, 기존 마커를 지우고 다시 표시합니다.
141
142
*/
142
- private func configureSegmentedControl( ) {
143
+ func configureSegmentedControl( ) {
143
144
let items = [ " 전체 " , " 내 제휴 " ]
144
145
mapSegmentedControl = UISegmentedControl ( items: items)
145
146
mapSegmentedControl. selectedSegmentIndex = 0
@@ -170,7 +171,12 @@ final class MapViewController: BaseViewController {
170
171
view. bringSubviewToFront ( mapSegmentedControl)
171
172
}
172
173
173
- private func setInitialSegmentedControlSetting( ) {
174
+ /**
175
+ 세그먼트 컨트롤을 기본 상태(전체)로 초기화합니다.
176
+
177
+ - Note: viewWillAppear에서 호출되어 화면이 나타날 때마다 세그먼트 컨트롤을 초기 상태로 되돌립니다.
178
+ */
179
+ func resetSegmentedControlToDefault( ) {
174
180
mapSegmentedControl. selectedSegmentIndex = 0
175
181
}
176
182
@@ -183,8 +189,8 @@ final class MapViewController: BaseViewController {
183
189
1. 0(기본: "내 제휴") 선택 시 전체 제휴 업체 데이터를 불러옵니다.
184
190
2. 1("전체") 선택 시 사용자의 제휴 업체 데이터(미구현)를 불러옵니다.
185
191
*/
186
- @objc private func segmentedControlChanged( _ sender: UISegmentedControl ) {
187
- clearAllMarkers ( )
192
+ @objc func segmentedControlChanged( _ sender: UISegmentedControl ) {
193
+ removeAllMarkersFromMap ( )
188
194
189
195
#if DEBUG
190
196
print ( " Selected segment index: \( sender. selectedSegmentIndex) " )
@@ -195,12 +201,12 @@ final class MapViewController: BaseViewController {
195
201
#if DEBUG
196
202
print ( " 전체 제휴 업체를 가져옵니다. " )
197
203
#endif
198
- fetchPartnerships ( )
204
+ fetchAllPartnershipsAndDisplay ( )
199
205
case 1 :
200
206
#if DEBUG
201
207
print ( " 사용자의 제휴 업체를 가져옵니다. " )
202
208
#endif
203
- fetchUserPartnership ( )
209
+ fetchUserPartnershipsAndDisplay ( )
204
210
default :
205
211
AlertControllerHelper . showConfirmAlert (
206
212
title: " 에러 " ,
@@ -209,9 +215,10 @@ final class MapViewController: BaseViewController {
209
215
)
210
216
}
211
217
}
218
+ }
212
219
213
- // MARK: - 마커 설정
214
-
220
+ // MARK: - Marker Management
221
+ private extension MapViewController {
215
222
/**
216
223
특정 위치에 마커를 추가합니다.
217
224
@@ -222,7 +229,7 @@ final class MapViewController: BaseViewController {
222
229
- markerData: 해당 마커에 대응하는 `MarkerData` (상세보기용 정보)
223
230
- Note: 마커를 탭하면 `presentMarkerDetailFloatingPanel(with:)`가 호출되어 상세 패널이 표시됩니다.
224
231
*/
225
- private func addMarker (
232
+ func createAndAddMarker (
226
233
at location: NMGLatLng ,
227
234
leftText: String ,
228
235
rightText: String ,
@@ -236,7 +243,7 @@ final class MapViewController: BaseViewController {
236
243
#if DEBUG
237
244
print ( " 마커가 탭되었습니다! " )
238
245
#endif
239
- self . presentMarkerDetailFloatingPanel ( with: markerData)
246
+ self . showMarkerDetailPanel ( with: markerData)
240
247
return true
241
248
} ,
242
249
markerData: markerData
@@ -250,15 +257,42 @@ final class MapViewController: BaseViewController {
250
257
251
258
- Note: `esMarkers` 배열에 저장된 `ESMarker`를 순회하며, 지도에서 제거(MapView 연결 해제)한 뒤 배열을 비웁니다.
252
259
*/
253
- private func clearAllMarkers ( ) {
260
+ func removeAllMarkersFromMap ( ) {
254
261
for marker in esMarkers {
255
262
marker. marker. mapView = nil
256
263
}
257
264
esMarkers. removeAll ( )
258
265
}
259
266
260
- // MARK: - 상세정보 표시
267
+ /**
268
+ 파트너십 응답 데이터를 기반으로 지도에 마커들을 생성하고 표시합니다.
269
+
270
+ - Parameter partnerships: 서버로부터 받은 파트너십 응답 데이터 배열
271
+ - Note: 각 파트너십 데이터에 대해 위치 정보와 마커 데이터를 생성하여 지도에 표시합니다.
272
+ */
273
+ func displayPartnershipsOnMap( from partnerships: [ PartnershipResponse ] ) {
274
+ for partnership in partnerships {
275
+ let location = NMGLatLng (
276
+ lat: partnership. latitude,
277
+ lng: partnership. longitude
278
+ )
279
+ let markerData = MarkerData (
280
+ title: partnership. storeName,
281
+ description: partnership. description
282
+ )
261
283
284
+ createAndAddMarker (
285
+ at: location,
286
+ leftText: partnership. storeName,
287
+ rightText: partnership. partnershipType,
288
+ markerData: markerData
289
+ )
290
+ }
291
+ }
292
+ }
293
+
294
+ // MARK: - FloatingPanel Management
295
+ private extension MapViewController {
262
296
/**
263
297
마커 상세 정보를 `FloatingPanel`로 표시합니다.
264
298
@@ -267,7 +301,7 @@ final class MapViewController: BaseViewController {
267
301
1. 이미 동일한 마커가 선택되어 있고, 패널이 표시 중이면 그대로 유지합니다.
268
302
2. 새로운 마커를 탭하면, `MarkerDetailViewController`를 생성해 패널 내용으로 설정하고 부모에 추가합니다.
269
303
*/
270
- private func presentMarkerDetailFloatingPanel ( with markerData: MarkerData ) {
304
+ func showMarkerDetailPanel ( with markerData: MarkerData ) {
271
305
if let currentData = selectedMarkerData, currentData == markerData,
272
306
floatingPanelController? . parent != nil
273
307
{
@@ -292,17 +326,18 @@ final class MapViewController: BaseViewController {
292
326
floatingPanelController? . addPanel ( toParent: self )
293
327
}
294
328
}
329
+ }
295
330
296
- // MARK: - 네트워크
297
-
331
+ // MARK: - Network Operations
332
+ private extension MapViewController {
298
333
/**
299
334
전체 제휴 목록을 네트워크로부터 가져오는 메서드입니다.
300
335
301
336
- Note:
302
337
1. 성공 시 `baseResponse.result`에 포함된 제휴 정보를 순회하며, 지도 위에 마커를 배치합니다.
303
338
2. 실패 시 디버그 로그를 남기고, 필요 시 사용자에게 알림을 표시하도록 TODO를 남겼습니다.
304
339
*/
305
- private func fetchPartnerships ( ) {
340
+ func fetchAllPartnershipsAndDisplay ( ) {
306
341
partnershipService. fetchAllPartnerships ( )
307
342
. subscribe (
308
343
onSuccess: { [ weak self] ( baseResponse: BaseResponse < [ PartnershipResponse ] > ) in
@@ -319,16 +354,24 @@ final class MapViewController: BaseViewController {
319
354
return
320
355
}
321
356
322
- createMarkers ( from: baseResponse. result)
357
+ displayPartnershipsOnMap ( from: baseResponse. result)
323
358
} ,
324
359
onFailure: { [ weak self] error in
325
- self ? . handlePartnershipError ( error)
360
+ self ? . showPartnershipErrorAlert ( error)
326
361
}
327
362
)
328
363
. disposed ( by: disposeBag)
329
364
}
330
365
331
- private func fetchUserPartnership( ) {
366
+ /**
367
+ 사용자의 학과/단과대 관련 제휴 목록을 네트워크로부터 가져와 표시하는 메서드입니다.
368
+
369
+ - Note:
370
+ 1. UserDepartmentService를 통해 사용자의 학과/단과대 관련 제휴 정보를 요청합니다.
371
+ 2. 성공 시 받아온 제휴 정보를 지도에 마커로 표시합니다.
372
+ 3. 실패 시 사용자에게 에러 알림을 표시합니다.
373
+ */
374
+ func fetchUserPartnershipsAndDisplay( ) {
332
375
userDepartmentService. getUserPartnership ( )
333
376
. subscribe (
334
377
onSuccess: { [ weak self] ( baseResponse: BaseResponse < [ PartnershipResponse ] > ) in
@@ -345,18 +388,35 @@ final class MapViewController: BaseViewController {
345
388
return
346
389
}
347
390
348
- createMarkers ( from: baseResponse. result)
391
+ displayPartnershipsOnMap ( from: baseResponse. result)
349
392
} ,
350
393
onFailure: { [ weak self] error in
351
- self ? . handlePartnershipError ( error)
394
+ self ? . showPartnershipErrorAlert ( error)
352
395
}
353
396
)
354
397
. disposed ( by: disposeBag)
355
398
}
399
+
400
+ /**
401
+ 파트너십 데이터 요청 실패 시 에러 알림을 표시하는 함수입니다.
402
+
403
+ - Parameter error: 발생한 에러 객체
404
+ - Note: 디버그 모드에서는 에러 상세 정보를 로그로 출력하고, 사용자에게는 간단한 에러 메시지를 알림으로 표시합니다.
405
+ */
406
+ func showPartnershipErrorAlert( _ error: Error ) {
407
+ #if DEBUG
408
+ print ( " 제휴 목록 가져오기 실패: \( error. localizedDescription) " )
409
+ #endif
410
+ AlertControllerHelper . showConfirmAlert (
411
+ title: " 문제가 발생했습니다 " ,
412
+ message: " 다시 시도하세요 " ,
413
+ confirmTitle: " 확인 " ,
414
+ in: self
415
+ )
416
+ }
356
417
}
357
418
358
419
// MARK: - NMFMapViewTouchDelegate
359
-
360
420
extension MapViewController : NMFMapViewTouchDelegate {
361
421
/**
362
422
사용자가 지도에서 단일 탭했을 때 호출됩니다.
@@ -398,7 +458,6 @@ extension MapViewController: NMFMapViewTouchDelegate {
398
458
}
399
459
400
460
// MARK: - FloatingPanelControllerDelegate
401
-
402
461
extension MapViewController : FloatingPanelControllerDelegate {
403
462
/**
404
463
FloatingPanel이 제거되었을 때 호출됩니다.
@@ -411,39 +470,3 @@ extension MapViewController: FloatingPanelControllerDelegate {
411
470
selectedMarkerData = nil
412
471
}
413
472
}
414
-
415
- private extension MapViewController {
416
- /// 파트너십 응답 데이터를 기반으로 지도에 마커를 생성하는 함수
417
- func createMarkers( from partnerships: [ PartnershipResponse ] ) {
418
- for partnership in partnerships {
419
- let location = NMGLatLng (
420
- lat: partnership. latitude,
421
- lng: partnership. longitude
422
- )
423
- let markerData = MarkerData (
424
- title: partnership. storeName,
425
- description: partnership. description
426
- )
427
-
428
- addMarker (
429
- at: location,
430
- leftText: partnership. storeName,
431
- rightText: partnership. partnershipType,
432
- markerData: markerData
433
- )
434
- }
435
- }
436
-
437
- /// 파트너십 데이터 요청 실패 시 처리하는 함수
438
- func handlePartnershipError( _ error: Error ) {
439
- #if DEBUG
440
- print ( " 제휴 목록 가져오기 실패: \( error. localizedDescription) " )
441
- #endif
442
- AlertControllerHelper . showConfirmAlert (
443
- title: " 문제가 발생했습니다 " ,
444
- message: " 다시 시도하세요 " ,
445
- confirmTitle: " 확인 " ,
446
- in: self
447
- )
448
- }
449
- }
0 commit comments