[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으로 만들어 봅시다. 순서는 다음과 같습...

[swift] swift 기본 문법 스터디 8주차

[swift] swift 기본 문법 스터디 8주차 상속 서브클래싱 상속 받아 새로운 클래스를 만드는 것 상속 받은 클래스의 프로퍼티와 메소드는 다 가진채로 추가 구현을 해줌 상속은 1개만 가능, 나머지는 프로토콜 중복의 문제 오버라이딩 덮어쓰기 상속받은 메소드와 프로퍼티를 재정의(덮어쓰기 가능) 메소드는 인자와 반환타입까지 일치 프로퍼티는 연산형으로 get, set 구현 타입 캐스팅 상속을 받으면 타입이 달라지는데, 이를위해 타입을 변환할 수 있다. 타입 비교 연산 is로 비교하고, 같은 타입이거나, 상위 타입이면 true를 반환 그 외에는 모두 false를 반환 타입 캐스팅 연산 as 를 이용해서 캐스팅 다운 캐스팅과 업캐스팅 가능 업 캐스팅은 보통 문제없음 (as) 다운 캐스팅은 문제가 생길 수 있음 (as?, as!) Any, AnyObject 모든 클래스와, 타입의 부모 어떤 캐스팅도 가능하다 제공 메소드, 프로퍼티가 없음 초기화 구문 init 초기화 메소드 init 이라는 이름의 메소드는 초기화에 사용됨 인스턴스를 생성할 때는 이름을 호출하지 않아도 가능 인스턴스 생성시 간접 호출 여러개의 초기화 구문작성 가능 (오버로딩 지원) 초기화 구문의 오버라이딩 상속받아 초기화를 하면 부모의 프로퍼티가 초기화가 되지 않음 super.init()으로 초기화 가능

iOS 개발자가 되어버린 데이터 분석가의 2020년 회고

이미지
iOS 개발자가 되어버린 데이터 분석가의 2020년 개인적으로 많은 변화들과 도전들이 있었던 한 해 였습니다. 많은 시행착오를 통해 나가아갸 할 방향을 정하는데 있었던 일들을 정리 해 두도록 하겠습니다. 저와 같은 커리어를 고민하시는 분들에게 도움이 되었으면 좋겠고, 또한 무지한 저를 깨우쳐 주시거나 가르쳐 주실 댓글도 환영입니다 ㅎ _ㅎ. 커리어 전환 첫 회사에서 데이터분석가로 일을한지 3년차가 되면서, 많은 한계를 느꼈습니다. 더 이상 흥미가 느껴지지 않기도 하고, 한 가지 이유보다는 여러가지 복합적인 이유와 iOS개발자로 커리어 전환할 수 있는 계기가 생겨서 도전하게 되었습니다. 물론 여태까지 쌓았던 커리어를 포기하는 것은 아깝지만 스스로 이 일을 하고 싶지 않다 라는 결론에 도달하며 미련없이 전환 했습니다. 아무 기반지식이 없었고, 오히려 개발자로서 역량이 부족했기에 좀 더 두려워 하면서 전환했으면 좋았을 텐데라는 아쉬움이 남았습니다. 예를 들면 기본적인 협업도구의 사용방법, 배포 전략에 대한 이해, 업무 분담의 방법, 테스트 및 QA 진행방법에 대한 지식이 부족한 상태에서의 커리어 전환은 너무나 큰 리스크 였지만 그 당시에는 알지 못했기에 하마터면 어쩔 뻔 했나 라는 생각에 지금도 등골이 서늘합니다. 관련 링크 개발자로 랜딩하기 가장 먼제 apple 생태계를 이해하는 것 부터 난관이었습니다. 인증서관리, 개발도구, 라이브러리 관리 등, 생각지 못한 부분들을 공부하는 것에도 시간을 많이 쏟았습니다. 가장 중요한 기초체력인 개발 언어를 한 번은 빠르게 다 공부하고 계속 이해하도록 시간을 쏟았어야 하는데 그러지 못하고 SDK 및 API에 너무 많은 시간을 할애 한 부분이 아쉬웠습니다. 지금이라도 한 언어를 깊게파 기초 체력을 다지는 중 입니다. 그 다음은 많이 만들어 보는 것 이었습니다. 개발자가 된다는 것은 말 그대로 개발을 하는 것 이었습니다. 많은 앱들을 보고 어떻게 구현했을까 고민하고 전체가 ...

[swift] swift 기본 문법 스터디 7주차

이미지
[swift] swift 기본 문법 스터디 7주차 일급 객체로서의 함수 특성 런타임에서 생성가능 인자값으로 객체 전달가능 반환값으로 객체를 사용할 수 있어야 함 변수, 데이터 구조 안에 저장 고유한 구별이 가능 변수나 상수에 함수를 대입할 수 있음 함수의 결과값을 변수나, 상수에 대입하는 것이 아는 그 자체를 변수나 상수에 대입할 수 있습니다. func printAddFive(base: Int) -> String { return "결과 값은 \(base)입니다." } let fnc1 = printAddFive(base: 4) // 결과 값은 9입니다. 위의 예제는 함수를 선언하고, 그 함수의 결과값을 변수에 저장하는 예제 입니다. let fnc2 = printAddFive fun2(5) // 결과 값은 10입니다. 이렇게 함수 자체를 대입하고, 인자를 넣어서 호출 할 수 있습니다. 하지만 왜 _ 이렇게 라벨을 없애지 않았는데 없어진 걸까요? 변수를 대입하는데에 타입이 필요하고, 같은 타입에 연산이 가능 하듯이 함수도 마찬가지 입니다. 함수도 함수 타입이 있습니다. (인자타입1, 인자타입2) -> 반환타입 우리가 위에서 만든 printAddFive 함수의 타입을 적어보면, (Int) -> String 이 되겠군요. 함수의 반환타입으로 함수를 사용할 수 있음 함수의 반환에는 자료형이나, 클래스, 구조체 뿐만 아니라 함수도 반환할 수 있습니다. 그러면 어떻게 생겼을까요? func desc() -> String { return "desc 함수입니다." } func pass() -> () -> String { return desc } let p = pass() p() // desc 함수입니다. 위의 예제 코드를 보면, pass 함수는, () -> String 이라는 함수를 반환 합니다. 그리고 그...

[Xcode] Breakpoint를 이용한 디버깅 툴 응용

이미지
[Xcode] Breakpoint를 이용한 디버깅 툴 응용 문제를 해결하기 위해서는 디버깅을 해야하는데, 좋은 디버깅 도구가 있음에도 프린트 문을 쓰거나 po 명령어만 쓰고 있는 자신을 발견하여, 좀 더 좋은 도구의 사용법을 익히고자 정리 해 둡니다. signal SIGABRT break point 프로그래밍을 하다 보면, 어디서 왜 죽었는지도 알기 전에 Thread 1: signal SIGABRT 빨간 라벨이 나와서 매우 분노한 일이 많았습니다. 이럴 때 어디서 죽는 건지 브레이크 포인트도 걸 수 없는데 어떻게 해야할까요? 브레이크 포인터 네비게이터로 간 후, 왼쪽 하단에 Exception Breakpoint를 누른 후 아무 곳이나 클릭 한 후 다시 실행 시켜 줍니다. 이번에는 Exception이 발생한 지점에서 멈춰있는 것을 알 수 있습니다. 브레이크 포인트를 걸지도 않았는데 말이죠. 그 다음은 브레이크 포인트가 걸려있는 지점을 살펴 보아야겠죠? 브레이크 포인트로 로그 남기기 원하는 곳에 브레이크 포인트를 걸고 값을 출력 해 본 적있으신가요? 예를 들면, 스크롤뷰에서 화면내 이미지의 마지막 순간 값을 출력 해 보려고 했던 경험 저는 많은데요. 스크롤 할 때마다 계속 브레이크 포인트에서 걸려 매우 난감했던 순간이었습니다. 이럴 때는 원하는 곳에 브레이크 포인트르 지정하고, 브레이크 포인트를 우클릭 합니다. edit breakpoint 를 누르면 이름과 조건을 설정할 수 있습니다. 하지만 우리가 필요한 기능은 Action이 Debbuger Command 입력란에 우리가 항상 브레이크 포인트가 걸리면, 입력해주는 lldb 명령어를 입력해줍니다. 예를 들면, po self.contentsOffset 과 같이 말입니다. 그리고 Automatically continue…를 체크 해주면, 이제 멈추지 않고 커맨드창에 출력됩니다. 더 나아가서, Action에 값을 Debbuger Command이 아닌 Log M...