꼼꼼한 재은씨의 스위프트 swift 기본편 영화목록 앱 api json
//
// MovieVO.swift
// MyMovieChart
//
// Created by stayfoolish on 28/10/2018.
// Copyright © 2018 stayfoolish. All rights reserved.
//
import Foundation
import UIKit
class MovieVO {
var thumbnail: String? // 영화 섬네일 이미지 주소
var title: String? // 영화 제목
var description: String? // 영화 설명
var detail: String? // 상세정보
var opendate: String? // 개봉일
var rating: Double? // 평점
// 영호 썸네일 이미지를 담을 UIImage 객체를 추가한다.
var thumbnailImage: UIImage?
}
//
// MovieCell.swift
// MyMovieChart
//
// Created by stayfoolish on 29/10/2018.
// Copyright © 2018 stayfoolish. All rights reserved.
//
import UIKit
class MovieCell: UITableViewCell {
@IBOutlet var title: UILabel!
@IBOutlet var desc: UILabel!
@IBOutlet var opendate: UILabel!
@IBOutlet var rating: UILabel!
@IBOutlet var thumbnail: UIImageView!
}
//
// ListViewController.swift
// MyMovieChart
//
// Created by stayfoolish on 28/10/2018.
// Copyright © 2018 stayfoolish. All rights reserved.
//
import UIKit
class ListViewController: UITableViewController {
@IBOutlet var moreBtn: UIButton!
/*
// 튜플 아이템으로 구성된 데이터 세트
var dataset = [
("다크 나이트","영웅물에 철학에 음악까지 더해져 예술이 되다.","2008-09-04",8.95,"darknight.jpg"),
("호우시절","때를 알고 내리는 좋은 비","2009-10-08",7.31,"rain.jpg"),
("말할 수 없는 비밀","여기서 너까지 다섯 걸음","2015-05-07",9.19,"secret.jpg")
]
*/
// 현재까지 읽어온 데이터의 페이지 정보
var page = 1
// 테이블 뷰를 구성할 리스트 데이터
lazy var list: [MovieVO] = {
var datalist = [MovieVO]()
/*
for (title, desc, opendate, rating, thumbnail) in self.dataset {
let mvo = MovieVO()
mvo.title = title
mvo.description = desc
mvo.opendate = opendate
mvo.rating = rating
mvo.thumbnail = thumbnail
datalist.append(mvo)
}
*/
return datalist
}()
@IBAction func more(_ sender: UIButton) {
// 0) 현재 페이지 값에 1을 추가한다.
self.page += 1
// 영화차트 API를 호출한다.
self.callMovieAPI()
// 데이터를 다시 읽어오도록 테이블 뷰를 갱신한다.
self.tableView.reloadData()
}
// 뷰가 처음 메모리에 로드될 때 호출되는 메소드
override func viewDidLoad() {
// 영화차트 API를 호출한다.
self.callMovieAPI()
}
func callMovieAPI() {
// 1) 호핀 API를 호출을 위한 URI를 생성
// let url = "http://swiftapi.rubypaper.co.kr:2029/hoppin/movies?version=1&page=\(self.page)&count=10&genreId=&order=releasedateasc"
let url = "http://swiftapi.rubypaper.co.kr:2029/hoppin/movies?version=1&page=\(self.page)&count=30&genreId=&order=releasedateasc"
let apiURL: URL! = URL(string: url)
// 2) REST API를 호출
let apidata = try! Data(contentsOf: apiURL)
// 3) 데이터 전송 결과를 로그로 출력 (반드시 필요한 코드는 아님)
let log = NSString(data: apidata, encoding: String.Encoding.utf8.rawValue) ?? "데이터가 없습니다"
NSLog("API Result=\( log )")
// 4) JSON 객체를 파싱하여 NSDictionary 객체로 받음
do {
let apiDictionary = try JSONSerialization.jsonObject(with: apidata, options: []) as! NSDictionary
// 5) 데이터 구조에 따라 차례대로 캐스팅하며 읽어온다.
let hoppin = apiDictionary["hoppin"] as! NSDictionary
let movies = hoppin["movies"] as! NSDictionary
let movie = movies["movie"] as! NSArray
// 6) Iterator 처리를 하면서 API 데이터 MovieVO 객체에 저장한다.
for row in movie {
// 순회 상수를 NSDictionary 타입으로 캐스팅
let r = row as! NSDictionary
// 테이블 뷰 리스트를 구성할 데이터 형식
let mvo = MovieVO()
// movie 배열의 각 데이터를 mvo 상수의 속성에 대입
mvo.title = r["title"] as? String
mvo.description = r["genreNames"] as? String
mvo.thumbnail = r["thumbnailImage"] as? String
mvo.detail = r["linkUrl"] as? String
mvo.rating = ((r["ratingAverage"] as! NSString).doubleValue)
// 웹상에 있는 이미지를 읽어와 UIImage 객체로 설정
let url: URL! = URL(string: mvo.thumbnail!)
let imageData = try! Data(contentsOf: url)
mvo.thumbnailImage = UIImage(data:imageData)
// list 배열에 추가
self.list.append(mvo)
// 7) 전체 데이터 카우트를 얻는다.
let totalCount = (hoppin["totalCount"] as? NSString)!.integerValue
// 8) totalCount가 읽어온 데이터 크기와 같거나 클 경우 더보기 버튼을 막는다.
if (self.list.count >= totalCount){
self.moreBtn.isHidden = true
}
}
}catch { NSLog("Parse Error!!")}
}
func getThumnailImage(_ index: Int) -> UIImage {
// 인자값으로 받은 인덱스를 기반으로 해당하는 배열 데이터를 읽어옴
let mvo = self.list[index]
// 메모이제이션 : 저장된 이미지가 있으면 그것을 반환하고, 없을 경우 내려받아 저장한 후 반환
if let savedImage = mvo.thumbnailImage {
return savedImage
}else {
let url: URL! = URL(string: mvo.thumbnail!)
let imageData = try! Data(contentsOf: url)
mvo.thumbnailImage = UIImage(data:imageData) // UIImage를 MovieVO 객체에 우선 저장
return mvo.thumbnailImage! // 저장된 이미지를 반환
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.list.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 주어진 행에 맞는 데이터 소스를 읽어온다.
let row = self.list[indexPath.row]
// 로그 출력
NSLog("제목:\(row.title!), 호출된 행번호:\(indexPath.row)")
// 테이블 셀 객체를 직접 생성하는 대신 큐로부터 가져옴
// as! UITableViewCell => as! MovieCell 로 캐스팅 타입 변경
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! MovieCell
// 데이터 소스에 저장된 값을 각 아울렛 변수에 할당
cell.title?.text = row.title
cell.desc?.text = row.description
cell.opendate?.text = row.opendate
cell.rating?.text = "\(row.rating!)"
/*
// 섬네일 경로를 인자값으로 하는 URL 객체를 생성
let url: URL! = URL(string: row.thumbnail!)
// 이미지를 읽어와 Data 객체에 저장
let imageData = try! Data(contentsOf: url)
// UIImage 객체를 생성하여 아울렛 변수의 image 속성에 대입
cell.thumbnail.image = UIImage(data: imageData)
*/
/*
// 이미지 객체를 대입힌다.
cell.thumbnail.image = row.thumbnailImage
*/
// 비동기 방식으로 섬네일 이미지를 읽어옴
DispatchQueue.main.async(execute: {
NSLog("비동기 방식으로 실행되는 부분입니다")
cell.thumbnail.image = self.getThumnailImage(indexPath.row)
})
NSLog("메소드 실행을 종료하고 셀을 리턴합니다.")
// 셀 객체를 반환
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
NSLog("선택된 행은 \(indexPath.row) 번째 행입니다.")
}
}
'Swift > 기초&문법' 카테고리의 다른 글
꼼꼼한 재은씨의 스위프트 swift 실전편 api alamofire (0) | 2018.11.01 |
---|---|
꼼꼼한 재은씨의 스위프트 swift 실전편 api 적용 앱 POST JSON (0) | 2018.10.31 |
꼼꼼한 재은씨의 스위프트 swift 기본편 화면전환 (0) | 2018.10.27 |
do it 스위프트 아이폰 앱 만들기 19장 Picnch Gesture swift (0) | 2018.10.25 |
do it 스위프트 아이폰 앱 만들기 18장 swift swipe gestrue 스와이프 제스처 (0) | 2018.10.24 |