-
[iOS] API 통신 및 지도 Marker 분리ToyProject 2023. 9. 28. 16:00
<결과물 먼저 보여주면, 아래와 같이 위치에 맞게 마커를 뿌려주고, 마커를 클릭하면 해당 음식점에 대한 정보가 보이도록 구현했다!>
음식점 종류에 맞게 Marker 이미지를 분리해서 지도에 표시해보았다!
1. 내위치 Marker
: 내 위치 마커는 현재 위치를 보여주는 마커로, 상단에 "내 위치 재검색" 버튼을 누르면 현재 위치로 돌아가서 마커가 보일 수 있도록 해주었다!
// 내 위치 마커 let my_marker = NMFMarker() // 마커 위치 my_marker.position = NMGLatLng(lat:latitude,lng: longitude) // 마커 이미지 my_marker.iconImage = NMFOverlayImage(name: "me") // 마커 크기 my_marker.width = 60 my_marker.height = 60 // 타입 이미지 self.typeImage.image = UIImage(named: "me") // 이름 텍스트 self.nameText.text = "현재 위치" // 마커 캡션 my_marker.captionText = "내 위치" my_marker.captionOffset = 5 my_marker.captionColor = UIColor.black my_marker.touchHandler = { (overlay: NMFOverlay) -> Bool in if self.addressView.isHidden { my_marker.width = 60 my_marker.height = 60 self.typeImage.image = UIImage(named: "me") self.nameText.text = "현재 위치" my_marker.captionText = "내 위치" my_marker.captionOffset = 5 my_marker.captionColor = UIColor.black self.addressView.isHidden = false return true // 이벤트 소비, -mapView:didTapMap:point 이벤트는 발생하지 않음 } else { my_marker.width = 50 my_marker.height = 50 self.addressView.isHidden = true my_marker.captionText = "" return false // 이벤트 넘겨줌, -mapView:didTapMap:point 이벤트가 발생할 수 있음 } }
: 마커를 클릭하면 "내 위치"라는 text가 하단에 나오고, 다시 지도를 클릭하게 되면 사라지도록 해두었다!
2. API 통신 및 Marker 분리
: URLSession을 이용해서 통신했으며, 통신이 정상적으로 되었다면, 미리 만들어둔 data Model에 데이터를 담아서 type에 따라 marker 이미지와 text를 분류했다!
→ 데이터 구조가 잡기 어렵다면? (아래 블로그 참고)
Instantly parse JSON in any language | quicktype
app.quicktype.io
// MARK: - DataModelElement struct DataModelElement: Codable { let id: Int let name: String let type: String let latitude, longitude: Double let address: String } typealias DataModel = [DataModelElement]
이미지는 Asset 파일에 미리 저장해두었다!
// API 통신 (localhost) guard let url = URL(string: "http://localhost:8080/main") else { print("Invalid URL") return } let task = URLSession.shared.dataTask(with: url) { (data, response, error) in if let error = error { print("Error: \(error.localizedDescription)") return } guard let httpResponse = response as? HTTPURLResponse else { print("Invalid HTTP response") return } if httpResponse.statusCode == 200 { if let data = data { do { let decoder = JSONDecoder() // dataModel에 받아온 정보 담기 let dataModel = try decoder.decode([DataModelElement].self, from: data) // 비동기 처리 DispatchQueue.main.async { for dataElement in dataModel { // 마커 생성 let new_marker = NMFMarker() // 마커 위치 new_marker.position = NMGLatLng(lat: dataElement.latitude, lng: dataElement.longitude) // 업태 분류 if(dataElement.type == "한식") { new_marker.iconImage = NMFOverlayImage(name: "rice") } else if(dataElement.type == "분식") { new_marker.iconImage = NMFOverlayImage(name: "tteokbokki") } else if(dataElement.type == "커피숍") { new_marker.iconImage = NMFOverlayImage(name: "coffee") } else if(dataElement.type == "제과영업점") { new_marker.iconImage = NMFOverlayImage(name: "bread") } else if(dataElement.type == "경양식") { new_marker.iconImage = NMFOverlayImage(name: "tonkatsu") } else if(dataElement.type == "호프/통닭") { new_marker.iconImage = NMFOverlayImage(name: "chicken") } else if(dataElement.type == "패밀리 레스토랑") { new_marker.iconImage = NMFOverlayImage(name: "restaurant") } else if(dataElement.type == "중국식") { new_marker.iconImage = NMFOverlayImage(name: "jjajangmyeon") } else if(dataElement.type == "패스트푸드") { new_marker.iconImage = NMFOverlayImage(name: "hamburger") } else if(dataElement.type == "일식") { new_marker.iconImage = NMFOverlayImage(name: "sushi") } new_marker.width = 40 new_marker.height = 40 new_marker.touchHandler = { (overlay: NMFOverlay) -> Bool in if self.addressView.isHidden { if(dataElement.type == "한식") { self.typeImage.image = UIImage(named: "rice") } else if(dataElement.type == "분식") { self.typeImage.image = UIImage(named: "tteokbokki") } else if(dataElement.type == "커피숍") { self.typeImage.image = UIImage(named: "coffee") } else if(dataElement.type == "제과영업점") { self.typeImage.image = UIImage(named: "bread") } else if(dataElement.type == "경양식") { self.typeImage.image = UIImage(named: "tonkatsu") } else if(dataElement.type == "호프/통닭") { self.typeImage.image = UIImage(named: "chicken") } else if(dataElement.type == "패밀리 레스토랑") { self.typeImage.image = UIImage(named: "restaurant") } else if(dataElement.type == "중국식") { self.typeImage.image = UIImage(named: "jjajangmyeon") } else if(dataElement.type == "패스트푸드") { self.typeImage.image = UIImage(named: "hamburger") } else if(dataElement.type == "일식") { self.typeImage.image = UIImage(named: "sushi") } new_marker.width = 50 new_marker.height = 50 self.addressText.text = dataElement.address self.nameText.text = dataElement.name new_marker.captionText = dataElement.name new_marker.captionOffset = 5 new_marker.captionColor = UIColor.black self.addressView.isHidden = false return true // 이벤트 소비, -mapView:didTapMap:point 이벤트는 발생하지 않음 } else { if(dataElement.type == "한식") { self.typeImage.image = UIImage(named: "rice") } else if(dataElement.type == "분식") { self.typeImage.image = UIImage(named: "tteokbokki") } else if(dataElement.type == "커피숍") { self.typeImage.image = UIImage(named: "coffee") } else if(dataElement.type == "제과영업점") { self.typeImage.image = UIImage(named: "bread") } else if(dataElement.type == "경양식") { self.typeImage.image = UIImage(named: "tonkatsu") } else if(dataElement.type == "호프/통닭") { self.typeImage.image = UIImage(named: "chicken") } else if(dataElement.type == "패밀리 레스토랑") { self.typeImage.image = UIImage(named: "restaurant") } else if(dataElement.type == "중국식") { self.typeImage.image = UIImage(named: "jjajangmyeon") } else if(dataElement.type == "패스트푸드") { self.typeImage.image = UIImage(named: "hamburger") } else if(dataElement.type == "일식") { self.typeImage.image = UIImage(named: "sushi") } new_marker.width = 40 new_marker.height = 40 self.addressView.isHidden = true new_marker.captionText = "" return false // 이벤트 넘겨줌, -mapView:didTapMap:point 이벤트가 발생할 수 있음 } } new_marker.mapView = mapView } } } catch { print("Error decoding data: \(error.localizedDescription)") } } else { print("No data received") } } else { print("HTTP status code: \(httpResponse.statusCode)") } } task.resume() print(latitude) print(longitude) // Do any additional setup after loading the view. }
'ToyProject' 카테고리의 다른 글
[DB] #9 주소값 위도, 경도로 바꾸기 (0) 2023.07.10 [Spring] #8 Spring, MySQL 연동 및 API 생성 (0) 2023.06.21 [DB] #7 ERD Cloud 이용해서 DB 설계 및 SQL 사용하기 (0) 2023.06.21 [DB] #6 DataGrip 이용해서 CSV 파일 Import (0) 2023.06.21 [iOS] #5 Naver 지도 API 내 위치 찾기 & Marker 이미지 변경 (0) 2023.06.21