Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

개발자의 삽질

[iOS] URLSession 을 이용한 네트워킹 본문

iOS

[iOS] URLSession 을 이용한 네트워킹

uniqueimaginate 2022. 1. 12. 23:38

https://developer.apple.com/documentation/foundation/urlsession

 

Apple Developer Documentation

 

developer.apple.com


이번 글은 URLSession 에 대해 알아보자!

iOS에서 네트워킹을 할 때는 URLSession을 통해서 한다.

URLSession 의 개요는 다음과 같다.

실습!

코드에 적혀 있는 주석에 유의해서 살펴보자!

import UIKit

// URL

let urlString = "https://itunes.apple.com/search?media=music&entity=song&term=Gdragon"
let url = URL(string: urlString)

url?.absoluteString
// https://itunes.apple.com/search?media=music&entity=song&term=Gdragon
url?.scheme
// https
url?.host
// itunes.apple.com
url?.path
// /search
url?.query
// media=music&entity=song&term=Gdragon
url?.baseURL
// nil

let baseURL = URL(string: "https://itunes.apple.com.")
let relativeURL = URL(string: "search?media=music&entity=song&term=Gdragon", relativeTo: baseURL)

relativeURL?.absoluteString
// https://itunes.apple.com/search?media=music&entity=song&term=Gdragon
relativeURL?.scheme
// https
relativeURL?.host
// itunes.apple.com
relativeURL?.path
// /search
relativeURL?.query
// media=music&entity=song&term=Gdragon
relativeURL?.baseURL
// https://itunes.apple.com/


// URLComponents
// 쿼리를 오브젝트로 추가하거나 접근하고 싶을 때가 있다. 그럴 때 쓰면 된다.
// 한글 인코딩의 경우도 그냥 URL 로 쓰면 에러가 발생하는데 이 녀석을 쓰면 자동으로 인코딩을 해주기 때문에 정상 작동하게 된다.

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)

urlComponents?.url?.scheme
// https
urlComponents?.string
// https://itunes.apple.com/search?media=music&entity=song&term=%EC%A7%80%EB%93%9C%EB%9E%98%EA%B3%A4
// 한글이 인코딩 되어 있는 것을 확인 할 수 있다.
urlComponents?.queryItems
// [{name "media", value "music"}, {name "entity", value "song"}, {name "term", value "지드래곤"}]

여기서 인코딩과 관련된 말이 나오는데 [Swift] URL Encoding 을 위한 Character Set 살펴보기 블로그 글을 보자!

 

URLSessionConfiguration 을 먼저 설정한 후, URLSession 에 넣어준다.

그 후 URLComponents 를 이용해 URL 을 세팅한다.

import UIKit
import Foundation

// URLSession

// 1. URLSessionConfiguration
// 2. URLSession
// 3. URLSessionTask 를 이용해서 서버와 네트워킹

// URLSessionTask

// - dataTask
// - uploadTask
// - downloadTask

let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)

// URL
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!
// https://itunes.apple.com/search?media=music&entity=song&term=%EC%A7%80%EB%93%9C%EB%9E%98%EA%B3%A4

 

이제 Codable 을 상속받는 2개의 구조체를 만든다.

Codable 에 대한 글은 나중에 다시 다루도록 하겠다.

그러나 간단하게 말하자면, JSON 형태의 API Response 를 받게 하는 구조를 손쉽게 만들게 해주는 클래스이다.

 

참고로 각 구조체 안에 있는 CodingKeys 는

구조체의 프로퍼티 명칭과 실제로 들어오는 JSON Key 값이 다를 경우, 맞춰주는 해준다.

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 = "artworkUrl30"
    }
    
    // trackName
    // artistName
    // artworkUrl30
}

이제 URLSessionTask 부분이다.

let dataTask = session.dataTask(with: requestURL) { (data, response, error) in
	// 에러 발생했을 경우 return
    guard error == nil else { return }
    
    // http response 의 상태 코드 확인
    guard let statusCode = (response as? HTTPURLResponse)?.statusCode else { return }
    let successRange = 200..<300
    
    // 상태 코드가 200 에서 300 사이가 아닐 경우
    // 에러 처리를 한 후에 return
    guard successRange.contains(statusCode) else {
        // handle response error
        return
    }
    
    // response 데이터가 없을 경우 return
    guard let resultData = data else { return }
    
    // 받은 데이터를 utf8 로 인코딩
    let resultString = String(data: resultData, encoding: .utf8)
    
    
    // 파싱 및 트랙 가져오기
    do {
    
    	// 아까 만든 Codable 을 상속받은 구조체를 이용해 JSON 파싱을 진행한다.
        let decoder = JSONDecoder()
        let response = try decoder.decode(Response.self, from: resultData)
        let tracks = response.tracks
        
        print("---> tracks: \(tracks.count)  -\(tracks.last?.title), \(tracks.last?.thumbnailPath)")
        
    } catch let error {
        print("---> error: \(error.localizedDescription)")
    }
    
//    print("---> result :\(resultString)")
}

dataTask.resume()

아래는 결과이다.

// ---> tracks: 50  -Optional("YOU DO (Outro)"), Optional("https://is1-ssl.mzstatic.com/image/thumb/Music118/v4/2a/61/2c/2a612c2b-7d08-d91a-3c29-396394869ace/source/30x30bb.jpg")
여기까지 URLSession에 대해 알아보았다!
Comments