
영진위 데이터 - 5/11 일자
{
"boxOfficeResult": {
"boxofficeType": "일별 박스오피스",
"showRange": "20260511~20260511",
"dailyBoxOfficeList": [
{
"rnum": "1",
"rank": "1",
"rankInten": "1",
"rankOldAndNew": "OLD",
"movieCd": "20259791",
"movieNm": "악마는 프라다를 입는다 2",
"openDt": "2026-04-29",
"salesAmt": "250692610",
"salesShare": "34.1",
"salesInten": "-459085710",
"salesChange": "-64.7",
"salesAcc": "12401287580",
"audiCnt": "24856",
"audiInten": "-43481",
"audiChange": "-63.6",
"audiAcc": "1246484",
"scrnCnt": "1079",
"showCnt": "3498"
},
{
"rnum": "2",
"rank": "2",
"rankInten": "1",
"rankOldAndNew": "OLD",
"movieCd": "20254121",
"movieNm": "살목지",
"openDt": "2026-04-08",
"salesAmt": "149637230",
"salesShare": "20.4",
"salesInten": "-431817520",
"salesChange": "-74.3",
"salesAcc": "31117243350",
"audiCnt": "14561",
"audiInten": "-41643",
"audiChange": "-74.1",
"audiAcc": "3037366",
"scrnCnt": "878",
"showCnt": "2641"
},
{
"rnum": "3",
"rank": "3",
"rankInten": "-2",
"rankOldAndNew": "OLD",
"movieCd": "20259773",
"movieNm": "슈퍼 마리오 갤럭시",
"openDt": "2026-04-29",
"salesAmt": "72856350",
"salesShare": "9.9",
"salesInten": "-727066010",
"salesChange": "-90.9",
"salesAcc": "12797524100",
"audiCnt": "7191",
"audiInten": "-75291",
"audiChange": "-91.3",
"audiAcc": "1325908",
"scrnCnt": "733",
"showCnt": "1685"
},
{
"rnum": "4",
"rank": "4",
"rankInten": "0",
"rankOldAndNew": "OLD",
"movieCd": "20261782",
"movieNm": "프로젝트 헤일메리",
"openDt": "2026-03-18",
"salesAmt": "86328020",
"salesShare": "11.8",
"salesInten": "-171644790",
"salesChange": "-66.5",
"salesAcc": "31662396640",
"audiCnt": "7049",
"audiInten": "-13720",
"audiChange": "-66.1",
"audiAcc": "2790015",
"scrnCnt": "546",
"showCnt": "934"
},
{
"rnum": "5",
"rank": "5",
"rankInten": "0",
"rankOldAndNew": "OLD",
"movieCd": "20240532",
"movieNm": "짱구",
"openDt": "2026-04-22",
"salesAmt": "43781220",
"salesShare": "6.0",
"salesInten": "-82122880",
"salesChange": "-65.2",
"salesAcc": "3713649280",
"audiCnt": "4447",
"audiInten": "-7784",
"audiChange": "-63.6",
"audiAcc": "381052",
"scrnCnt": "429",
"showCnt": "785"
},
{
"rnum": "6",
"rank": "6",
"rankInten": "0",
"rankOldAndNew": "OLD",
"movieCd": "20242837",
"movieNm": "왕과 사는 남자",
"openDt": "2026-02-04",
"salesAmt": "31877200",
"salesShare": "4.3",
"salesInten": "-51521200",
"salesChange": "-61.8",
"salesAcc": "162533352330",
"audiCnt": "3446",
"audiInten": "-4840",
"audiChange": "-58.4",
"audiAcc": "16836970",
"scrnCnt": "372",
"showCnt": "555"
},
{
"rnum": "7",
"rank": "7",
"rankInten": "0",
"rankOldAndNew": "OLD",
"movieCd": "20262685",
"movieNm": "란 12.3",
"openDt": "2026-04-22",
"salesAmt": "15206950",
"salesShare": "2.1",
"salesInten": "-26729200",
"salesChange": "-63.7",
"salesAcc": "2317632710",
"audiCnt": "1590",
"audiInten": "-2620",
"audiChange": "-62.2",
"audiAcc": "231977",
"scrnCnt": "271",
"showCnt": "360"
},
{
"rnum": "8",
"rank": "8",
"rankInten": "5",
"rankOldAndNew": "OLD",
"movieCd": "20259626",
"movieNm": "마이클",
"openDt": "2026-05-13",
"salesAmt": "16200000",
"salesShare": "2.2",
"salesInten": "3348000",
"salesChange": "26.1",
"salesAcc": "188388000",
"audiCnt": "1506",
"audiInten": "750",
"audiChange": "99.2",
"audiAcc": "18375",
"scrnCnt": "4",
"showCnt": "4"
},
{
"rnum": "9",
"rank": "9",
"rankInten": "-1",
"rankOldAndNew": "OLD",
"movieCd": "20262947",
"movieNm": "모탈 컴뱃 2",
"openDt": "2026-05-06",
"salesAmt": "12540250",
"salesShare": "1.7",
"salesInten": "-14937700",
"salesChange": "-54.4",
"salesAcc": "148652290",
"audiCnt": "1168",
"audiInten": "-1172",
"audiChange": "-50.1",
"audiAcc": "13217",
"scrnCnt": "314",
"showCnt": "410"
},
{
"rnum": "10",
"rank": "10",
"rankInten": "-1",
"rankOldAndNew": "OLD",
"movieCd": "20247648",
"movieNm": "내 이름은",
"openDt": "2026-04-15",
"salesAmt": "8243200",
"salesShare": "1.1",
"salesInten": "-5113550",
"salesChange": "-38.3",
"salesAcc": "1836367180",
"audiCnt": "896",
"audiInten": "-644",
"audiChange": "-41.8",
"audiAcc": "205640",
"scrnCnt": "99",
"showCnt": "128"
}
]
}
}

