๋คํธ์ํฌ
๊ฐ๋จํ๊ฒ ๋งํ์๋ฉด, ๋ ์ด์์ ์ปดํจํฐ๊ฐ ์ฐ๊ฒฐ๋๊ณ ์ํตํ๋ ๊ฒ
ํธ๋ํฐ๊ณผ ์๋ฒ์์ ํต์ ๋ ๋คํธ์ํฌ ํต์ ์ด๋ค.
๋คํธ์ํฌ์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํด์๋ ๋ฐ์ดํฐ๋ฅผ ํํํ๋ ์ ํด์ง ํ์์ ์ง์ผ ๊ตํํ๋ ๊ฒ์ด ์ข๋ค.
์๋ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋ฐ์ดํฐ ํ์์ด JSON ํ์์ด๋ค.
JSON์ key-value ํํ๋ฅผ ๊ฐ์ง๋ค.
[
{
"name": "Jihyeon",
"phoneNumber": "010-1111-2222"
},
{
"name": "Swift",
"phoneNumber": "010-3333-4444"
},
{
"name": "Apple",
"phoneNumber": "010-5555-6666"
}
]
ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฐํ ๋ ํ์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ฃผ๋ ์ฐฝ๊ตฌ, ์ค๋ช ์, ๋๊ตฌ์ด๋ค.
API๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๊ฐ API ์๋ฒ์๊ฒ ํ์ํ ์์ฒญ์ ํ๋ฉด API ์๋ฒ๋ API๋ฅผ ํตํด ์๋ต์ ํ๋ค.
Swift์ Codeable ํ๋กํ ์ฝ์ ์ฑํํ๋ฉด ์ธ์ฝ๋ฉ๊ณผ ๋์ฝ๋ฉ ๋ชจ๋ ๊ฐ๋ฅ
์๋ฒ์ ํต์ ํ๊ธฐ ์ํด์ JSON ํ์์ผ๋ก ์ธ์ฝ๋ฉ์ ๋ง์ด ํ๋ค.
๐ JSON ํ์์ ๋ฐ์ดํฐ์์ Swift๋ก ๋ฐ์ดํฐ๋ฅผ ๋์ฝ๋ฉํด์ ์ถ์ถํ๋ ๊ณผ์ ๐
1. Codeable์ ์ฑํํด ์ธ์ฝ๋ฉ๊ณผ ๋์ฝ๋ฉ์ด ๊ฐ๋ฅํ ๊ฐ์ฒด ์์ฑ
2. String์ผ๋ก JSON ๋ชจ์์ ๋ฐ์ดํฐ ์์ฑ
3. JSON ํ์์ผ๋ก ๋ฐ๊พธ๊ธฐ : jsonString์ผ๋ก jsonData ์์ฑ -> data(using: .utf8)
4. JSON ๋์ฝ๋(JSON -> ์๋ณธ์ผ๋ก ๋ณํ) : JSONDecoder()
5. Codeable ๋์ฝ๋ฉ ์งํ
import Foundation
struct PhoneBook: Codable { //Codable์ ์ฑํํด ์ธ์ฝ๋ฉ๊ณผ ๋์ฝ๋ฉ์ด ๊ฐ๋ฅํ ๊ฐ์ฒด๊ฐ ๋จ
let name: String
let phoneNumber: String
}
// string ์ผ๋ก json ๋ชจ์์ ๋ฐ์ดํฐ๋ฅผ ์์ฑ.
let jsonString = """
[
{
"name": "Jihyeon",
"phoneNumber": "010-1111-2222"
},
{
"name": "Swift",
"phoneNumber": "010-3333-4444"
},
{
"name": "Apple",
"phoneNumber": "010-5555-6666"
}
]
"""
// jsonString ์ผ๋ก jsonData ๋ฅผ ์์ฑ -> JSON ํ์์ผ๋ก ๋ฐ๋
let jsonData = jsonString.data(using: .utf8)!
// Swift ๊ฐ ์ ๊ณตํ๋ JSON ๋์ฝ๋.
let jsonDecoder = JSONDecoder()
// JSON -> Codable ๋์ฝ๋ฉ ์งํ.
do {
//jsonDecoder๋ก [PhoneBook] ํ์
์ผ๋ก jsonData์ ๋์ฝ๋ฉ ํ๋ค.
let phoneBooks = try jsonDecoder.decode([PhoneBook].self, from: jsonData)
for phoneBook in phoneBooks {
print("name: \(phoneBook.name), phoneNumber: \(phoneBook.phoneNumber)")
}
} catch {
print("JSON ๋์ฝ๋ฉ ์คํจ")
}
URL(Uniform Resource Locator)์ ์์์ ์์น๋ฅผ ๋ํ๋ด๋ ์๋ณ์๋ค.
์ฆ, ์น์์ ์์์ด ์ด๋์ ์๋์ง๋ฅผ ๊ฐ๋ฆฌํจ๋ค.
์น ๊ธฐ๋ฐ์ ๋คํธ์ํฌ ํต์ ์ ๊ฐ๋จํ๊ณ ์ผ๊ด์ฑ ์๊ฒ ์ค๊ณํ๊ธฐ ์ํ ์ํคํ ์ฒ ์คํ์ผ์ด๋ค.
REST๋ ์์์ URL๋ก ์๋ณํ๊ณ , HTTP ๋ฉ์๋(POST, GET, PUT, DELETE)๋ฅผ ์ฌ์ฉํ์ฌ ์์์ ์ฒ๋ฆฌํ๋ค.
JSON ๋๋ XML ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ API
๐ REST API์ ์ฃผ์ ๊ฐ๋ ๐
1. ์์ (Resource)
URI(Uniform Resource Identifier, URI ์์ URL์ด ํฌํจ๋ ๊ฐ๋ )๋ก ์๋ณ๋๋ ๋์.
์๋ฅผ ๋ค์ด, ์ฌ์ฉ์ ์ ๋ณด๋ /users๋ผ๋ URI๋ก ์๋ณ๋ ์ ์๋ค.
2. HTTP ๋ฉ์๋ : ์๋ฒ๊ฐ ํ์ ํ๊ธฐ ์ํ(ํต์ ํ๊ธฐ ์ํ) ์์ฒญ์ ์ข ๋ฅ
3. HTTP ์ํ ์ฝ๋
ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ํ ์๋ฒ์ ์๋ต ์ํ๋ฅผ ๋ํ๋.
** URL์ ๊ฐ์ง๊ณ ๋คํธ์ํฌ ํต์ ์ ํ ์ ์๊ฒ ํ๋ Swift ํด๋์ค๊ฐ URLSession.
import Foundation
// 1. ๋คํธ์ํฌ ์์ฒญ์ ๋ณด๋ผ URL์ ์์ฑ
let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1")!
// 2. URL์ ๊ธฐ๋ฐ์ผ๋ก URLRequest ๊ฐ์ฒด๋ฅผ ์์ฑ
var request = URLRequest(url: url)
// 3. URLRequest ๊ฐ์ฒด์ HTTP ๋ฉ์๋๋ฅผ GET์ผ๋ก ์ค์
request.httpMethod = "GET"
/* 4. URLSession์ ๊ธฐ๋ณธ shared ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ฌ URLSession์ ์์ฑ
URLSession์ ๋คํธ์ํฌ ์์
์ ๊ด๋ฆฌํ๋ ํด๋์ค๋ก, ์ธ์
์ ์์ฑํ๊ณ , ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ์์
์ ๊ด๋ฆฌ.
URLSession.shared๋ ๊ธฐ๋ณธ ์ธ์
์ธ์คํด์ค๋ก, ์บ์, ์ฟ ํค, ์ธ์ฆ์ ๋ฑ์ ๊ณตํต ๊ตฌ์ฑ์ ๊ฐ์ถ ๊ณต์ ์ธ์
์ ์ ๊ณตํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก shared ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐํธํ๊ฒ ๋คํธ์ํฌ ์์
์ ์ํํ ์ ์๋ค.
*/
let session = URLSession.shared
// 5. URLSessionDataTask๋ฅผ ์์ฑํ์ฌ GET ์์ฒญ์ ๋ณด๋ด๊ธฐ(์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ก)
let task = session.dataTask(with: request) { data, response, error in
// 6. ์๋ฌ๊ฐ ๋ฐ์ํ๋์ง ํ์ธ
if let error = error {
print("Error: \(error)")
return
}
// 7. ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์๋์ง ํ์ธ
guard let data = data else {
print("No data")
return
}
// 8. ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ JSON์ผ๋ก ํ์ฑ
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print("JSON Response: \(json)")
} catch {
print("Failed to parse JSON: \(error)")
}
}
/* 9. ์์ฒญ ์์
URLSessionDataTask๋ URLSessionDownloadTask ๋ฑ์ ์์
์ ์์ํ๋ ๋ฉ์๋.
๋คํธ์ํฌ ์์ฒญ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ผ์ ์ค๋จ๋ ์ํ๋ก ์์ฑ๋๋ฏ๋ก, resume()์ ํธ์ถํด ๋คํธ์ํฌ ์์
์์.
*/
task.resume()
์๋ต ์ฒ๋ฆฌ: URLSessionDataTask์ ํด๋ก์ ๋ด๋ถ์์ ์๋ต์ ์ฒ๋ฆฌํ๋ค.
ํด๋ก์ ๋ด๋ถ์ ์ฒ๋ฆฌ ๋ฐฉ์
ํด๋ก์ ๋ด๋ถ์์ ๋ฐ์ ๋ฐ์ดํฐ๋ ํด๋น ํด๋ก์ ๋ด๋ถ์์๋ง ์ฒ๋ฆฌ๋๋ค.
๋ฐ์ดํฐ๋ฅผ UI์ ์ ๋ฐ์ดํธํ๊ฑฐ๋ ๋ค๋ฅธ ๋น๋๊ธฐ ์์ ์ ์ํํด์ผ ํ ๊ฒฝ์ฐ,
ํด๋ก์ ์ธ๋ถ์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ ์ฝ๋ฐฑ์ ํธ์ถํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํ ๊ฐ๋ฅ.
๐ Swift์์๋ ๊ฐ๋ฅํ๋ฉด Codable ํ๋กํ ์ฝ์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋์ฝ๋ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋๋ฉฐ,
JSONSerialization์ ๋ ๋ฎ์ ์์ค์ JSON ๋ฐ์ดํฐ ์ฒ๋ฆฌ๊ฐ ํ์ํ ๋ ์ฌ์ฉ๋ ์ ์๋ค!!!!
import Foundation
// 1. POST ์์ฒญ์ ๋ณด๋ผ URL์ ์์ฑํฉ๋๋ค.
let url = URL(string: "https://jsonplaceholder.typicode.com/posts")!
// 2. URL์ ๊ธฐ๋ฐ์ผ๋ก URLRequest ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค.
var request = URLRequest(url: url)
// 3. ์์ฒญ์ HTTP ๋ฉ์๋๋ฅผ POST๋ก ์ค์ ํฉ๋๋ค.
request.httpMethod = "POST"
// 4. ์์ฒญ์ Content-Type์ ์ค์ ํด ์์ฒญ ๋ฐ๋์ ๋ฐ์ดํฐ ํ์์ JSON์ผ๋ก ์ค์ ํฉ๋๋ค.
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// 5. ์์ฒญ ๋ฐ๋์ ํฌํจํ JSON ๋ฐ์ดํฐ๋ฅผ ๋์
๋๋ฆฌ๋ก ์์ฑํฉ๋๋ค.
let parameters: [String: Any] = ["title": "foo", "body": "bar", "userId": 1]
// 6. ๋์
๋๋ฆฌ๋ฅผ JSON ๋ฐ์ดํฐ๋ก ๋ณํํ์ฌ ์์ฒญ ๋ฐ๋์ ์ค์ ํฉ๋๋ค.
// ๋์
๋๋ฆฌ ๊ฐ์ฒด๋ฅผ JSON ๋ฐ์ดํฐ๋ก ๋ณํํ์ฌ ์์ฒญ ๋ฐ๋์ ์ค์ .
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: [])
// 7. URLSession์ shared ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ฌ URLSession์ ์์ฑํฉ๋๋ค.
let session = URLSession.shared
// 8. URLSessionDataTask๋ฅผ ์์ฑํ์ฌ ์์ฒญ์ ๋ณด๋
๋๋ค.
let task = session.dataTask(with: request) { data, response, error in
// 9. ์๋ฌ๊ฐ ๋ฐ์ํ๋์ง ํ์ธํฉ๋๋ค.
if let error = error {
print("Error: \(error)")
return
}
// 10. ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์๋์ง ํ์ธํฉ๋๋ค.
guard let data = data else {
print("No data")
return
}
// 11. ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ JSON์ผ๋ก ํ์ฑํฉ๋๋ค.
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print("JSON Response: \(json)")
} catch {
print("Failed to parse JSON: \(error)")
}
}
// 12. ์์ฒญ์ ์์ํฉ๋๋ค.
task.resume()
์ฝ๋๋ฅผ ๋ณด๋ GET, POST๊ฐ ํท๊ฐ๋ฆฐ๋ค..๐ซ
์ฐจ์ด์ ์ ๋ํด ์ข ๋ ์ ๋ฆฌํด๋ณธ๋ค.
GET ์์ฒญ๊ณผ POST ์์ฒญ์ HTTP ํ๋กํ ์ฝ์์ ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ ๊ฐ์ง ์ฃผ์ ๋ฐฉ์์ด๋ค.
๋ชฉ์ : ์๋ฒ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
ํน์ง:
๋ชฉ์ : ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์ ์ ์ฅํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
์) ์ธ์คํ๊ทธ๋จ ํผ๋ ์ฌ๋ฆฌ๊ธฐ, ๋ค๋ฅธ ์ฌ๋์ ๊ฒ์๋ฌผ์ ๋๊ธ ๋ฌ๊ธฐ, ์๋น์ค ๊ฐ์
ํน์ง: