B2024001225 윤지선

14주차 수업 본문

iOS프로그래밍 실무

14주차 수업

윤지선 2026. 6. 2. 14:05

 

//
//  GeminiViewController.swift
//  MovieYJS
//
//  Created by CMAC_43 on 2026/06/02.
//

import UIKit // iOS UI 관련 기능 가져오기
// 요청(Request)에 사용할 구조체들
// API에 보낼 JSON 구조를 Swift 구조체로 표현
// Encodable: Swift 객체 → JSON 변환 가능하게 해줌
// 최상위 요청 구조: { "contents": [...] }
struct GeminiRequest: Encodable {
    let contents: [RequestContent] // contents 배열
}
// contents 배열의 각 항목: { "parts": [...] }
struct RequestContent: Encodable {
    let parts: [RequestPart] // parts 배열
}
// parts 배열의 각 항목: { "text": "..." }
struct RequestPart: Encodable {
    let text: String // 실제 프롬프트 텍스트
}
// API가 보내주는 JSON 구조를 Swift 구조체로 표현
// Decodable: JSON → Swift 객체 변환 가능하게 해줌
// 최상위 응답 구조: { "candidates": [...] }
struct GeminiResponse: Decodable {
    let candidates: [Candidate] // candidates 배열
}
// candidates 배열의 각 항목: { "content": {...} }
struct Candidate: Decodable {
    let content: ResponseContent // content 객체
}
// content 객체: { "parts": [...] }
struct ResponseContent: Decodable {
    let parts: [ResponsePart] // parts 배열
}
// parts 배열의 각 항목: { "text": "..." }
struct ResponsePart: Decodable {
    let text: String // AI가 생성한 실제 텍스트
}

class GeminiViewController: UIViewController {
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var textView: UITextView!
    
    let apiKey = "AIzaSyALYH1nho21uQQG5JL2cWVD52BMFzYGjbc"
    
    @IBAction func buttonTapped(_ sender: UIButton) {
        // 입력값 비어있으면 종료
        guard let mood = textField.text, !mood.isEmpty else { return }
        // 로딩 메시지 표시
        textView.text = "추천 중…"
        // 키보드 내리기
        view.endEditing(true)
        // 영화 추천 받아오기 시작
        getData(mood: mood)
    }
    func getData(mood: String){
        let geminiURL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=\(apiKey)"
        
        guard let url = URL(string: geminiURL) else { return }
        
        let prompt = "기분이 '\(mood)'일 때 볼만한 영화 3편을 한국어로 추천해줘. 각 영화마다 제목, 장르, 추천이유를 간단히 적어줘."
        
        let requestBody = GeminiRequest(
            contents: [
                RequestContent(
                    parts: [
                        RequestPart(text: prompt)
                    ]
                )
            ]
        )
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = try? JSONEncoder().encode(requestBody)
        
        let session = URLSession(configuration: .default)
        
        let task = session.dataTask(with: request) { [self] data, response, error in
            
            if let error = error {
                print(error)
                return
            }
            
            guard let jsonData = data else { return }
            
            let decoder = JSONDecoder()
            
            do {
                let decodedData = try decoder.decode(GeminiResponse.self, from: jsonData)
                
                let text = decodedData.candidates.first?.content.parts.first?.text ?? "결과 없음"
                
                let cleanText = text
                
                DispatchQueue.main.async {
                    self.textView.text = cleanText
                }
                
            } catch {
                print(error)
            }
        }
        
        task.resume()
        
        
        
        
        func viewDidLoad() {
            super.viewDidLoad()
            
            // Do any additional setup after loading the view.
        }
        
        
        /*
         // MARK: - Navigation
         
         // In a storyboard-based application, you will often want to do a little preparation before navigation
         override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         // Get the new view controller using segue.destination.
         // Pass the selected object to the new view controller.
         }
         */
        
    }
}

 
 
 
9주차
JSON의 구조
두개의 메소드 사용법 철저하게
=>
tableView(_:cellForRowAt:)
tableView(_:didSelectRowAt:)
 
11주차
가장 중요함
어제 날짜 구하는 소스는 시험범위 X
 
12주차
오토레이아웃 -> 방법 여러가지인데 그 방법이 몇가지인지만 알면 됨. (5가지 방법만 알면 됨. 장단점 X)
43, 44p 제외 
 
13주차
24p 차이점만 알고있으면 됨. 
 
14주차
20,21p만 시험범위.

'iOS프로그래밍 실무' 카테고리의 다른 글

13주차 수업  (0) 2026.05.26
11주차 수업  (0) 2026.05.19
10주차 수업  (0) 2026.05.12
9주차 수업  (0) 2026.04.28
7주차 수업  (0) 2026.04.14