해당 주소가 없다면 nil 이 나와야하기 때문에 옵셔널형임.


JSON 파싱을 쉽게 하기 위함 - https://app.quicktype.io/
- 영진위에서 받아온 JSON 데이터를 구조체로 만듦
import Foundation
// MARK: - Welcome
struct Welcome {
let boxOfficeResult: BoxOfficeResult
}
// MARK: - BoxOfficeResult
struct BoxOfficeResult {
let boxofficeType, showRange: String
let dailyBoxOfficeList: [DailyBoxOfficeList]
}
// MARK: - DailyBoxOfficeList
struct DailyBoxOfficeList {
let rnum, rank, rankInten: String
let rankOldAndNew: RankOldAndNew
let movieCD, movieNm, openDt, salesAmt: String
let salesShare, salesInten, salesChange, salesAcc: String
let audiCnt, audiInten, audiChange, audiAcc: String
let scrnCnt, showCnt: String
}
enum RankOldAndNew: String {
case old
}




- 2등인 영화의 제목 출력

- 1등인 영화의 누적 관객 수


- reloadData를 사용할 때도 self를 명시해야됨

- 명시를 했음에도 오류 발생 : main Thread에서 사용해야되는데 클로저 안에서 사용 중임


//
// ViewController.swift
// movie_yjy
//
// Created by 소프트웨어컴퓨터 on 2026/04/28.
//
import UIKit
let name = ["살목지","란 12.3","짱구","프로젝트 헤일메리","왕과 사는 남자","내 이름은","리 코로닌의 미이라",
"기동전사 건담: 섬광의 하사웨이 키르케의 마녀", " 르누아르","마녀배달부 키키"]
struct MovieData : Codable {
let boxOfficeResult : BoxOfficeResult
}
struct BoxOfficeResult : Codable {
let dailyBoxOfficeList : [DailyBoxOfficeList]
}
struct DailyBoxOfficeList : Codable {
let movieNm : String
let audiCnt : String
let audiAcc : String
let rank : String
}
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
@IBOutlet weak var table: UITableView!
var movieData : MovieData? // 프로퍼티는 반드시 초기값이 있어야함. -> 옵셔널로 지정하여 초기값을 nil로
// let movieURL = 정해진 날짜가 아닌
// 앱 실행시마다 날짜가 어제의 날짜로 설정되도록
var movieURL = "https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=&targetDt="
override func viewDidLoad() {
super.viewDidLoad()
table.delegate = self
table.dataSource = self
movieURL += makeYesterdayString()
getData()
}
func makeYesterdayString() -> String{
let y = Calendar.current.date(byAdding: .day, value: -1, to: Date())!
let dateF = DateFormatter()
dateF.dateFormat = "yyyyMMdd"
let day = dateF.string(from: y)
return day
}
func getData(){
//if let url = URL(string: movieURL){}
guard let url = URL(string: movieURL) else { return } //네트워크 1단계 : url (주소) 만들기
let session = URLSession(configuration: .default) // 2단계 : URLSession 만들기
//3단계
let task = session.dataTask(with: url) { data, response, error in
if error != nil {return} // 에러가 있으면 종료
guard let JSONdata = data else {return}
print(JSONdata)
let dataString = String(data:JSONdata, encoding: .utf8)
//print(dataString!)
let decoder = JSONDecoder()
do{
let decodedData = try decoder.decode(MovieData.self, from: JSONdata)
//MovieData라는 자료형을 매개변수로 쓰려면 .self를 적어야함
print(decodedData.boxOfficeResult.dailyBoxOfficeList[1].movieNm)
print(decodedData.boxOfficeResult.dailyBoxOfficeList[0].audiAcc)
self.movieData = decodedData
DispatchQueue.main.async {
self.table.reloadData()
}
}catch{
print(error)
}
//print(response!)
}
task.resume()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
// as! MyTableViewCell
// cell.movieName.text = "\(indexPath.row+1)등 " + name[indexPath.row]
// //print(indexPath,separator: " ",terminator: " ") //화면에 보이는 셀을 모두 만듦
// return cell
// }
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//print(indexPath.description) //어떤 섹션을 눌렀는지 확인 가능
}
func tableView(_ tableView : UITableView, cellForRowAt indexPath : IndexPath) ->
UITableViewCell{
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableViewCell
cell.movieName.text = movieData?.boxOfficeResult.dailyBoxOfficeList[indexPath.row].movieNm
return cell
}
}
- 마무리 프로젝트 모습

'iOS' 카테고리의 다른 글
| iOS_3grade - 13주차 (0) | 2026.06.02 |
|---|---|
| iOS_3grade - 11주차 (0) | 2026.05.19 |
| iOS_grade3 - 9주차 (0) | 2026.04.28 |
| iOS_3grade - 7주차 (0) | 2026.04.14 |
| iOS_3grade - 6주차 (1) | 2026.04.07 |