//웹에 있는 데이터를 가져오는 방법
//cell.thumbnail.image = UIImage(data: try! Data(contentsOf: URL(string: row.thumbnail!)!)) 축약
let url: URL! = URL(string: row.thumbnail!)
let imageData = try! Data(contentsOf: url)
cell.thumbnail.image = UIImage(data: imageData)
//처음 한 번만 실행
override func viewDidLoad() {
//URL은 파운데이션 프레임워크에 정의된 객체, NSURL클래스를 바탕으로 만들어짐
let url = "http://swiftapi.rubypaper.co.kr:2029/hoppin/movies?version=1&page=1&count=10&genreId=&order=releasedateasc"
let apiURL: URL! = URL(string: url)
//restAPI GET방식으로 호출
let apidata = try! Data(contentsOf: apiURL)
//NSString 타입의 문자열로 변환해 로그로 출력 (데이터를 편리하게 인코딩해서 문자열로 변환할 수 있다)
let log = NSString(data: apidata, encoding: String.Encoding.utf8.rawValue) ?? ""
NSLog("API Result=\(log)")
do {
//JSON객체를 파싱하여 NSDictionary 객체러 변환
let apiDictionary = try JSONSerialization.jsonObject(with: apidata, options: []) as! NSDictionary
let hoppin = apiDictionary["hoppin"] as! NSDictionary
let movies = hoppin["movies"] as! NSDictionary //{키:값} 형태일 때
let movie = movies["movie"] as! NSArray //[값] 형태일 때
for row in movie {
let r = row as! NSDictionary
let mvo = MovieVO()
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
self.list.append(mvo)
}
} catch {
}
}
URL session 활용하기
//
// WeatherManager.swift
// Clima
//
// Created by Angela Yu on 03/09/2019.
// Copyright © 2019 App Brewery. All rights reserved.
//
import Foundation
import CoreLocation
protocol WeatherManagerDelegate {
func didUpdateWeather(_ weatherManager: WeatherManager, weather: WeatherModel)
func didFailWithError(error: Error)
}
struct WeatherManager {
let weatherURL = "https://api.openweathermap.org/data/2.5/weather?appid=e72ca729af228beabd5d20e3b7749713&units=metric"
var delegate: WeatherManagerDelegate?
func fetchWeather(cityName: String) {
let urlString = "\(weatherURL)&q=\(cityName)"
performRequest(with: urlString)
}
func fetchWeather(latitude: CLLocationDegrees, longitude: CLLocationDegrees) {
let urlString = "\(weatherURL)&lat=\(latitude)&lon=\(longitude)"
performRequest(with: urlString)
}
func performRequest(with urlString: String) {
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
if let safeData = data {
if let weather = self.parseJSON(safeData) {
self.delegate?.didUpdateWeather(self, weather: weather)
}
}
}
task.resume()
}
}
func parseJSON(_ weatherData: Data) -> WeatherModel? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
let id = decodedData.weather[0].id
let temp = decodedData.main.temp
let name = decodedData.name
let weather = WeatherModel(conditionId: id, cityName: name, temperature: temp)
return weather
} catch {
delegate?.didFailWithError(error: error)
return nil
}
}
}
//
// ViewController.swift
// Clima
//
// Created by Angela Yu on 01/09/2019.
// Copyright © 2019 App Brewery. All rights reserved.
//
import UIKit
import CoreLocation
class WeatherViewController: UIViewController {
var weatherManager = WeatherManager()
override func viewDidLoad() {
super.viewDidLoad()
weatherManager.delegate = self
}
}
extension WeatherViewController: WeatherManagerDelegate {
func didUpdateWeather(_ weatherManager: WeatherManager, weather: WeatherModel) {
DispatchQueue.main.async {
self.temperatureLabel.text = weather.temperatureString
self.conditionImageView.image = UIImage(systemName: weather.conditionName)
self.cityLabel.text = weather.cityName
}
}
func didFailWithError(error: Error) {
print(error)
}
}
URLSession을 사용하면 HTTP를 포함한 몇 가지 프로토콜을 지원하고, 인증, 쿠키 관리, 캐시 관리 등을 지원합니다.
세션을 연결한 상태라면 앱이 실행되지 않는 상태여도 다운로드를 받을 수 있다!!! 이게 더 실제와 비슷한 거 같다
백그라운드상태에서도 음악 재생하기가 이런 기능인건가?
https://hcn1519.github.io/articles/2017-07/iOS_URLSession
일시정지되거나 다시 재생할 수 있는 백그라운드 만들기
Saving and Playing the Track 부터...
와 아예 세션 연결해서
다운로드 하는 거네
Foundation > URL Loading System > URLSession
class URLSession : NSObject
iOS에서는 앱이 not running이거나 suspended 상태에서 background 다운로드가 가능하다.
(not running은 실행 전, suspended는 백그라운드에서 실행되지 않을 때)
주요 delegate
URLSession의 종류
URLSessionConfiguration으로 설정
URL Session Tasks의 종류
Data tasks
: send and receive data using NSData objects. Upload tasks
: support background uploads while the app isn’t running.Download tasks
: support background downloads and uploads while the app isn’t running.WebSocket tasks
: WebSocket(RFC 6455)을 통한 TCP and TLSURLSessionTaskDelegate
세션은 strong 참조 관계를 가지고 있기 때문에 주의해야한다.
세션의 콜백 task를 관리하기 위해 URLSessionTaskDelegate를 사용한다.
비동기성 Asynchronicity
download(from:delegate:)
다운로드 받으면서, data(from:delegate:)
데이터를 가져올 수 있다.
전송이 완료되기 까지 await 키워드를 사용해 지연시킬 수 있다.
bytes(from:delegate:)
비동기적인 순서로 데이터를 가져올 수 있다.
URLProtocol을 상속받아 프로토콜도 사용 가능
왼쪽은 기본 검색을 지원하는 Default 세션
오른쪽은 Private한 검색을 지원하는 Ephemeral한 세션으로 캐싱하지 않는다
하나의 URLSession에 여러가지 Task가 있다
https://developer.apple.com/documentation/foundation/urlsession
https://www.raywenderlich.com/3244963-urlsession-tutorial-getting-started