Skip to content

Commit

Permalink
[Merge] #319 - 위경도로 식당 상세 지도 및 주소 띄우기
Browse files Browse the repository at this point in the history
  • Loading branch information
EunsuSeo01 authored Jan 1, 2025
2 parents cb23b69 + bf91d9e commit a13e6d3
Show file tree
Hide file tree
Showing 22 changed files with 452 additions and 68 deletions.
36 changes: 36 additions & 0 deletions Hankkijogbo/Hankkijogbo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@
A23D11972C47FFB90023480C /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23D11962C47FFB90023480C /* SearchViewModel.swift */; };
A23D119A2C4811790023480C /* HankkiDebouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23D11992C4811790023480C /* HankkiDebouncer.swift */; };
A23D119C2C4844AE0023480C /* PostHankkiValidateRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23D119B2C4844AE0023480C /* PostHankkiValidateRequestDTO.swift */; };
A23F354F2D2211B200B6F8C8 /* NaverMapAPIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23F354E2D2211B200B6F8C8 /* NaverMapAPIService.swift */; };
A23F35512D2211BF00B6F8C8 /* NaverMapTargetType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23F35502D2211BF00B6F8C8 /* NaverMapTargetType.swift */; };
A23F35552D22135200B6F8C8 /* GetHankkiAddressResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23F35542D22135200B6F8C8 /* GetHankkiAddressResponseDTO.swift */; };
A240EA082C3EF6E0000FF458 /* BufferView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A240EA072C3EF6E0000FF458 /* BufferView.swift */; };
A240EA0C2C3EFD77000FF458 /* CompositionalLayoutFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A240EA0B2C3EFD77000FF458 /* CompositionalLayoutFactory.swift */; };
A240EA192C3F35BC000FF458 /* SearchBarCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A240EA182C3F35BC000FF458 /* SearchBarCollectionViewCell.swift */; };
Expand Down Expand Up @@ -400,6 +403,9 @@
A23D11962C47FFB90023480C /* SearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = "<group>"; };
A23D11992C4811790023480C /* HankkiDebouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HankkiDebouncer.swift; sourceTree = "<group>"; };
A23D119B2C4844AE0023480C /* PostHankkiValidateRequestDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostHankkiValidateRequestDTO.swift; sourceTree = "<group>"; };
A23F354E2D2211B200B6F8C8 /* NaverMapAPIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NaverMapAPIService.swift; sourceTree = "<group>"; };
A23F35502D2211BF00B6F8C8 /* NaverMapTargetType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NaverMapTargetType.swift; sourceTree = "<group>"; };
A23F35542D22135200B6F8C8 /* GetHankkiAddressResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetHankkiAddressResponseDTO.swift; sourceTree = "<group>"; };
A240EA072C3EF6E0000FF458 /* BufferView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BufferView.swift; sourceTree = "<group>"; };
A240EA0B2C3EFD77000FF458 /* CompositionalLayoutFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionalLayoutFactory.swift; sourceTree = "<group>"; };
A240EA182C3F35BC000FF458 /* SearchBarCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchBarCollectionViewCell.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -718,6 +724,7 @@
A2EC33A92C4711A000809840 /* Report */,
A24A78792CB44E110049B031 /* Menu */,
A2EC33AA2C4711A600809840 /* Location */,
A23F354D2D2211A000B6F8C8 /* NaverMap */,
);
path = Network;
sourceTree = "<group>";
Expand Down Expand Up @@ -1384,6 +1391,32 @@
name = ViewModel;
sourceTree = "<group>";
};
A23F354D2D2211A000B6F8C8 /* NaverMap */ = {
isa = PBXGroup;
children = (
A23F35522D22134300B6F8C8 /* DTO */,
A23F35502D2211BF00B6F8C8 /* NaverMapTargetType.swift */,
A23F354E2D2211B200B6F8C8 /* NaverMapAPIService.swift */,
);
path = NaverMap;
sourceTree = "<group>";
};
A23F35522D22134300B6F8C8 /* DTO */ = {
isa = PBXGroup;
children = (
A23F35532D22134900B6F8C8 /* Response */,
);
path = DTO;
sourceTree = "<group>";
};
A23F35532D22134900B6F8C8 /* Response */ = {
isa = PBXGroup;
children = (
A23F35542D22135200B6F8C8 /* GetHankkiAddressResponseDTO.swift */,
);
path = Response;
sourceTree = "<group>";
};
A240EA092C3EF712000FF458 /* HankkiReusableView */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2014,6 +2047,7 @@
86880C2A2C47F2DF00CAEF58 /* HankkiListViewModel.swift in Sources */,
8641516B2C67B9AE00E2FD44 /* MyZipListCollectionViewCell.swift in Sources */,
A2C9FCB12C49985800868DF7 /* GetZipListResponseDTO.swift in Sources */,
A23F35552D22135200B6F8C8 /* GetHankkiAddressResponseDTO.swift in Sources */,
A240EA442C446AB6000FF458 /* HankkiDetailButton.swift in Sources */,
A2AF6FDB2CE61AA000F5271D /* MenuResponseDTO.swift in Sources */,
839138DF2C4962E500611D5C /* GetHankkiThumbnailResponseDTO.swift in Sources */,
Expand Down Expand Up @@ -2046,11 +2080,13 @@
86880C0F2C47116900CAEF58 /* DeleteZipToHankkRequestiDTO.swift in Sources */,
83DBED942C2564A20042BA48 /* HomeView.swift in Sources */,
86880BF42C46E89C00CAEF58 /* GetMeUniversityResponseDTO.swift in Sources */,
A23F354F2D2211B200B6F8C8 /* NaverMapAPIService.swift in Sources */,
A2FF94112C31660E001ADA03 /* BaseDTO.swift in Sources */,
A200C66F2D19EA0D0065C749 /* DetailMapView.swift in Sources */,
837F10DC2C4A851A00E3CCE6 /* ReportCompleteViewController.swift in Sources */,
866DFE0E2D155DC6006EE662 /* CreateZipViewControllerType.swift in Sources */,
865D59C62C7B72C9004CC517 /* FullLoadingView.swift in Sources */,
A23F35512D2211BF00B6F8C8 /* NaverMapTargetType.swift in Sources */,
86B761232C3EC87A00413059 /* ZipListCollectionViewCellModel.swift in Sources */,
83DBEDCA2C256AE70042BA48 /* UIViewController+.swift in Sources */,
A23D11972C47FFB90023480C /* SearchViewModel.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Hankkijogbo/Hankkijogbo/Global/Consts/StringLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ enum StringLiterals {
static let myZip = "내 족보"
static let address = "주소"
static let copy = "복사"
static let mapLoadErrorMessage = "주소를 불러오지 못했어요"
static let copyToastMessage = "주소를 복사했습니다"
static let menu = "메뉴"
static let editMenu = "메뉴 수정/삭제 제보하기"
Expand Down
16 changes: 16 additions & 0 deletions Hankkijogbo/Hankkijogbo/Global/Extensions/UIViewController+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,20 @@ extension UIViewController {
self.view.window!.layer.add(transition, forKey: nil)
self.dismiss(animated: true, completion: nil)
}

/// 한끼 네비로 세팅한 후 식당 상세로 push
func pushToDetailWithHankkiNavigation(hankkiId: Int) {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootViewController = windowScene.windows.first?.rootViewController as? HankkiNavigationController {
let type: HankkiNavigationType = HankkiNavigationType(hasBackButton: true,
hasRightButton: false,
mainTitle: .string(""),
rightButton: .string(""))
rootViewController.setupNavigationBar(forType: type)
rootViewController.isNavigationBarHidden = false

let hankkiDetailViewController = HankkiDetailViewController(viewModel: HankkiDetailViewModel(hankkiId: hankkiId))
rootViewController.pushViewController(hankkiDetailViewController, animated: true)
}
}
}
16 changes: 16 additions & 0 deletions Hankkijogbo/Hankkijogbo/Global/Resources/Config.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ enum Config {
static let baseURL = "BASE_URL"
static let NMFClientId = "NMFClientId"
static let Amplitude = "Amplitude"
static let reverseGeocodingClientId = "ReverseGeocodingClientId"
static let reverseGeocodingClientSecret = "ReverseGeocodingClientSecret"
static let Kakao = "Kakao"
static let DefaultHankkiImageURL = "DefaultHankkiImageURL"
}
Expand Down Expand Up @@ -43,6 +45,20 @@ extension Config {
return key
}()

static let ReverseGeocodingClientId: String = {
guard let key = Config.infoDictionary[Keys.Plist.reverseGeocodingClientId] as? String else {
fatalError("ReverseGeocodingClientID is not set in plist for this configuration.")
}
return key
}()

static let ReverseGeocodingClientSecret: String = {
guard let key = Config.infoDictionary[Keys.Plist.reverseGeocodingClientSecret] as? String else {
fatalError("ReverseGeocodingClientSecret is not set in plist for this configuration.")
}
return key
}()

static let Amplitude: String = {
guard let key = Config.infoDictionary[Keys.Plist.Amplitude] as? String else {
fatalError("Amplitude is not set in plist for this configuration.")
Expand Down
8 changes: 6 additions & 2 deletions Hankkijogbo/Hankkijogbo/Global/Supporting Files/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key></key>
<string></string>
<key>ReverseGeocodingClientId</key>
<string>$(ReverseGeocodingClientId)</string>
<key>ReverseGeocodingClientSecret</key>
<string>$(ReverseGeocodingClientSecret)</string>
<key>Amplitude</key>
<string>$(Amplitude)</string>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>BASE_URL</key>
<string>$(BASE_URL)</string>
<key>CFBundleURLTypes</key>
Expand Down
24 changes: 18 additions & 6 deletions Hankkijogbo/Hankkijogbo/Network/Base/BaseTargetType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//

import Foundation
import UIKit

import Moya

Expand All @@ -25,6 +24,7 @@ enum HeaderType {
case loginHeader(accessToken: String)
case withdrawHeader(authorizationCode: String)
case formdataHeader(multipartData: [MultipartFormData])
case naverMapHeader(clientId: String, clientSecret: String)
}

/// 각 API에 따라 공통된 Path 값 (존재하지 않는 경우 빈 String 값)
Expand All @@ -38,6 +38,7 @@ enum UtilPath: String {
case university = "/v1/universities"
case location = "/v1/locations"
case universityStores = "/v1/university-stores"
case naverMap = "/v2/gc"
}

protocol BaseTargetType: TargetType {
Expand All @@ -51,26 +52,33 @@ protocol BaseTargetType: TargetType {

extension BaseTargetType {
var baseURL: URL {
guard let baseURL = URL(string: URLConstant.baseURL) else {
fatalError("ERROR - BASEURL")
switch utilPath {
case .naverMap:
guard let reverseGeocodingBaseURL = URL(string: URLConstant.reverseGeocodingBaseURL) else {
fatalError("ERROR - NAVER MAP Reverse Geocoding BASEURL")
}
return reverseGeocodingBaseURL
default:
guard let baseURL = URL(string: URLConstant.baseURL) else {
fatalError("ERROR - BASEURL")
}
return baseURL
}
return baseURL
}

var headers: [String: String]? {
var header: [String: String] = [:]

switch headerType {

case .loginHeader(let accessToken):
header["Content-Type"] = "application/json"
header["Authorization"] = "\(accessToken)"
return header

case .refreshTokenHeader:
header["Content-Type"] = "application/json"
let refreshToken = UserDefaults.standard.getRefreshToken()
header["Authorization"] = URLConstant.bearer + "\(refreshToken)"
return header

// 이후부터는 access token이 헤더에 필요합니다.
case .withdrawHeader(let authorizationCode):
Expand All @@ -80,6 +88,10 @@ extension BaseTargetType {
case .formdataHeader:
header["Content-Type"] = "multipart/form-data"

case .naverMapHeader(let clientId, let clientSecret):
header["x-ncp-apigw-api-key-id"] = clientId
header["x-ncp-apigw-api-key"] = clientSecret

default:
header["Content-Type"] = "application/json"
}
Expand Down
1 change: 1 addition & 0 deletions Hankkijogbo/Hankkijogbo/Network/Base/NetworkService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ final class NetworkService {
let locationService: LocationAPIServiceProtocol = LocationAPIService()
let zipService: ZipAPIServiceProtocol = ZipAPIService()
let reportService: ReportAPIServiceProtocol = ReportAPIService()
let naverMapService: NaverMapAPIServiceProtocol = NaverMapAPIService()
}

extension NetworkService {
Expand Down
1 change: 1 addition & 0 deletions Hankkijogbo/Hankkijogbo/Network/Base/URLConstant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum URLConstant {
// MARK: - Base URL

static let baseURL = Config.baseURL
static let reverseGeocodingBaseURL = "https://naveropenapi.apigw.ntruss.com/map-reversegeocode"

// MARK: - URL Path

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ struct GetHankkiDetailResponseData: Codable {
let isLiked: Bool
let imageUrls: [String]
let menus: [MenuData]
let latitude: Double
let longitude: Double
let categoryImageUrl: String
}

struct MenuData: Codable {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// GetHankkiAddressResponseDTO.swift
// Hankkijogbo
//
// Created by 서은수 on 12/30/24.
//

import Foundation

// MARK: - Naver Reverse Geocoding API Res

struct ReverseGeocodingBaseDTO: Decodable {
let code: Int
let name: String
let message: String
}

struct GetHankkiAddressResponseDTO: Decodable {
let status: ReverseGeocodingBaseDTO
let results: [GetHankkiAddressResult?]
}

struct GetHankkiAddressResult: Decodable {
let region: Region?
let land: Land?
}

struct Region: Decodable {
let area1: Area1?
let area2, area3, area4: Area?
}

struct Area1: Decodable {
let name, alias: String?
}

struct Area: Decodable {
let name: String?
}

struct Land: Decodable {
let name: String?
let number1, number2: String?
}
38 changes: 38 additions & 0 deletions Hankkijogbo/Hankkijogbo/Network/NaverMap/NaverMapAPIService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// NaverMapAPIService.swift
// Hankkijogbo
//
// Created by 서은수 on 12/30/24.
//

import Foundation

import Moya

protocol NaverMapAPIServiceProtocol {
func getHankkiAddress(latitude: Double, longitude: Double, completion: @escaping(NetworkResult<GetHankkiAddressResponseDTO>) -> Void)
}

final class NaverMapAPIService: BaseAPIService, NaverMapAPIServiceProtocol {

private let provider = MoyaProvider<NaverMapTargetType>(plugins: [MoyaPlugin.shared])

func getHankkiAddress(
latitude: Double,
longitude: Double,
completion: @escaping (NetworkResult<GetHankkiAddressResponseDTO>) -> Void) {
provider.request(.getHankkiAddress(latitude: latitude, longitude: longitude)) { result in
switch result {
case .success(let response):
let networkResult: NetworkResult<GetHankkiAddressResponseDTO> = self.fetchNetworkResult(statusCode: response.statusCode, data: response.data)
print(networkResult)
completion(networkResult)
case .failure(let error):
if let response = error.response {
let networkResult: NetworkResult<GetHankkiAddressResponseDTO> = self.fetchNetworkResult(statusCode: response.statusCode, data: response.data)
completion(networkResult)
}
}
}
}
}
Loading

0 comments on commit a13e6d3

Please sign in to comment.