기초 문법 .h 헤더 파일과 .m 구현 파일 2개가 존재한다. 헤더 파일에는 클래스나 변수, 메서드를 선언해 주고 .m 파일에서 자세한 구현 사항을 기술한다. 한 문장이 끝날 때마다 세미콜론을 사용해야 한다. #import #import "headerSomethingHeader.h" #import 외부 라이브러리, 프레임워크, 프로젝트 내에 있지만 다른 파일에 선언된 클래스를 사용할 때 import해 준다. 구현 파일에서도 자신의 헤더 파일을 반드시 import 해야 하며, .h 파일에서 import 한 내용은 .m 에서 import할 필요가 없다. 각각 파일별로 관리된다고 보면 되며, C언어와 비슷하게 사용할 클래스가 있다면 import하여 사용한다. 클래스 선언 @interface Person : N..
iOS에서 앱을 실행하면? UIKit은 Objective-C 기반으로 되어 있기 때문에 내부에서 main 함수를 기반으로 돌아간다. 이 main 함수가 돌아가면서 `UIApplication`이 실행되고, 이 `UIApplication`은 singleton 형태로 생성되어 앱 전역에서 사용할 수 있다. 이후, 아래 사진의 Main Run Loop가 실행된다. 이 Main Run Loop가 돌아가면서 View에서 사람들의 event를 받고 update한다. 당연히! main Run Loop는 UI 관련 동작을 하기 때문에 Main Thread에서 동작한당. 앱의 생명 주기를 관리하기 개요 앱의 현재 상태란 앱이 언제든지 수행할 수 있는 작업과 수행할 수 없는 작업을 결정한다. 예를 들어, 포그라운드 앱은 사..
기존의 방법으로 Widget에 Background를 적용하려고 하면, 제대로 적용되지 않고 이상한 padding이 적용되어 있다. 이런 식으로! 너무 이상해 보여서 여러 방법을 찾아보다가 괜찮은 글을 발견해서~~! 블로그에도 기록해놓으려고 한다. 찾아보니 Xcode15 / iOS 17부터는 Widget에 contentMargin이 기본으로 적용되어 있어 이를 해제해 주는 것이 필요하다. 그 방법으로는. .. . struct CoinWidgets: Widget { let kind: String = "CoinWidgets" // 위젯의 고유한 문자열 var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: Configura..
Enum 먼저 Enum을 사용할 때 연관값과 CaseIterable을 왜 사용하는지를 이야기하기 위해서는 Enum이 몬지 알아야겠쬬. Enum, 열거형은 서로 연관된 값들의 집합입니다. 열거형은 컴파일 최적화가 되어 있어 컴파일 타임에 어떤 요소가 해당 열거형에 속하는지가 미리 정해집니다. 열거형에는 연관값 말고도 원시값이라는 RawValue를 사용하는데, 이 원시값을 통해서 해당 열거형을 더욱 폭넓게 사용할 수 있습니다. 원시값은 해당 열거형 케이스의 별칭이라고 불러도 좋을 것입니다. 예를 들어 봅시다. enum 음식점: String { case 파스타 = "pasta" case 김밥 = "gimbap" } 이런 식으로 사용할 수 있겠군뇨! 만약에 원시값을 사용하겠다고 선언하고 위처럼 따로 지정해 주지..
정답! UIViewController이다. 모든 뷰 컨트롤러는 UIViewController를 상속받고 있는데, UIViewController가 하는 역할은 무엇일까? 하고 생각해 보면다면 일단 생각나는 건 아래와 같당. 속한 객체의 크기 및 레이아웃을 잡음 (UI를 구성) 사용자의 response를 받아서 처리함 ... ... 또 뭐가 있을까? UIViewController가 하는 역할을 명확히 알려면, UIViewController가 상속받고 있는 객체들이 무엇인지 알면 더 좋을 것 같다는 생각에 조금 더 파헤쳐 보게 되었다. UIViewController 뜯어보기 먼저, UIViewController가 상속받고 있는 class들은 다음과 같당. 차례대로, UIResponder NSCoding UIA..
Share 기능 구현하기 전체적인 로직은 다음과 같다. 간단하다! 초반 구현 func share(activeVC: UIActivityViewController) { activeVC.popoverPresentationController?.sourceView = self.view self.present(activeVC, animated: true) } 요런 식으로 작성했다. 다만, 내가 원하는 거랑 많이 달랐다 ,, ,, ㅠ,ㅠ 짱나. 왜 내가 원하는 것과 다르게 나오는 걸까? 정답은 ActivityViewController를 구성하는 방법에 있다. 처음 코드에서는 String 배열로 ActivityuViewController에 들어가는 내용을 구성해 주었기 때문에 원하는 형식으로 들어가지 않는 것이다! 고..
오른쪽과 왼쪽은 단 한 줄 차이이다. 바로~~~~~~ imageView.clipToBounds...... 이걸 못 찾아서 이틀 동안 몇 시간을 헤맨 건지 ,, ^___^ 도와주신 섭님과 훈님과 코님께 무한 감사를 전한다........... 나는 기본이 true일 줄 알고 있었는데 대체 왜 그랫을까? 진작 해볼걸........................................ clipToBounds는 위 설명과 같이 true일 경우에는 속한 뷰와 그 하위 뷰를 깎아주고 아닐 경우에는 그대로 내비둔다. 나는 ...... clipToBounds보다는 Layout 문제라고 생각해서 이게 왜 안 잡혀~~~!!!!! 하고 레이아웃쪽과 이미지 들어가는 부분을 확인하고 파고 바꾸고 했는데 그냥... 전혀 상관 ..
UI Test와 Unit Test UI Test 화면에 보이는 객체가 잘 눌리는지, 화면 전환은 잘 되는지 확인할 수 있다. 또한, 접근성 관련 설정이 잘 동작하는지 테스트할 수 있다. Unit Test 비즈니스 모델에 문제가 없는지, 로직에 대한 테스트를 하는 것! 이 안에서 UI적인 이름을 많이 가지고 있을 경우에는 추후 UI 객체를 수정하게 될 때, 테스트 코드까지 수정해야 할 수 있다. 따라서, 로직만 테스트 할 수 있는 형태로 구성하는 것이 좋다! CLEAN CODE에서 나온 원칙으로, FIRST 원칙이 있는데... ... Fast: 빨리 테스트를 할 수 있게끔 만들어야 한다. Independent: 각각의 테스트가 독립적이어야 한다. (서로 영향을 받으면 안 됨) Repeat: 반복적으로 같은..