https://simth999wrld.tistory.com/76

 

우리말 퀴즈 앱)2.퀴즈뷰 구성중...

https://simth999wrld.tistory.com/75 우리말 퀴즈 앱)1.우리말샘 api https://simth999wrld.tistory.com/74 1차시. OT 간단하게 스터디 일정과 인사후 개인프로젝트 소개를 하였습니다, ^_^/ 간단하게 아이디어를 정리해

simth999wrld.tistory.com

이번에 구성에 대해 조금더 업그레이드를 해보았는데요,,하하

 

네이버 검색 API를 사용해서 정답 단어의 이미지를 가져오는것 입니다..ㅎ

 

 

 

 

디렉토리 구조를 조금 바꾸었습니다.. (이렇게 하는거 맞나.,.?)

 

조금더 고민한 후에 조금더 보기 편하게 만들어 보겠습니다^_^

 

 

 

 

 

 

 

 

네이버 이미지검색 API

 

일단 네이버 검색 API를 사용하기 위해 네이버 디벨로퍼 회원가입, 키 발급 등을 합니다.

 

https://developers.naver.com/docs/serviceapi/search/image/image.md

 

검색 > 이미지 - Search API

검색 > 이미지 이미지 검색 개요 개요 검색 API와 이미지 검색 개요 검색 API는 네이버 검색 결과를 뉴스, 백과사전, 블로그, 쇼핑, 웹 문서, 전문정보, 지식iN, 책, 카페글 등 분야별로 볼 수 있는 API

developers.naver.com

 

 

 

 

묵념을 검색을 하게된다면 이렇게 최소 10개의 이미지를 가져올 수 있게 됩니다.

 

저는 가장 맨 위의 이미지만을 사용하겠습니다.

 

이 JSON형식에 따라 Swift파일을 만들어 줍니다.

 

 

 

 

 

- NaverImageData.swift -

import Foundation

// MARK: - NaverImageData
struct NaverImageData: Codable {
    let lastBuildDate: String
    let total, start, display: Int
    let items: [NaverItem]
}

// MARK: - NaverItem
struct NaverItem: Codable {
    let title: String
    let link: String //이미지의 URL
    let thumbnail: String
    let sizeheight, sizewidth: String
}

 

이렇게 만들어 주는데 물론 손으로 만드면 좋겠지마는~ 

 

https://app.quicktype.io/

 

Instantly parse JSON in any language | quicktype

 

app.quicktype.io

 

이 사이트에서 여러 타입의 데이터들을 코드로 만들어 줍니다. 편리하죠..?

 

 

클라이언트 아이디와 시크릿 값을 저장하기 위한 파일을 만들어 줍니다.

 

- NaverStorage.swift -

//TODO: - gitignore에 NaverStorage.swift 추가하기..
import Foundation

struct NaverStorage {
    let naverClientID: String = "Your naverClientID"
    let naverClientSecret: String = "Your naverClientSecret"
}

 

 

앗 그전에 까먹은 것이 있네요..

Alamofire를 사용해 HTTP통신을 하여 네이버 API를 사용해야하니 Alamofire또한 Cocopod를 통해 설치해 줍니다.

(킹피셔로 이미지를 보여줄것이니 같이 다운 받아요 ㅎㅎ)

pod 'Alamofire'
pod 'Kingfisher', '~> 7.0'

 

 

pod install을 하였다면,, 이제 HTTP통신을 해야 하겠죠?

 

HTTP 통신에 사용되는 메소드를 편하게 사용하기 위해 enum에 저장하여 사용합니다.

 

- HTTPMethod.swift - 

enum HTTPMethod: String {
    case get = "GET"
    case post = "POST"
    case put = "PUT"
    case head = "HEAD"
    case delete = "DELETE"
    case patch = "PATCH"
    case trace = "TRACE"
    case options = "OPTIONS"
    case connect = "CONNECT"
}

 

 

Alamofire를 사용해 네트워크 통신 부분을 작성 해보겠습니다.

 

- NaverNetwork.swift -

import Foundation
import Alamofire


protocol NaverNetworkDelegate: AnyObject {
    func imageDataUpdated(_ imageData: NaverImageData?)
}

class NaverNetwork: ObservableObject {
    static let shared = NaverNetwork()
    private init() {}
    
    @Published var imageData: NaverImageData?
    
    weak var delegate: NaverNetworkDelegate?
    
    func requestSearchImage(query: String, completion: @escaping () -> Void) {
        let baseURL = "https://openapi.naver.com/v1/search/image"
        
        let headers: HTTPHeaders = [
            "X-Naver-Client-Id": NaverStorage().naverClientID,
            "X-Naver-Client-Secret": NaverStorage().naverClientSecret,
        ]
        
        let parameters: Parameters = [
            "query": query,
            "display": 50
        ]
        
        AF.request(baseURL,
                   method: .get,
                   parameters: parameters,
                   encoding: URLEncoding.default,
                   headers: headers)
        .validate(statusCode: 200...500)
        .responseDecodable(of: NaverImageData.self) { response in
            switch response.result {
            case .success(let data):
                guard let statusCode = response.response?.statusCode else { return }
                if statusCode == 200 {
                    DispatchQueue.main.async {
                        self.imageData = data
                        self.delegate?.imageDataUpdated(data)
                        completion()
                    }
                }
                print("\(#file) > \(#function) :: SUCCESS")
            case .failure(let error):
                print("\(#file) > \(#function) :: FAILURE : \(error)")
            }
        }
    }
}

 

