2021 1분기 회고

2021 1분기 회고 2021 1분기 회고 1년동안 있었던 일을 하루, 이틀만에 글로 적어 놓는 것은 너무나 많은 것들을 놓치는 것 같아 분기마다 회고를 적고, 4개의 회고를 합친 것이 1년의 회고가 되었으면 해서 분기별로 회고를 적게 되었습니다. 개발자는 항상 스스로 뒤쳐지지 않는지 고민하고, 내가 무엇을 하는데 시간을 썼는지 관심있어야 한다고 생각합니다. 1분기에는 어디에 시간을 썼고 얼마나 성정했는지 정리해보려 합니다. 2번째 앱 배포 첫 번째 개인앱인 토큰 메모를 유지 보수하면서, 2번째 앱인 그러나커밋을 배포 했습니다. 누군가를 위해서 앱을 만들기보다는 내가 필요한, 나의 삶의 질을 올려줄 수 있는 앱을 만들었습니다. 만들면서 즐겁고, 필요한 생기니 개발이 훨씬 즐겁습니다. 다만 문제는 기록에 쓰던 시간들이 줄어들어 블로그 관리가 소홀해지고, 다시 모든것이 후다닥 지나가면서 휘발되는 것 같은 느낌이 사라지지 않습니다. 만들면서 배웠던 것들 삽질했던 것들을 잘 정리해야겠습니다. 2번째 앱은 1일 1커밋을 하면서 시작하면서 불편함을 느껴서 만든 앱 입니다. 내가 매일 얼마나 커밋을 하고 있는지 한 눈에 확인이 가능하고, 나에게 동기부여를 해 줄 수 있는 앱을 만들었습니다. 조언과 피드백은 언제나 환영이에요 :) 다시 시작한 1일 1커밋 이전에 데이터 분석을 하면서 1일 1커밋을 한 적이 있습니다. 그 때 채 1년이 되기 전에 1일 1커밋을 그만 두었던 이유가 몇 가지 있었습니다. 가장 큰 예를 들어보자면 아래와 같습니다. 의미없는 커밋을 위한 시간이 아깝다. 1일 1커밋을 한다고 보여지는 것은 없다. iOS개발을 하면서 다시 시작하게 되었고 그 이유는 다음과 같습니다. 개발실력은 개발 시간에 비례해 늘기 때문에 Todolist는 이미 쌓여있어서 꾸준히 개발해야한다. 의미없는 커밋이 없다고 가정할 때, 꾸준한 커밋은 상당한 성실함을 보여준다. 꼭 연속으로 하루도 빼놓지 않고 커밋을 해야한다는

ButCommit을 배포하고 나서

이미지
ButCommit을 배포하고 나서 ButCommit을 배포하고 나서 2번째 앱인 But Commit을 만들었습니다. 매일 매일 커밋을 할 수 있도록 도와주는 동기부여 앱 입니다. 당신의 커밋을 볼 수 있습니다.Publish to Blogger 개발자리 (개발자리)

[iOS] UITableVIew의 아웃라인

