목록분류 전체보기 (50)
Stacking Fire
회사에서 새롭게 만드는 프로젝트의 중요 기능에 유닛 테스트를 적용하기 위해 방법을 정리해 보았다. 방법 테스트 타겟을 만들어 특정 함수가 기대하는 결과를 내는지를 검증. 순서 : 유닛 테스트 타겟 추가 → 테스트용 인스턴스 생성 → 결과 확인을 XCTest 함수에 연결 → ⌘ + U로 실행 테스트용 인스턴스 테스트용 인스턴스는 setUp()에서 만들고 tearDown()에서 풀어준다. setUp() 에서는 super.setUp()아래에 인스턴스를 만든다. tearDown()에서는 super.tearDown() 위에서 nil을 할당해 준다. var instanceForTesting: ClassForTesting! override func setUp() { super.setUp() instanceForTes..
Monad [|mɑ:nӕd;|moʊn-](철학)모나드(무엇으로도 나눌 수 없는 궁극적인 실체)Oxford Advanced Learner's English-Korean Dictionary ...왜 이 개념이 이렇게 쓰였는지는 아직 모르겠습니다. 더 공부해 보겠습니다. 컨텍스트 맥락. 어떤 위치에 어떤 값이 존재할 수 있는 맥락. 옵셔널은 맥락은 존재하지만 값이 필연적으로 존재하지는 않을 수도 있는 부분에 들어감. 값과 컨텍스트는 다르다. 그래서 옵셔널은 값을 대신할 수 없다! func add3(to int: Int) -> Int { return int + 3 } add3(to: Optional(2)) // 오류! // 값이 들어가야 하는 곳에 컨텍스트만이 들어갔다. 함수객체 함수객체란 맵을 적용할 수 있는..
map, filter, reduce는 객체에 데이터를 보내서 받는 전통적인 형태의 함수가 아닙니다. 클로저로 다른 함수를 받아 데이터셋을 변형시키는 고차 함수입니다. 옵저빙 프로퍼티와 함께 함수형 프로그래밍 '스러운' 기능을 지원하는 것입니다. 아래는 단순히 사용법이지만, 체인처럼 걸어서 사용할 수 있습니다. 맵 for-in처럼 각 요소에 특정한 행동을 수행해준 후에 그 각각 처리된 요소를 이용한 컬렉션을 만들어줍니다. 반환하지 않는 클로저를 전달하면 그냥 반복문으로 사용 가능. //긴 버전 var doubled: [Int] = numbers.map { (i: Int) -> Int in return i * 2 } print(doubled) //짧은 버전 var dbld: [Int] = numbers.ma..
옵셔널 체이닝 윗물이 맑으면 아랫물은 괜찮을 수도 있다. 체이닝의 끝은 늘 Optional! 바인딩과 함께 써 보도록 하자. 백견이 불여일RUN //옵셔널인 놈에게만 궁금증을 가진다! ash?.bag.badgeCase?.append(grayBadge) //바인딩과 함께 바인딩! if let firstBadge = ash?.bag.badgeCase?[0] { print(firstBadge) } 빠른 종료 guard let 한 코드 블럭에서 여러 개의 옵셔널을 다루어야 할 때가 있다. 쓸 때마다 언 함수, 메서드, 반복문 등 특정 블록 내에서만 사용이 가능. 반환값이 있는 함수 내에서 사용할 경우 반환값을 요구하기도 한다. func greet(person: [String: String]) { guard le..
이제 구직 활동을 시작한 지 2주 정도 지났다. 누군가에게 나를 언어로 표현하는 일은 역시, 고되다. 그 중에서도 '아는 것'에 대해 많은 생각을 하게 된다. 긴 기간은 아니지만 간단히 정리해 보려고 한다. 아는 것을 안다고 하는 것 논어에 이런 구절이 있다. 知之爲知之 不知爲不知 是知也 아는 것을 안다고 하고, 모르는 것을 모른다 하는 것. 그것이 정말 아는 것이다. 아주 간단한 이야기지만, 생각만큼 쉽지가 않다. 모르는 게 뭔지 모르기 때문이다. 얼마만큼 알아야 정말 다 아는 건지 모르니까. 면접을 보러 다니면서 새삼 정말 어려운 일이라는 것을 느끼고 있다. 내가 나름대로 안다고 생각해서 안다고 이야기하면 더 잘 아는 사람 눈에는 모르는 게 보일 것이고, 그렇다고 무턱대고 모른다거나 노력하겠다고만 하..
결국 프로그래밍이라는 것은, 적절한 타이밍에 적절한 행동을 적절한 대상에게 시키는 일입니다. 그리고 iOS 앱이란 App 과 view로 이루어져 있기에, 그 각각의 생명 주기를 아는 것은 어떤 일을 어떻게 시키는지 아는 것만큼이나 중요합니다.아래는 간단히 2개의 뷰로 이루어진 테스트용 앱에서 각 라이프사이클 메서드에 로그를 찍은 결과입니다. awakeFromNib - 첫번째 뷰가 Nib에서 깨어났습니다. didFinishLaunchingWithOptions 앱이 옵션과 함께 런치되었습니다. --------------------------------------------------------------------- loadView - 첫 번째 뷰가 로드됩니다. viewDidLoad - 첫번째 뷰가 로드되었..
Objective-C의 블록 같은 녀석입니다....만 좀더 빈번히, 또 쉽게 사용됩니다. 함수형 언어에서 함수를 담당하고 있는 클로저!! 처음에 그 표현법 때문에 좀 당황을 먹었는데요, 스위프트를 겪으면서 쓰다 보니 점점 괜찮아져서, 이제는 클로저로 처리 가능한 것은 왠만하면 클로저로 처리하게 됐네요. 표현법 통상적으로는 아래와 같음. {(parameters) -> ReturnType implementation return returnValue //있을 경우만! } 예전의 코드. 생략의 HELL //아래 names 어레이를 역순으로 정렬하는 코드들. let names:[String] = ["wizplan", "eric", "yagom", "jenny"] //풀버전. first와 second를 가지고 어느..
Objective-C에서는 은닉화가 아예 파일 구조로 분리가 되어 있었고, 필요할 때 필요한 파일만을 연결해서 사용했습니다. 그런데 Swift에서는 파일 구분이 사라졌고 게다가 한 프로젝트 전체가 하나의 네임스페이스가 됩니다. 이에 따라, Swift 은닉화는 의미에 따라 자연스럽게 되는 것이 아니라 일부러 해주어야 하는 구조가 된 겁니다. 접근 제어는 사실 문법이 너무 쉬운지라 그냥 그런가보다 하고 지나가지만, 제대로 판단해서 넣어주지 않으면 Objective-C보다 더 정리가 안 된 코드가 되고 맙니다. 접근 수준 open : class에서만 사용됨. 모듈 밖에서도 상속이 가능... 즉 상속이 가능한 클래스에서만. public : 모듈 외부에서 접근이 가능. 상속은 불가능! intrenal : 모듈 내..
패스트캠퍼스에서 딜리게이트에 관련된 수업을 진행하던 도중, 텍스트필드의 글자수를 제한하는 것에 관련된 예제를 진행한 적이 있었습니다. 최초에 나온 답변에 대해서 다시 버그를 찾아내고, 그 버그를 픽스하고 하면서 Delegate에 대해서 알아볼 수 있는 굉장히 유익한 시간이었는데요. 해결하고자 하는 요건은 아래와 같았습니다. 입력되는 글자수가 10자를 넘지 않을 것. 입력시 커서가 텍스트 내에 어디에 있든 상관없이 작동할 것. 복사해온 스트링을 넣어도 알아서 거부할 것. 삭제도 문제없이 될 것. 단순히 잘 해결했다는 느낌을 떠나서, 딜리게이트의 구조를 정확히 알고 또 구현하고자 하는 상황의 의미를 그대로 코드로 자아낸 예제라서 기억에 많이 남습니다. 당시 배운 것들을 정리합니다. 풀이와 설명 결론부터 말하..
들어가면서 모바일에서 정보를 입력 받는 뷰의 경우... 안 그래도 좁은 화면에 키보드까지 덮여 있기 때문에 사용자가 불편함을 느껴 키보드를 내리려고 할 때가 많습니다. 키보드에 액세서리 뷰를 추가하는 방법도 있긴 하지만 잠깐 화면을 볼 때마다 뭔가 결정하는 듯한 뉘앙스를 주는 거 같아서, 그냥 화면 내에 인터랙션이 없는 곳을 탭해서 내리고 싶을 때가 있죠. 그럴 때 쉽게 적용할 수 있는 방식을 소개합니다! 1. UIViewController의 extension 만들기 extension UIViewController { func endEditingModeWhenUserTapOutside() { let tap = UITapGestureRecognizer(target: self, action: #selecto..