(NaverNetworkDelegate이 뒤에 이미지를 QuizView에서 보여져야 하지만 이미지가 보이지 않았어서 추가하였습니다.. 이부분은 추가로 글쓸 예정!)

 

QuizView에서 보여질 이미지를 위해 QuizViewModel에서 메소드들을 작성해 줍니다.

//MARK: - KoreanWordSearchAPI

// 단어 데이터 처리 메서드
func handleWordData(word: String, wordData: WordData?) {
    if let wordData = wordData {
        wordDataDictionary[word] = wordData
        // 정답 단어의 설명을 가져오기
        if word == correctWord {
            fetchCorrectWordDefinition()
            fetchImageForWord(correctWord)
        }
    } else {
        print("\(word) 단어 데이터를 가져오지 못함 ")
        isLoading = false // 데이터를 가져오지 못한 경우 isLoading을 false로 설정하여 프로그레스 뷰를 숨김
    }

    isLoading = false
}

// 정답 단어의 설명 가져오기
func fetchCorrectWordDefinition() {
    isLoading = true

    guard let wordData = wordDataDictionary[correctWord] else {
        correctWordDefinition = "설명을 가져올 수 없습니다."
        isLoading = false // 작업 완료
        return
    }

    if let firstSense = wordData.channel.item.first?.sense.first {
        correctWordDefinition = firstSense.definition
        print(correctWordDefinition)
    } else {
        correctWordDefinition = "설명을 찾을 수 없습니다."
    }

    isLoading = false // 작업 완료
}

//MARK: - NaverSearchAPI

func fetchImageForWord(_ word: String) {
    isLoading = true

    naverNetwork.requestSearchImage(query: word){ [weak self] in
        // 이미지 데이터 로드 완료 시에만 isLoading을 false로 설정
        self?.isLoading = false
    }
}

//MARK: - NaverNetworkDelegate
func imageDataUpdated(_ imageData: NaverImageData?) {
    DispatchQueue.main.async {
        self.imageData = imageData
    }
}
}

 

 

 

 

Kingfisher

킹피셔를 사용하여 이미지를 띄워 줍니다.

//MARK: - 문제의 이미지
VStack{
    if quizViewModel.isLoading {
        ProgressView("Loading...")
            .frame(width: 200, height: 200)
    } else {
        if let imageData = quizViewModel.imageData {
            if let firstImage = imageData.items.first {
                KFImage(URL(string: firstImage.link))
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 200, height: 200)
            }
        }
    }
}
.padding()

 

 

 

디자인은 잼병이라,, 다른앱을 참고하며 바꿔보도록 하겠습니다.

 

 

 

 

이렇게 이미지를 가져올수 있게 되었습니다!!

 

 

문제 발생..

문제라 함은 2개가 발생 하였는데요...

 

문제 1.

//TODO: - gitignore에 NaverStorage.swift 추가하기..
import Foundation

struct NaverStorage {
    let naverClientID: String = "Your naverClientID"
    let naverClientSecret: String = "Your naverClientSecret"
}

 

이부분은 큰 문제는 아니지만, 조금더 보안을 신경 써준다면 키체인을 사용하면 좋아 보입니다!!!

 

 

문제 2.

 

 

 

 

 

 

 

 

바로 이미지에서 정답을 알수있는 이미지가 나온다는 사실...

관련 이미지를 싹 깃허브에 올려서 가져오는 방법으로 해야 이런 문제가 안날것 같지만..

시간이 많이 걸릴것 같군요 하하..ㅎ 

 

(아이디어 있다면 알려주세요..)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

긴글 읽어주셔서 감사합니다 ^_^🙏

 

 

 

 

 

 

 

 

https://developers.naver.com/docs/serviceapi/search/image/image.md#%EC%9D%B4%EB%AF%B8%EC%A7%80-%EA%B2%80%EC%83%89-%EA%B2%B0%EA%B3%BC-%EC%A1%B0%ED%9A%8C

 

검색 > 이미지 - Search API

검색 > 이미지 이미지 검색 개요 개요 검색 API와 이미지 검색 개요 검색 API는 네이버 검색 결과를 뉴스, 백과사전, 블로그, 쇼핑, 웹 문서, 전문정보, 지식iN, 책, 카페글 등 분야별로 볼 수 있는 API

developers.naver.com

https://github.com/Alamofire/Alamofire

 

GitHub - Alamofire/Alamofire: Elegant HTTP Networking in Swift

Elegant HTTP Networking in Swift. Contribute to Alamofire/Alamofire development by creating an account on GitHub.

github.com

https://velog.io/@dbqls200/iOS-%EB%84%A4%EC%9D%B4%EB%B2%84-%EA%B2%80%EC%83%89%EB%8F%84%EC%84%9C-API-%EC%82%AC%EC%9A%A9%EA%B8%B0

 

[iOS] 네이버 검색(도서) API 사용기

네이버 Open API를 사용해서 책 검색 해보기

velog.io

 

+ Recent posts