[iOS] UITableVIew의 아웃라인 UItableView를 처음에 공부할 때는, 어떻게 사용하는지, 화면에 테이블만 잘 그려지면 땡 이라는 생각으로 만들었습니다. 하지만 iOS의 개발의 절반 이상이라고 해도 과언아 아닐 정도로 많이 다루는 주제이기 때문에, 무었이 있는지 어떻게 공부를 해야하는지 정리 해 두고 깊게 공부하면서 남겨볼까 합니다. 내용은 전부 Apple Developer Documentation 에 있는 내용이기 때문에, 더 정확한 내용을 원하시는 분들에게는 원문을 읽어 보시는 것을 추천 드립니다. 첫 번째 글이지만 문서의 순서와는 상관없습니다. 실제 문서에서는 사용자 인터페이스의 하위 항목 > 뷰와 컨트롤 > 컨테이너뷰 > 컬렉션 뷰와 테이블 뷰 중 테이블 뷰의 순서대로 설명합니다. 테이블 뷰 요약 테이블 뷰는 컬럼들을 수직의 방향으로 보여주고, 스크롤 해서 볼 수 있도록 제공해 주며, 셀과 섹션으로 이루어져있습니다. 셀 은 한 줄의 구성요소이고, 이런 셀들을 특정 기준으로 묶은 것이 섹션 입니다. 테이블 뷰는 셀들을 직접 만들 수 있으며, 조립해서 사용할 수 있습니다. 테이블 뷰를 사용할 때는 데이터가 층계구조로 잘 구분될 때 입니다. 그리고 테이블 뷰 컨트롤러를 이용해서 다룰 수 있습니다. 보통은 UITableViewDelegate와 UITableViewDataSource 이 두 프로토콜을 채택해서 프로그래밍을 하게 되는데요, UITableViewDelegate에는 테이블뷰의 행동과 관련된 내용이, UITableViewDataSource에는 테이블 뷰의 형태와 데이터에 관련된 내용들이 정의 되어있으니 꼭 한번 메소드 이름이라도 다 읽어보시기 바랍니다. 테이블 뷰의 필수요소 테이블 뷰를 생성하는 방법에는 2가지 방법이 있습니다. init(frame: CGRect, style: UITableView.Style) 를 써서 코드로 생설할 때 불리는 초기화 함수와 init?(co

[iOS] UIView의 생성자

[iOS] UIView의 생성자 내가 원하는 커스텀 뷰를 만들다보면, UIView와 같은 기존의 뷰를 상속받아서 테두리나 투명도를 조절하는 등의 커스터마이징을 할 수 있습니다. 하지만 항상 개발하면서, 생성자가 헷갈려서 정리 해 놓도록 하겠습니다. 필수 생성자 init(frame: CGRect) 코드로 뷰를 만들면 호출됩니다. CGRect 타입으로 만들어 주어야 합니다. 코드 상에서는 let avatarImageView = GFAvatarImageView(frame: .zero) 이렇게 선언 합니다. 스토리 보드가 없을 때 사용합니다. init(coder: NSCoder) 스토리 보드에서 나오면서 UIView를 만들 때 사용되는 생성자 입니다. 스토리 보드에 그려놓으면 이 생성자가 호출됩니다. 코드 상에서는 @IBOutlet weak var appIconImageView: SoftBorderImageView! 이렇게 선언해줍니다. 스토리 보드에 연결 되어있을 때 사용합니다. awakeFromNib TableViewCell을 xib으로 만들 때 override func awakeFromNib() 이 생기는데요, 이 awakeFromNib은 인스턴스 화 된 후 호출 됩니다. 즉 init(coder: NSCoder) -> awakeFromNib() 이 호출됩니다. 헷갈리는 부분을 여러번 실행하고 애플 문서를 찾아 정리 해 보았는데요, 혹시 틀린 부분있으면 망설임없이 지적 부탁드립니다!

[swift] 오류 처리

[swift] 오류 처리 오류처리 프로그래밍을 하다보면, 모든 예외처리를 해 줄 수 없기 때문에, 미리 예상이 되는 오류들을 정의 해 놓고 발생되면 개발자에게 알려주는 방법으로 위기를 줄이는 방법이 있습니다. 디버깅을 하면서 어디서 부터 문제가 시작되는지 알려주는 게 있었으면 좋겠다라고 생각했는데, 오류 처리를 해 놓으면 문제 추적에 실마리가 될 것입니다. 한 번도 직접 해보지 못했던 오류 처리를 정리해 보도록 하겠습니다. 오류를 정의하기 오류를 정의하는 방법은 아주 간단합니다. enum으로 오류의 케이스들을 정의 해 놓고 Error프로토콜을 채택 해 주면 됩니다. 날짜(YYYY-MM-DD)를 파싱하는 메소드에서 발생할 수 있는 에러에 대해 정의 해 보겠습니다. 입력받은 값이 날짜 형식보다 길다 입력받은 값이 날짜 형식보다 짧다 숫자가 아닌 형식이다 입력값의 범위가 날짜의 값보다 크거나 같다(13월 32일) enum DatePareseError: Error { case overSizeString case underSizeString case incorrectFormat(part: String) case incorrectDate(part: String) } 오류 던져주기 오류는 던져줍니다. 이게 무슨 뜻이나면 func pareDate(:NSString) -> Date 날짜를 파싱하는 메소드가 있을 때 오류가 발생되면, 에러를 반환? 해야합니다. 하지만 우리는 이미 정상동작일 때 문자열을 반환한다고 정의 해 놓았으니 에러는 반환되는 것이 아니라 던져줘야 합니다. 그러면 어떻게 던질 수 있을까요? 바로 반환값 앞에다가 throw 를 써줍니다. func pareDate(:String) throws -> String func parseDate(param: NSString) throws -> Date { guard param.length == 10 el

[Xcode] LLDB의 기능 활용해서 디버깅 하기

[Xcode] LLDB의 기능 활용해서 디버깅 하기 디버깅을 하면서 데이터를 출력하는 방법에는 크게 3가지가 있습니다. po, p, fr v 이들은 각각의 특성을 가지고 있습니다. po는 debugDescription의 포맷팅으로 출력해줍니다. p는 빌트인 포맷터를 사용합니다. fr v는 빌트인 포맷터를 쓰지만 사이드 이펙트를 만들지 않습니다. 하지만 제한된 조건에서만 출력할 수 있습니다. 빌트인 포맷터는 우리가 디버깅을 할 때 볼 수 있는 왼쪽의 구조와 같습니다. fr v가 안전하면서 사이드 이펙트를 발생시키지 않는 이유는, p와 po는 실행문 입니다. 그러므로 출력 이외에 코드를 실행할 수 있습니다. 그러므로 우리가 생각하지 못한 부분을 만들어 낼 수 있지만, fr v는 출력만 해 줍니다. 디버깅 변수 활용 특정 상황에서 브레이트 포인트를 걸고 싶을 때가 있습니다. 예를 들면 테이블 뷰의 셀이 100개 이지만, 47번째 셀이 그려질 때가 그 예입니다. 이럴 때는 디버깅 변수를 하나 생성하여, 조건문에 그 값을 넣어 조건을 만족할 때만 브레이크 포인트에서 멈추게 할 수 있습니다. 변수를 만드는 방법은 간단합니다. viewDidLoad 메소드에서 디버깅 변수를 하나 선언해줍니다. 메소드 중간에 아무라인이나 우클릭 합니다. Edit Breakpoint -> Add Action 그리고 Debugger Command를 입력해줍니다. p var $row = 0 그리고 테이블뷰의 cellForRowAt 메소드에서, 브레이크 포인트를 만들어 준 후에, Edit Breakpoint -> Add Action 그리고 Debugger Command를 입력해줍니다. p $row = indexPath.row 라고 만들겠습니다. 이러면 인덱스 패스가 바뀔 때 마다 우리의 디버깅 변수도 값이 바뀌겠죠? 마지막으로 셀이 그려지는 메소드에 가서, 브레이크 포인트를 만들어주고 Edit Breakpoint -> Conditio

[Swift] Encoding과 Decoding

이미지
[Swift] Encoding과 Decoding iOS개발의 많은 부분들이 데이터를 요청해서 받고, 또 보내는 것인데요. 할 때마다 헷갈려서 정리 해 놓으려고 합니다. Data 만약에 아래와 같은 json 데이터를 서버로 보내야 한다고 생각해봅시다. { "name" : "Leeo", "age" : 29, "pet" : { "name" : "coco", "type" : "dog" } } 어떻게 보낼 수 있을까요? 물론 문자열로도 만들 수 있지만, 그러면 같은 모양의 여러 데이터를 여러개 만들 때 비용이 너무 크게 들테니 모델을 만들어서 같은 데이터를 찍어내는게 좋겠습니다. 가장 바깥의 단계 부터 차례대로 구조를 보고 모델을 만들면, 객체를 만들 수 있을 것 같습니다. 아래와 같이 코딩을 하면 변환이 가능해 보입니다! import Foundation struct Person: Codable { var name: String var age: Int var pet: Animal } struct Animal: Codable { var name: String var type: String } Codable은 Decodable 과 Encodable을 동시에 채택한 프로토콜입니다. 그러면 Encodable은 뭐고 Decodable은 무엇일까요? Encodable 이 프로토콜을 채택하면, 이 구조체는 json데이터로 인코딩 될 수 있음을 보장합니다. Person만 Encodable을 채택하고, Animal은 Encodable을 채택하지 않으면, Person은 json으로 온전히 변환된다는 보장이 없으니, 모두 채택 해 주어야 합니다. 그럼 이제, 우리의 데이터를 json으로 만들어 봅시다. 순서는 다음과 같습