Postman을 통해서 네트워크 작업을 볼 수 있음
ios에서는 URLSession을 통해 네트워크 작업을 할 수 있음
Queue
- 컴퓨터 공학에서 말하는 자료 공학
- 먼저 들어온 값이 먼저 나가는 방식
네트워킹
- 기본적으로 HTTP라는 방법으로 Rest api를 이용해서 json데이터를 주고받음
Concurrency(동시성)
- 동시에 여러 가지 일을 수행하는 능력
- GCD와 Operration 통해서 동시성이 필요한 작업들을 관리해 줄 수 있음
- 사용자 인터랙션 처리, 네트워킹, 백그라운드에서 파일 다운로드, 파일 저장하고 읽기 같은 작업 수행 이러한 작업들을 스레드라고 함
Thread(스레드)
- 4개의 스레드가 있다고 가정, 4개의 스레드는 동시에 번갈아가면서 모든 작업을 함
- 메인 스레드는 사용자 인터렉션을 처리하면서 ui 표시하는 작업을 함
- 복잡한 계산이나 네트워크 느린 작업은 메인이 아닌 다른 스레드에서 처리해야 앱의 반응을 빠르게 가져갈 수 있음
HTTP
- 앱과 서버 간에 데이터를 주고받을 때 사용하는 통신 규약
- 동영상 스트리밍 할 때도 사용(HLS)
HTTP Request
- url창에 무언가를 입력하고 엔터를 눌렀을 때 하는 행위가 request 하는 방식
1. post: create
- 새로운 데이터를 해당 url에 생성을 요구할 때
2. get: read
- 해당 url에 있는 데이터를 보고 싶을 때
3. update: update
- 해당 url에 있는 데이터를 수정하고 싶을 때
4. delete: delete
- 해당 url에 있는 삭제하고 싶을 때
GCD
- 해야 할 일들을 만들어서 gcd에 넘기면 시스템에서 알아서 스레드를 할당해서 안전하게 수행시켜줌
- 스레드와 비슷한 개념
- gcd에서 사용하는 큐는 dispatch queue
- 테스크를 동기(Sync) & 비동기(Async)로 처리할 수 있음
Sync
- 앞에 작업이 끝나고 나서 다음 일을 처리하는 방식
Async
- 앞에 작업이 끝나지 않아도 다음 일을 시작하는 방식
- 해당하는 우선순위 작업에 따라 진행
- 다운로드하는 작업은 Async로 진행
// Async
// 일을 같이 처리
DispatchQueue.global(qos: .background).async {
for i in 0...5 {
print("A \(i)")
}
}
// 우선 순위가 더 높기 때문에 먼저 마무리
DispatchQueue.global(qos: .userInteractive).async {
for i in 0...5 {
print("B \(i)")
}
}
// Sync
// Sync는 먼저 일을 처리 후 그 다음 일을 처리
DispatchQueue.global(qos: .background).sync {
for i in 0...5 {
print("A \(i)")
}
}
DispatchQueue.global(qos: .userInteractive).async {
for i in 0...5 {
print("B \(i)")
}
}
Dispatch Queue
1. main queue
- 메인 스레드에서 작동하는 큐
- 시스템에서 제공
// main
DispatchQueue.main.async {
let view = UIView()
view.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
}
2. global queue
- 시스템에 의해 관리되는 큐
- 큐에 들어가는 테스크의 우선순위를 qos 클래스를 통해서 표현할 수 있음
- 시스템에서 제공
Qos
우선순위가 높은 순
- 1. userinteractive
-- 바로 수행되어야 할 작업에 대해서 userinteractive 설정
- 2. userinitiated
-- 사용자 결과를 기다리는 작업에 사용
- 3. default
-- userinitiated 보다 좀 더 걸리는 작업에 사용
- 4. utility
-- 몇 초 ~ 몇 분 걸리는 작업에 사용
-- 네트워킹이나 파일 불러오기 같은 작업에 사용
- 5.background
-- 사용자에게 당장 인식될 필요가 없는 경우 사용
3. custom queue
- 큐를 직접 만들어서 사용해야 하는 경우
- 시스템에서 제공하지 않음
// global
DispatchQueue.global(qos: .userInteractive).async {
// 가장 먼저 해줘야 하는 일
}
DispatchQueue.global(qos: .userInitiated).async {
// 사용자가 기다리고 있으니 빨리 해줘야 하는 일
}
DispatchQueue.global(qos: .default).async {
// 그냥 저냥 해도 되는 일
}
DispatchQueue.global().async { // default는 이런 식으로 표현 가능
}
DispatchQueue.global(qos: .utility).async {
// 시간이 좀 걸리는 일들, 사용자가 당장 없어도 상관 없는 일들, 네트워킹, 큰 파일 다운로드
}
DispatchQueue.global(qos: .background).async {
// 사용자한테 당장 필요하지 않은 일들, 뉴스데이터 미리 받기, 위치 업데이트, 영상 다운로드 등등
}
URLSession
- URLSession은 URLSessionConfiguration을 이용해서 생성을 하게 됨
- URLSessionTask를 만들 수 있음(URLSessionTask를 통해 서버와 통신함)
- URLSeesionDelegate을 통해 네트워킹 중간 과정을 확인할 수 있음
URLSessionConfiguration
- URLSessionConfiguration을 생성할 때는 URLSession 정책에 따라서 Default, Ephemeral, Background 세 가지 타입으로 만들 수 있음
1. Default
- 기본 통신할 때 사용
2. Ephemeral
- 쿠키나 캐시 같은 것을 저장하지 않게 정책을 가져갈 때 사용(예: 시크릿 모드)
3. Background
- 다운로드할 때 사용
URLSessionTask
1.URLSessionDataTask
- 기본적인 데이터를 받는 작업에 사용
- response 데이터를 메모리 상에서 처리
- 백그라운드 세션에 대한 지원이 안됨
2. URLSessionUploadTask
- 파일 업로드할 때 사용
3. URLSessionDownloadTask
- 파일 다운로드할 때 사용
import UIKit
// url
// 웹 리소스의 주소
let urlString = "https://itunes.apple.com/search?media=music&entity=song&term=Gdragon"
let url = URL(string: urlString)
url?.absoluteString // urlStrung에 입력된 값을 보여줌
url?.scheme // 어떤 방식으로 네트워킹을 하고 있는지 확인 시켜줌
url?.host
url?.path
url?.query // 검색에 대한 조건
url?.baseURL
let baseURL = URL(string: "https://itunes.apple.com")
let relativeURL = URL(string: "search?media=music&entity=song&term=Gdragon", relativeTo: baseURL)
relativeURL?.absoluteString
relativeURL?.scheme
relativeURL?.host
relativeURL?.path
relativeURL?.query
relativeURL?.baseURL
// URLComponents
var urlComponents = URLComponents(string: "https://itunes.apple.com/search?")
let mediaQuery = URLQueryItem(name: "media", value: "music")
let entityQuery = URLQueryItem(name: "entity", value: "song")
let termQuery = URLQueryItem(name: "term", value: "Gragon")
urlComponents?.queryItems?.append(mediaQuery)
urlComponents?.queryItems?.append(entityQuery)
urlComponents?.queryItems?.append(termQuery)
urlComponents?.url
urlComponents?.string
urlComponents?.queryItems
import UIKit
var urlComponents = URLComponents(string: "https://itunes.apple.com/search?")!
let mediaQuery = URLQueryItem(name: "media", value: "music")
let entityQuery = URLQueryItem(name: "entity", value: "song")
let termQuery = URLQueryItem(name: "term", value: "지드래곤")
urlComponents.queryItems?.append(mediaQuery)
urlComponents.queryItems?.append(entityQuery)
urlComponents.queryItems?.append(termQuery)
let requestURL = urlComponents.url!
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
struct Response: Codable {
let resultCount: Int
let tracks: [Track]
enum CodingKeys: String, CodingKey {
case resultCount
case tracks = "results"
}
}
struct Track: Codable {
let title: String
let artistName: String
let thumbnailPath: String
enum CodingKeys: String, CodingKey {
case title = "trackName"
case artistName
case thumbnailPath = "artWorkUrl100"
}
}
let dataTask = session.dataTask(with: requestURL) { (data, response, error) in
guard error == nil else { return }
guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
let successRange = 200..<300
guard successRange.contains(statusCode) else {
// handle response error
return
}
guard let resultData = data else { return }
let resultString = String(data: resultData, encoding: .utf8)
// 파싱
do {
let decoder = JSONDecoder()
// try - 해당 작업이 항상 성공 한다는 보장이 없음, 시도를 하다가 오류가 생기면 catch 구문으로 빠짐
let response = try decoder.decode(Response.self, from: resultData)
let tracks = response.tracks
print("tracks: \(tracks.count) -\(tracks.first?.title), \(tracks.last?.thumbnailPath)")
} catch let error {
print("error: \(error.localizedDescription)") // 오류에 대한 설명은 localizedDescription에 나와 있음
}
}
dataTask.resume()
'Swift' 카테고리의 다른 글
Firebase / Cocoa Pods (0) | 2021.03.22 |
---|---|
넷플릭스 스타일 앱 만들기 / 오픈 소스 가져오는 방법 (0) | 2021.03.19 |
List App (0) | 2021.03.15 |
뮤직 앱 (0) | 2021.03.13 |
CollectionView (0) | 2021.03.06 |