티스토리 뷰
HTTP 프로토콜
서버와 클라이언트는 "정해진 형태"로 "요청"과 "응답"을 주고 받는다.
클라이언트 -> 서버에게 HTTP 방식으로 요청할 때에는 여러가지 방법이 존재!
GET -> 데이터를 얻고 싶을 때 요청
HEAD -> 헤더 정보를 얻고 싶을 때 요청
POST -> 내용을 전송할 때
PUT -> 내용을 갱신하고 싶을 때
DELETE -> 내용을 삭제하고 싶을 때
OPTIONS -> 가능한 메소드 옵션을 파악할 때
TRACE -> 리소스가 수신되는 경로를 파악할 때
PATCH -> 리소스를 일부 수정할 때
서버는 요청한 메서드에 맞춰서 Response를 클라이언트에게 전달한다 !
REST (Representational State Transfer)
자원을 이름으로 구분해, 자원의 정보를 주고 받는 것 -> 하나의 개발 아키텍쳐 개념
REST API 는 행위 / 자원 / 메세지로 구성이 된다.
행위
HTTP 메서드 중에서 GET / POST / DELETE 를 사용
자원
URL 을 통해 오브젝트에 접근하게 된다.
메시지
JSON 포맷의 데이터로 메세지를 받는다.
JSON 은 JavaScript Object Notation 의 약자로, 데이터를 저장하거나 전송할 때 사용하는 형식이다.
key - value 형태이며, 모두 ""를 이용해 표기해야 한다.
객체, 배열 등을 사용할 수 있고, 중첩이 가능한 형태이다.
클라이언트가 서버에게 해당 URl를 통해 GET 요청을 하면,
JSON 형태로 데이터를 받는다!
JSON <- 데이터 모델 (Encode)
struct 데이터모델: Encondable
JSON -> 데이터 모델 (Decode)
struct 데이터모델: Decodable
Encode 예시
import UIKit
struct PersonDataModel : Encodable
{
var name : String
var age : Int
}
class ViewController: UIViewController {
let personData = PersonDataModel(name: "철수", age: 10)
override func viewDidLoad() {
super.viewDidLoad()
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
do
{
let data = try jsonEncoder.encode(personData)
print(String(data: data, encoding: .utf8)!)
}
catch
{
print(error)
}
}
}
do - catch // try 문에 대해 살펴보자 ..!
해당 구문은 오류처리를 위한 문법이며, 오류 처리는 3가지 과정을 통해 진행된다 !
1번 - 오류를 정의한다.
enum (열거형)을 통해, Error 프로토콜을 채택해서 에러의 종류를 나열한다.
-> 해당 상황에서 발생할 수 있는 에러를 나열하는 것 !
enum SampleError : Error {
case invalidNumber
case invalidUser
}
2번 - 오류를 던진다
함수 이름 옆에, throws 라는 키워드를 붙이게 되면 이 함수에서는 throw가 가능하다! 라는 뜻이다.
class SampleObject
{
func printNumber(_ number: Int) throws -> Int {
if number < 0 {
throw SampleError.invalidNumber
}
return number
}
}
함수 내에서 예외 사항(오류)인 경우에 아까 우리가 선언한 Error을 사용해 throw 던져버린다.
3번 - 던진 오류 처리하기
throw로 던진 에러를 우리는 잡는다! 라는 의미로 예외 처리는 catch라는 구문을 사용한다.
let object = SampleObject()
do {
let resultNumber = try object.printNumber(-20)
print(resultNumber)
}
catch {
switch(error)
{
case SampleError.invalidNumber: print("number Error")
case SampleError.invalidUser : print("user Error")
default:
print("알 수 없는 에러 발생")
}
}
do 구문 안에서 printNumber를 실행하려면 try라는 키워드가 필요하다.
printNumber는 에러가 발생할 수 있는 함수이기 때문이다.
우선 시도해보고... 성공하면 resultNumber로 넘기고, 실패하면 catch로 던져버린다는 뜻 !
* try! 나 try? 를 사용하면 do - catch 문이 필요가 없다.
대신 try! 에서 실패하면 에러가 발생하고, try?는 성공하면 optional 형으로 데이터를 뱉어내서
옵셔널 바인딩이 따로 필요하다 !
Decode 예시
import UIKit
struct CoffeeDataModel : Decodable {
var drink : String
var price : Int
var orderer : String
}
class ViewController: UIViewController {
let dummyData = """
{
"drink" : "아메리카노",
"price" : 2000,
"orderer" : "JH"
}
""".data(using: .utf8)!
override func viewDidLoad() {
super.viewDidLoad()
let jsonDecoder = JSONDecoder()
do
{
let order = try jsonDecoder.decode(CoffeeDataModel.self, from: dummyData)
print("디코더 성공")
dump(order)
}
catch
{
print(error)
}
}
}
Encode와 다르게 Decode에서는 고려해줘야 할 것이 2가지가 있다.
1. Key의 이름이 변경되었을 때
CodingKeys를 사용하면 기존 프로퍼티 이름은 그대로 놔두고, JSON에서 넘어오는 이름에 대응할 수 있다.
JSON의 key값과, 프로퍼티의 이름이 동일하다면 case이름만 선언!
꼭 CodingKeys라는 이름으로 열거형을 선언해야한다!
2. Key - Value 한 쌍 자체가 없을 때
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
drink = (try? values.decode(String.self, forKey: .drink)) ?? ""
price = (try? values.decode(Int.self, forKey: .price)) ?? 0
orderer = (try? values.decode(String.self, forKey: .orderer)) ?? ""
}
만약 try? 해서 decode 했는데 실패한다면 우측에 있는 빈스트링("") or 0이 값으로 할당되어 decode가 진행
Key - Value 한 쌍 자체가 아예 없을 경우에 기본값으로 정해둔 값이 할당된다.
예외 경우를 처리하기 위해 작성 !
JSON 파일과 Swift 데이터 구조가 1대1로 완벽하게 매칭된다면 위 2개는 작성하지 않아도 괜찮다.
하지만, 요 두가지 예외 사항을 처리하기 위해 우리는 Decodable 한 구조체를 작성한다 !
'Sopt 28th 세미나 - iOS' 카테고리의 다른 글
[Swift] Alamofire (GET) & Postman (0) | 2021.08.20 |
---|---|
[Swift] Escaping Closure & Singleton Pattern (0) | 2021.08.20 |
[Swift] Animation (0) | 2021.08.16 |
[Swift] Refresh Control (당겨서 새로고침) (0) | 2021.08.16 |
[Swift] Activity Indicator & Lottie (0) | 2021.08.16 |