9월, 2021의 게시물 표시

URLSession 공부의 시작점

이미지
iOS 개발 뿐 아니라 많은 서비스 들을 개발하다 보면 네트워크를 다루게 됩니다. 네트워크를 처음 접한 건 라이브러리를 사용해서 입니다. 그런데 구현체가 어떻게 생겼는지 모르고, 네트워크 통신 규약 문서를 볼 수 없는 상태로 사용만 하는 것은 문제가 생겼을 때 해결할 수 없었습니다. 그래서 moya 나 alamofire 과 같은 라이브러리들이 어떻게 구현되어 있는지 그리고 URLSession 은 어떻게 이루어져 있는지 정리하려고 합니다. 동기 비동기 네트워크를 공부하기 전에 동기, 비동기를 먼저 공부하는 걸 추천 드립니다. 왜냐하면 네트워크는 여러가지 요청과 응답이 처리되어야 하는데, 이 작업들이 동기로 처리되어야 하는지 비 동기로 처리되어야 하는지를 판단하거나 이해하지 못하면 전반적인 내용에 대해서 이해하기 어렵습니다. 해당 내용은 여기 에 정리한 적이 있습니다. 네트워크 프로세스 가장 많이 만나는 코드 중 하나를 가지고 예를 들어 보도록 하겠습니다 let urlSession = URLSession(configuration: . default ) // 1. let task = urlSession.dataTask( with : url) { data, response, error in // 2. print(response ?? "no response" ) } task.resume() // 3. URLSession 클래스를 이용해 세션을 하나 만듭니다. 그 세션은 여러가지 일을 할 수 있는데, URLSession에 구현되어있는 메소드로 어떤 일(task)을 추가할 수 있습니다. 그리고 그 일을 하는 task 객체를 반환 합니다. task는 resume() 으로 실행합니다. 그럼 순서대로 알아보도록 하겠습니다. 세션 만들기 URLSession 은 세션을 만든다고 언급했습니다. 그러면 어떻게 만들 수 있을까요? 코드를 살펴보면 init(configuration: URLSessionConfiguration)

[인터뷰질문 017] protocols을 주니어 개발자에게 어떻게 설명해 줄 것 인가요?

이미지
프로토콜이란? 프로토콜은 인터페이스 입니다. swift에서는 특정 기능을 정의합니다. 실제 구현은 하지 않고 정의만 합니다. 마치 설계도와 같죠. 간단한 예제 간단한 예제를 보도록 하겠습니다. 자동차의 기능을 구현하기에 앞서 일단 정의하려고 하는데요. 자동차가 주행에 필요한 것들을 나열해 봅시다. 간단하게 생각해서 출발과, 정지를 할 수 있으면 자동차가 주행할 수 있겠죠? 앞에 나오는 조건들이 주행에 필요한 요소들이라고 했으니 이 조건들을 모두 갖추면, 주행이 가능하다고 할 수 있습니다. 그럼 한번 설계 해 볼까요? protocol Driveable { func start () func stop () } 이렇게 설계 해 놓으면 이 프로토콜을 채택하면, 아 주행가능하구나 라고 생각하면됩니다. 아래와 같이 구현되겠죠? struct Sonata : Driveable { func start () { print ( "주행 시작합니다." ) } func stop () { print ( "주행 종료합니다." ) } } 사실 위에서 Driveable 프로토콜을 채택하지 않아도 돌아가는데는 문제가 없습니다. 하지만 다른 곳에서 사용할 때 프로토콜을 채택하고 있지 않으면 주행이 가능한건지에 대한 보장이 되지않겠죠? 그렇기 때문에 설계와 기능의 보장을 위해 프로토콜을 정의해서 채택해서 써야합니다. 여러 프로토콜 하나의 프토콜이 한 종료의 기능을 보장해준다면, 여러개의 기능은 아래와 같이 여러개의 프로토콜을 채택해서 구현할 수 있을 것 입니다. 거꾸로 이 객체가 어떤 기능을 하는지에 대한 것들은 프로토콜을 살펴보는 것 만으로도 가능 합니다. protocol Driveable { func start () func stop () } protocol Openable { func open () f

[인터뷰질문 016] operator overloading을 주니어 개발자에게 어떻게 설명해 줄 것 인가요?

이미지
오버라이딩 이 문제를 이해하기 위해서는 오버라이딩이라는 개념을 알고 있어야 합니다. 오버라이딩은 쉽게 말해 같은 이름의 다른 타입의 함수를 정의하는 것 입니다. 두개의 인자를 받아서 더하는 함수를 정의해 보겠습니다. func sum(_ a : Int, _ b : Int) -> Int { return a + b } func sum(_ a : Double, _ b : Double) -> Double { return a + b } print (sum( 3 , 2 ) ) // 5 print (sum( 4.1 , 4.2 ) ) // 8.3 두 숫자의 합을 구하고 싶을 때, 매개별수로 정수와 실수가 들어가야 한다면, 이렇게 한 함수를 오버라이딩해서 사용하는 사람이 편하게 쓸 수 있도록 구현할 수 있습니다. 연산자 오버라이딩 이름에서 알 수 있듯이, 연산자를 오버라이딩 하는 것 입니다. 우리가 알고있는 연산자는 다음과 같습니다. + , - , / , * 등등... 그렇다면, 언제 연산자를 오버라이딩 할까요? 아래 예제를 보면서 생각해 보겠습니다. struct Point { var x = 0.0 var y = 0.0 } let p1 = Point(x: 12.3 , y: 34.5 ) let p2 = Point(x: 67.2 , y: 89.6 ) 두개의 좌표가 있을 때, 좌표의 합을 구하고 싶다면, 어떻게 해야할까요? 쉽게드는 생각은 p1 + p2 하면 x는 x끼리 y는 y끼리 더해주었으면 좋겠는데, 실제 돌려보면 binary operator '+' cannot be applied to two 'Point' operands print(p1 + p2) 와 같은 에러가 발생합니다. 왜냐하면 + 연산자는 좌표를 더하는 것에 대한 처리가 되어있지 않기 때문입니다. 그렇다면? 위에서 봤던 예제처럼 연산자를 오버라이딩 하면 문제를 해결할 수 있을것 같습니다. struct Poi