[iOS/Swift] 네트워크통신 - 데이터를 Class가 아닌 Struct형태로 받는 이유

HTTP 프로토콜을 이용해 서버와 통신하는 경우, 클라이언트쪽에서는 서버에서 받은 데이터를 가공해서 사용해야 한다.

이 과정을 디코딩이라고 하는데, 보통 Swift에서 데이터를 받는 그릇으로 struct로 만드는 편이다.

그러니까, 서버에서 String형태로 오는 데이터를 struct에 담아 가공해서 데이터를 사용하는 방식이라고 생각하면 된다.

 

그러다보니 이런 궁금증이 생겼다.

"왜 class가 아닌 struct로 받는거지?"

 

이번 글에서는 iOS의 네트워크통신과, struct/class의 차이점을 알아보겠다.


iOS의 네트워크통신

클라이언트가 서버에게 "이런 데이터 가져다줘!"라고하고, 서버가 해당 데이터를 응답으로 주는걸 보통 "네트워크 통신을 한다"고한다.

이러한 정보 요청에 대한 기준을 API라고 하며, 그 과정을 그림으로 나타내면 다음과 같다.

클라이언트는 API Key와 GET, POST 등과 같은 HTTP METHOD와 함께 서버에게 요청을 하고, 서버는 이에 대한 응답으로 JSON이나 XML의 형태로 돌려주게 된다.

보통은 JSON의 형태를 많이 사용하는데, 응답의 형태는 다음과 같다.

 

이렇게 String형식으로 된 JSON파일을 앱에서 사용하려고 하면 데이터 가공의 과정이 필요한데, 그 과정을 Decoding이라고 한다.

반대로 서버로 데이터를 넘겨줄 때 JSON 형태로 가공하는걸 Encoding이라고 한다.

아무튼, iOS에서는 response로 온 데이터를 다음과 같이 구조체를 만들어서, 그 구조체에 담아서 사용한다.

struct Photo: Decodable {
    let total: Int
    let results: [PhotoDetail]
}

struct PhotoDetail: Decodable {
    let id: String
    let created_at: String
    let width: Int
    let height: Int
    let urls: PhotoURL
    let likes: Int
    let user: User
}

물론 실제 구조는 더 복잡하지만, 이런식으로 데이터를 담을 그릇을 만들어준다고 생각하면 된다.

 

그런데 문득 다음과 같은 의문이 들었다.

 

"어차피 데이터를 담는 그릇이라는건 struct나 class나 비슷한데, 왜 굳이 struct를 사용하는걸까?

 


데이터를 Class가 아닌 Struct형태로 받는 이유

사실 "절대 class를 사용하면 안되고, 무조건 struct를 사용해야해!" 라는건 당연히 아니긴 하다.

그런데 찾아보다보니 공식문서에서도 class와 struct의 사용에 대한 글이 있었는데, 그 내용을 정리하자면 다음과 같다.

앱에 새로운 데이터 유형을 추가할 때 어떤 옵션이 적합한지 선택할때는, 다음의 권장사항을 고려해보세요.
- 기본적으로 Struct를 사용하세요.
- Objective-C와 상호 운용성이 필요한 경우 Class를 사용하세요.
- 모델링하는 데이터의 Identity를 제어해야 하는 겨우 Class를 사용하세요.
- Struct와 Protocol을 함께 사용하여 상속을 모델링할 수 있습니다.

 

이 글의 골자는 기본적으로는 struct를 사용하되, 필요한 경우 class를 사용하라는것을 권장하고 있다.

기본적으로 struct를 사용하는 이유는 다음과 같다.

 

Struct를 사용하면 앱의 전체 상태를 고려하지 않고도 코드의 일부에 대해 추론하기가 더 쉬워집니다. Struct는 Class와 달리 값 타입이므로 Struct에 대한 로컬 변경 사항은 앱의 흐름의 일부로 의도적으로 변경 사항을 전달하지 않는 한 앱의 나머지 부분에서 볼 수 없습니다. 결과적으로 코드 섹션을 보고 해당 섹션의 인스턴스에 대한 변경 사항이 간접적으로 관련된 함수 호출에서 보이지 않게 변경되는 것이 아니라 명시적으로 변경된다는 확신을 가질 수 있습니다.

너무.. 말이 어려워서 조금 더 찾아보고 해석해본 결과,

class가 참조타입인것과 다르게 struct는 값타입이기 때문에, 값의 변경 사항을 의도적으로 전달하지 않는 이상 다른 부분에서 확인할 수 없다는, 일종의 추론의 편리성을 제공한다는 것이다.

만약 class를 사용했다면 이곳저곳에서 참조를 할수도 있고, 인스턴스가 변경될 수도 있기 때문에 코드에서 신경써야할 부분이 많아지는데, struct는 그에비해 덜 신경써도 된다는 말이다.

 

단순히 신경을 덜써서 좋다기보다, 어쨌든 struct는 독립적인 메모리 공간을 가지게 되고, 데이터를 누군가 참조해서 변경할 수 없으므로 데이터의 불변성을 유지할 수 있게된다.

이러한 struct의 특징을 통해 네트워크로 부터 받은 데이터의 무결성을 보장할 수 있으므로 class보단 struct를 사용하는것이 더 좋아보인다.

 

물론, 위에서 언급한 class의 단점은 여러 방법을 통해 극복해볼수는 있으며, 마찬가지로 struct의 장점 역시 예외가 있을수도 있다.

그러나 기본적으로 애플에서도 class보다는 struct의 사용을 권장하고 있으므로, 네트워크 통신의 데이터를 받을 때도 struct를 사용하는것이 더 바람직해 보인다.

 

 

 

※참고자료