Responder Chain Responder란 터치 이벤트를 처리할 수 있는 객체를 의미합니다. 터치 이벤트가 발생할 경우 iOS는 터치이벤트가 발생한 지점의 최상위 뷰를 찾습니다. 최상위 뷰를 First Responder이라 하는데 만약 First Responder가 이벤트를 처리하지 못할경우 최상위 뷰에서 하위뷰로 파고들며 이벤트를 처리 가능한 Responder를 찾게 되는데 이 과정을 Responder Chain이라 합니다. First Responder First Responder는 hitTest(_:with) 메서드로 찾는습니다. 이 메서드는 터치 이벤트가 발생했을 시점에 최상위 뷰의 hitTest가 호출될때까지 UIWindow부터 터치된 지점의 subView들의 hitTest 메서드를 순차적으..
댓글이나 게시글의 목록을 보면 현재시간을 기준으로 몇분전, 몇일전, 혹은 날짜로 시간이 나와있는 경우가 있습니다. Swift에서는 Calender를 이용하여 계산할 수 있습니다. 서버에서 생성 시간을 받아오고 나서 우선 Calender로 계산할 수 있는 시간 형식을 만들어줍니다. private func calculateDate(to dateStr: String) -> Date { //서버에서 받은 시간이 2022-06-21T14:06:35.288Z 형식으로 되어있으므로 Calender로 계산할 수 있는 형식으로 만들기 var sliceDateStr = dateStr.components(separatedBy: ["T", "."]) sliceDateStr.removeLast() let joinedDateSt..
요즘 모집공고의 우대 사항을 보면 UnitTest, 클린 아키텍쳐, TDD 이런게 꼭 한두가지씩은 들어가 있습니다. UnitTest와 TDD는 자바 스프링을 공부해 보신분이나 테스트 코드를 작성해 보신분을 알고 계시겠지만 TDD는 Test Driven Development로 테스트 주도 개발을 뜻합니다. IOS에서는 UnitTest를 통해 계속해서 테스트를 하면서 개발을 해나가는 것이지요. 말은 쉽지만 UnitTest를 하기 위해서는 각 기능을 분리시켜서 하나의 역할을 하게 코드를 구성해야 합니다. 하지만 마구잡이식으로 분리를 하다보면, 코드가 어지러워지고 가독성이 떨어질 수도 있고, 똑같은 기능을 하는 코드를 계속 다시 작성하는 경우도 있으며, 기능 하나 추가하는데 다른 기능의 소스코드를 수정해야 하거..
이번에 진행하고 있는 프로젝트에 본격적으로 클린 아키텍쳐, 객체지향 프로그래밍, solid 원칙 등등을 적용해 보기로 결정해서 공부해 보기로 했습니다. 우선은 객체지향 프로그래밍의 특성인 캡슐화와 은닉화에 대해서 알아보도록 하겠습니다. 은닉화 외부에서 내부의 변수나 연산등을 접근하지 못하도록 하는 것을 의미합니다. private를 붙이는것을 은닉화라고 할 수 있습니다. 또 함수 getter, setter를 이용해서 private로 선언된 변수를 접근 제어 하는것 역시 은닉화입니다. 캡슐화 실제로 구현되는 부분은 외부에 드러나지 않고, 사용하는 방법만 알려주고, 특정한 목적을 위해 필요한 변수나 로직을 하나로 묶어서 외부에서 사용 할 수 있게 해주는것을 캡슐화라고 합니다. 다만 아무거나 묶으면 안되고 목적..
서버 API에서 목록을 받아 테이블 뷰에 이를 표시할 때 이미지같은 어느정도 사이즈가 있는 것을 셀마다 넣어 줄 때가 있습니다. 이미지들을 넣을때는 보통, 서버에서 이를 받아와서 화면에 나타내는 식으로 처리를 합니다. 그런데 테이블 뷰의 셀은 reuse로 인해 화면 바깥으로 나간 후 다시 화면에 보이면 재사용하는 식으로 작동합니다. UIImage를 extension해서 셀의 이미지를 다운로드할 때 print를 찍어보았습니다. 셀이 reuse 되면서 계속해서 이미지를 다운로드 한다는걸 볼 수 있습니다. 테이블 뷰가 reuse 될때마다 계속 다운로드 하는것은 사용자의 많은 자원 소모와 앱의 성능 저하를 야기합니다. 이러한 문제를 해결하기 위해 NSCache를 이용합니다. NSCache란? 기본적인 개념은 캐..
음의 pitch값을 조정, 재생 속도를 조절할때는 AVAudioEngine을 사용한다. AVAudioEngine은 AVAudioPlayerNode로 음원파일을 재생시키고, MixerNode, AVAudioUnitVarispeed, AVAudioUnitTimePitch 노드를 추가해 사용자가 원하는 형태로 음원을 조정할 수 있다. AVAudioPlayerNode의 scheduleFile에는 AVAudioPlayerNodeCompletionCallbackType이라는 completionHandler가 있습니다. 이 핸들러는 재생되고 있는 음원파일이 재생이 끝나면 핸들러 내부의 코드를 실행합니다. 처음에는 단순히 여기에서 PlayerNode를 stop을 하고 다시 예약을 하면 되는게 아닐까 하고 개발을 했지만..