iOS
[iOS] 동시에 여러 Gesture 인식하기(feat.GestureRecognizer)
애플의 공식문서 - Preferring one gesture over another를 참고하였습니다.동시에 두 개의 Gesture Recognizer를 달고 있을 경우, 어떻게 핸들링을 하면 될까?답: Gesture Recognizer Delegate Object를 활용하여 뷰에서 어떤 gesture를 먼저 인식할 지를 설정해줄 수 있다.두 개의 예시를 통해서 한번 확인해보자. 예시 1만약 내가 탭 이벤트와 더블 탭 이벤트를 받아야된다면?gestureRecognizer(_:shouldRequireFailureOf:)두 제스처 인식기 사이에 "실패 요구사항"을 설정할지 결정한다.Default 값은 false이다.true일 경우GestureRecongnizer와 OtherGestureRecognizer 사이..
[iOS] 특정영역만으로 QR 코드 스캔하기(feat. AVFoundation)
최근 프로젝트를 하면서, AVFoundation를 활용하여 QR code scanner를 구현한 경험이 있습니다. 공식문서를 통하여 해당 기능을 구현한 경험을 소개하고, 더 나아가 전체 Camera Preview 속 모든 input이 아니라, 특정 영역만을 포커싱하여 QR 코드를 인식하는 코드 또한 소개해보도록 하겠습니다. AVFoundation?시각과 청각과 관련된 에셋, 디바이스 카메라 제어, 오디오 처리 등을 구성할 수 있는 Framework시청각 자산으로 작업하고, 디바이스 카메라를 제어하고, 오디오를 처리하고, 시스템 오디오 상호 작용을 구성할 수 있다. (AVFoundation을 활용하기 전에 대충 해당 Framework가 카메라를 다룰 수 있다는 것은 알고 있었는데, 오디오도 처리하는지는 ..
[iOS] TabbarController의 presentingViewController(feat.currentContext)
UITabbarController위에 쌓여있는 ViewController들의 presentingViewController가 무엇인 지에대해서 알아보자. 문제 상황은 아래와 같았다. 먼저 현재 개발하고 있는 앱은 UITabbarController에 3개의 tab이 존재했고, 해당 tab들은 각각 UINavigationController로 구현이되어있다. 즉, UITabbarViewController → MypageViewController(UINavigationController) → … 여러 개의 ViewController가 stack 형식으로 들어가있다. 만약 MyPage에서 push를 통해서 올라간 맨 위 ViewController가 TicketRefundRequestViewController라고 가..
[iOS] JSONEncoding과 URLEncoding의 차이점(Alamofire/Moya)
최근 프로젝트에서 Moya 라이브러리를 활용하여 네트워크 로직을 구현하던 중, 제대로 공부를 하지 않고 활용하여 API 통신을 실패한 경험이 있다.(스웨거만 제대로 봤어도..) Moya에서 TargetType을 채택한 API를 구성할 떄, 아래와 같이 HTTP Task를 구성한다. var task: Task { switch self { case .login(let provider, let DTO): let params: [String: Any] switch provider { case .kakao: params = ["accessToken": DTO.accessToken] case .apple: params = ["idToken": DTO.accessToken] } return .requestParame..
[iOS] CollectionView Reordering (feat. WWDC 20)
Collection view를 활용하여, 아래와 같은 reordering을 구현하는 방법을 한번 알아보겠습니다!(with ListConfiguration) 먼저 reordering과 관련된 WWDC 20의 Advances in diffable data sources를 정리하고 구현해보도록 하겠습니다. Diffable datasource의 가장 큰 장점은 유니크한 item identifier를 통하여 Collection view의 데이터를 모델링할 수 있다는 것입니다. 이러한 유니크한 item identifier를 통하여, 프레임워크가 자체적으로 reordering된 변화점을 알아서 확인하지만, 이것만으로는 충분하지 않습니다. 우리의 앱은 유저가 발생시킨 reordering 작업을 알아차려야지, 새로운 r..
[iOS] Core Location Unit Test하기(feat. WWDC18)
WWDC18 Testing Tips & Tricks 속 4가지 주제 중, Mocking with Protocols 세션을 정리해보았습니다. 해당 세션은 Core Location 활용 시의 외부 의존성(CLLocationManager, CLLocationManageDelegate)을 끊어주어 실제 API 호출 없이 Core Location을 Test하는 코드를 설명하고 있습니다. 위와 같은 과정은 프로토콜 의존성 주입을 통해서 구현을 했는데, 세션의 내용을 따라가면서 어떻게 테스트를 진행하는 지 알아보겠습니다. (추가로 해당 세션을 기반으로 실제 프로젝트에도 적용해보겠습니다!) Mocking with Protocols Core Location을 구현할 때는 주로 위와 같이 CLLocationManager(..
[iOS] 공식문서로 보는 Core Location
공식문서를 보면서 CoreLocation에대해서 한번 알아보겠습니다. 또, 프로젝트에서 실제 사용해보죠! (참고한 공식문서 페이지는 맨 마지막에 참고로 올려두겠습니다 ☺️) Core Location이란? Core Location은 디바이스의 지정학적 위치, 고도, 방향 및 가까운 iBeacon 디바이스와 연관된 위치를 알려주는 서비스입니다. (iBeacon - 근거리 무선 통신 기술을 바탕으로 신호를 발산하는 소형 장치) Core Location 프레임워크는 Wi-Fi, 블루투스, 자력계, 기압계, 셀룰러 하드웨어 등 기기 내의 모든 요소들을 활용해서 데이터를 수집합니다. Core Location은 CLLocationManager 클래스를 활용하며, 아래와 같은 활동들을 제공합니다. 표준적이고 중요한 위..
[iOS] delegate는 항상 weak var로 선언해야 될까?
delegate는 항상 weak var로 선언해야 될까? 항상 습관적으로 delegate을 weak var로 선언을 하던 중, 항상 weak를 써줘야 할까라는 의문이 들었습니다. 아래의 예를 통해서 언제 써줘야 하는지 알아보겠습니다! 예시 프로젝트 왼쪽부터 firstVC, secondVC, thirdVC입니다. firstVC -> secondVC -> thirdVC로 갔다가, 다시 dismiss하면서 처음 firstVC로 가는 코드를 작성해 보겠습니다. label의 text를 바꾸는 등, 불필요한 코드가 있지만, 값 참조하는 부분만 확인해 주시면 됩니다! 함수, delegate, 프로퍼티 naming은 간략하게 했습니다! FirstViewController button을 누르면 SecondVC로 넘어가게..
[iOS] Diffabledatasource의 identifier는 왜 Hashable 해야 할까?
HTML 삽입 미리보기할 수 없는 소스 먼저 공식문서가 설명하는 diffabledatasource 사용의 이유를 알아보자 Updating Collection Views Using Diffable Data Sources Diffabledatasource can streamline the display and update of data in a collection view using a diffable data source that contains identifiers. ➡️ dffiable datasources는 자신이 가지고 있는 identifiers를 통하여 collection view의 data를 업데이트하고 매끄럽게 보여줄 수 있다. A diffable data source stores a list..
[iOS] FileManager
HTML 삽입 미리보기할 수 없는 소스 FileManager A convenient interface to the contents of the file system, and the primary means of interacting with it. ➡️ 파일 시스템의 내용에 대한 편리한 인터페이스 및 상호 작용의 주요 수단입니다. A file manager object lets you examine the contents of the file system and make changes to it. The FileManager class provides convenient access to a shared file manager object that is suitable for most types of f..
[iOS] NotificationCenter
HTML 삽입 미리보기할 수 없는 소스 NotificationCenter A notification dispatch mechanism that enables the broadcast of information to registered observers. ⇒ 등록된 Observer에게 정보를 BroadCast하는 것을 가능하게 하는 Notification Dispatch(보내기) 메커니즘이다. 세 가지의 관계 알림을 만들어내는 Publisher 알림을 전달하는 Dispatcher 역할의 NotificationCenter 알림을 관찰하는 Observer 기본 예제 코드 NotificationCenter을 하나 생성 → Notification.Name을 통하여 이름을 맞춘다. NotificationCenter..
[iOS] Gesture recognizer, Touch event handling
제스처를 구현하는 방법은 두 가지가 존재한다. Gesture Recognizer UIView's Touch Event Handling UIView's Touch Event Handling 터치 이벤트와 관련된 함수들이다. touchesBegan 터치가 일어날 때 불려지는 함수이다. touchesMoved 터치를 움직일 때마다 불려지는 함수이다. touchesEnded 터치가 끝날 때 불려지는 함수이다. touchesCancelled 위의 3가지의 이벤트가 발생도중에 갑자기 Alert이 발생한 경우 불려지는 함수이다. 아래의 예와 같이 viewcontroller 안에 아무곳에서 override를 하면된다. override func touchesMoved(_ touches: Set, with event: U..
[iOS] 의존성 관리 도구(Package Manager)
다양한 의존성관리 도구 CocoaPods Dynamic, Static 라이브러리를 모두 지원 대부분의 라이브러리가 지원한다. 여러 개의 pod들의 종속성을 확인하기가 쉽다. 종속된 pod들을 매번 build해야된다. → 시간이 많이 든다. Carthage Dynamic, Static 라이브러리를 모두 지원 프레임워크를 한번만 빌드하면 되므로, 빌드 속도가 매우 빠르다. 어떤 오픈소스를 쓰고있는 지 보기 편한다. 여러 개의 pod들의 종속성을 확인하기가 쉽다. 새로운 패키지를 가져다 쓸 때마다 프레임워크를 추가해 줘야하는 번거로움이 존재한다(추가할 때 시간이 많이 걸린다.) 설치하려면 Ruby gem 필요 (맥은 ruby가 내장되어 필요x) Swift Package Manager (SPM) Dynamic,..
[iOS] TableView에서 Swipe해서 Delete하기
UITableViewDelegate 를 통하여서 구현한다! deleteRows(at:with:) Deletes the rows that an array of index paths identifies, with an option to animate the deletion. 특정 indexPath에 cell을 tableview에서 제거해준다. func deleteRows( at indexPaths: [IndexPath], with animation: UITableView.RowAnimation ) tableView(_:editingStyleForRowAt:) Asks the delegate for the editing style of a row at a particular location in a table..
[iOS] sizeToFit()과 ToolBar
sizeToFit() Resizes and moves the receiver view so it just encloses its subviews. Call this method when you want to resize the current view so that it uses the most appropriate amount of space. Specific UIKit views resize themselves according to their own internal needs. 안에 있는 element(label의 경우, 글자의 intrinsic size)에 따라서 view의 사이즈가 알아서 조절되는 것! 😎 예시를 통해서 알아보자. 아래는 textfield의 extension을 통하여 keyboar..
[iOS] Target-Action Pattern
Target-Action Pattern 이벤트가 발생할 때 다른 객체에 메시지를 보내는 데 필요한 정보를 포함 액션 특정 이벤트가 발생했을 때 호출할 메서드를 의미 타겟 액션이 호출될 객체를 의미, 프레임워크 객체를 포함한 모든 객체가 될 수 있으나, 보통 컨트롤러가 담당한다! 만약 타켓이 nil이라면? Responde chain을 따라서 이벤트(action)을 처리하기에 적합한 리스폰더 객체를 찾아나선다! If you specify nil, UIKit searches the responder chain for an object that responds to the specified action message and delivers the message to that object. about. UIRes..
[iOS] UIResponder
UIResponder(feat.becomeFirstResponder) Textfield를 사용할 때 많이 쓰는 메소드인 becomeFirstResponder에대해서 공부를 하다가 UIResponder 에대해 더 깊게 공부해보자는 생각이 들었다. UIResponder란? UIResponder객체는 UIkit 앱 이벤트 처리 백본을 구성한다. 앱 이벤트 → ex) 화면 터치 UIApplication객체, UIViewController객체 및 모든 UIView객체(UIWindow포함) 모두 다 리스폰더 객체이다. 리스폰터는 UIKit이 제공하는 이벤트 정보를 사용하여서 터치 이벤트의 변경 사항을 추적하고, 앱의 인터페이스를 적절하게 업데이트한다. Responder Chain 리스폰더 객체들이 동적으로 구성된 ..
[iOS] CGPoint, CGSize, CGRect
CGPoint, CGSize, CGRect 기본적으로 view를 짜기위해서는 x,y 좌표가 필요하고, width, height가 필요하다. CGPoint View의 위치를 나타낼 때 사용한다 public struct CGPoint { public init() public init(x: Double, y: Double) public var x: Double public var y: Double } 활용 let point: CGPoint = .init(x: 10, y: 20) CGSize (width, height) 사이즈를 설정할 때 사용한다 public struct CGSize { public init() public init(width: Double, height: Double) public var w..
[iOS] TextField 왼쪽 여백 넣기
TextField 왼쪽 여백 textField의 leftView에 UIView를 넣어주면된다!(width를 추가하여서!) 아래의 예와 같이 padding을 넣어줄 수 있다. textField.leftView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 20.0, height: 0.0)) textField.leftView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 20.0, height: 0.0)) 그리고 leftView 는 4 가지의 leftViewMode가 존재한다. .always 항상 leftview 보여주기 .whileEditing 타이핑 중일 때 leftView를 보여주기 .unlessEditing 타이핑 중이 아닐 때 ..
[iOS] File System
File System 내가 어떻게 저장하고, 불러올 지 정하는 것 APFS는 mac OS, iOS, watchOS 및 tvOS의 기본 파일 시스템입니다 iOS 앱은 보안상의 이유로 파일 시스템의 sandbox directory에서 각각 관리됩니다. Sandbox directory 번들 컨테이너 실행가능한 파일, info.plist, 각종 Resources(이미지, 사운드, strings등)등을 할때 그룹화 데이터 컨테이너 Document(사용자가 직접 접근) Library(사용자가 직접 접근하지 못함) Temp iCloud 컨테이너 1) 데이터 컨테이너 - Document 설정에 따라 유저가 직접 파일 추가 및 삭제 가능> 따라서 유저에 의해 삭제되거나 내용이 변경되어도 무방하고 유저가 다루는 컨텐츠와 ..
[iOS] MVC
SW architecture 와 SW design pattern의 개념 차이 , 왜 필요할까? SW architecture란? 수많은 기능 하나하나의 부품들을 어떻게 연결시켜 관계를 맺었는지를 결정하는 것 이러한 모듈들을 어떻게 분할하고 배치할 것인가? 및 구성관계 설정 작은 기능 → 모듈 모듈을 기능별로 묶어놓은 집합 → 컴포넌트 전체 → 라이브러리 SW architecture의 기본원리 모듈화 ⇒ 소프트웨어 성능 향상 및 유지관리 등이 용이하도록 시스템의 기능을 모듈단위로 나누는 것 추상화 ⇒ 전체적이고 포괄적인 개념을 설계한 후에 구체화시켜 나가는 것 단계적 분해 ⇒ 상위 개념부터 하위 개념으로 구체화 시키는 분할 기법 하향식 설계 전략 정보은닉 ⇒ 모듈 내부에 정보와 자료들을 숨겨서 다른 모듈이 ..
[iOS] Singleton(싱글톤)
싱글톤이란? Design Pattern 중 하나이다. 타입 프로퍼티로 선언이 되어있으므로, lazy 하게 initialize가 된다. 특정 용도로 객체를 하나만 생성하여, 공용으로 사용하고 싶을 때 사용하는 디자인 유형 하나의 instance에 어느 클래스에서든 접근 가능하게 하는 것! “이 클래스에 대한 Instance는 최초 생성될 때 딱 한번만 생성해서 전역에 두고, 그 이후로는 이 Instance만 접근 가능하게 하자”할 때 사용이된다. 싱글톤을 언제 사용하면 좋을까? class UserInfo { var id: String? var password: String? var name: String? } 위의 코드와 같이 UserInfo를 담는 class를 만든다고 생각해보자. 근데 각 3개의 vie..
[iOS] 메모리 구조/ARC(Automatic Reference Count)
메모리 구조 Stack 영역 값 타입이 할당된다 함수 호출 시, 지역변수, 매개변수, 반환 값, 파라미터 값 등이 저장된다. 함수 호출이 완료되면 사라진다. -> 메모리를 직접 해제해주지 않아도 된다! 컴파일 시 크기가 결정된다. 메모리가 한정되어있다. 함수도 들어간다. Heap 영역 대체로 참조 타입값(클래스 인스턴스, 클로저)이 할당되지만, 값 타입도 할당될 때가 많다. class안에 struct가 있으면 struct도 class라는 컨테이너 안에 넣어져서 같이 Heap에 할당된다. 유일하게 런타임 시 크기 결정된다. 사용하고 난 후에는 반드시 메모리 해제를 해줘야한다.(memory leak 위험성) -> Swift에서는 ARC가 직접 해준다. 프로그래머가 할당 및 해제를 해줘야된다.(동적 할당) 할..
[iOS] 의존성 주입
의존성 주입(Dependency Injection) 특정 객체가 필요로하는 것들을 내부적으로 생성하게 두지 않고, 외부에서 제공해주는 것. 인스턴스 생성의 책임을 객체가 스스로 하도록 하지 않고 initializer, peroperty, method parameter의 형태로 “넘겨주는 것” 🤨 왜? 의존성이 높을 경우, 아래와 같은 문제가 있다. 클래스간의 결합도가 높아진다. 자연스럽게 테스트 성도 낮아진다. 코드 재사용성이 낮아진다. 의존성 주입을 해주면 아래와 같은 이점이 생긴다. 객체가 의존성을 받는 시점을 컴파일 타임이 아닌, 런타임으로 늦출 수 있다. 클래스가 생성이 된 후에도 프로퍼티 값등을 변경할 수 있다. 가장 쉬운 의존성 주입 예를 봐보자, 아래와 같이 ViewController 클래스..
[iOS] Delegate Pattern
Delegate Pattern 두 개의 클래스 A,B가 존재한다고 가정해보자. 만약 A에서 B의 어떠한 프로퍼티 값을 고치고 싶다면? 혹은 A에서 B로 데이터를 옮기고 싶다면? 우리는 Delegate Pattern을 사용해 볼 수 있다. ☀️ Delegate Pattern 예시(1) Teacher는 cleaningArea 프로퍼티를 가지고 있고, Student는 Teacher의 cleaningArea값을 변화시킨다. 해당 과정을 delegate pattern을 통하여 구현해보자. ViewController간의 데이터 전달이 아닌, 일반 클래스 간의 데이터 전달의 예를 알아보자. 아래와 같은 protocol을 생성해보자. // 청소를 시킬 수 있는 protocol CleanOrderable { var cl..
[iOS] Queue 구현하기
💥 Queue 구현하기 Queue를 구현할 경우, 필수적으로 구현해야될 메소드가 몇가지 있다. enqueue dequeue count isEmpty … 일반 array로 구현하는 것보다 double stack으로 구현할 경우 dequeue시, 시간 복잡도면에서 이득을 볼 수 가 있다. ☀️ Array를 통한 Queue 구현 일반 array로 queue를 구현해보면 아래와 같이 구현할 수 있다. struct QueueArray: Queue { private var array: [T] = [] var isEmpty: Bool { return array.isEmpty } var peek: T? { return array.first } mutating func enqueue(_ element: T) { arra..
[iOS] Priority(Autolayout)
Priority UILayoutPriority 는 0~1000의 값을 가진다. .required == 1000 .defaultHigh == 750 .defaultLow == 250 lessThanOrEqualTo 나 greaterThanOrEqualTo 는 다른 제한조건과 같이 쓰인다. 만약 다른 제한조건이 없다면 equal로 간다! 아래의 경우, 아이폰 X과 SE(8)의 safe area의 차이를 보여주는 그림이다. SE는 safe area의 bottom과 super view의 bottom이 같음을 알 수 있다. 위의 두 아이폰 기종을 통하여 priority에대해 이해를 해보자. 먼저 아래의 코드는 button을 view에 추가하고 leading, trailing만 safe area에 맞춰준 상태이다...
[iOS] prepareForReuse()
prepareForReuse() tableView를 구현 시, reusableCell을 dequeue할 때 생기는 문제를 해결하는 방법! 먼저, dequeueReusableCell 은 아래의 그림과 같은 과정으로 진행이된다! 이럴 경우, line2에 설정된 attribute이 그대로 line6에 적용이될 수 있다. 이런 문제를 해결하기 위해서는, cell이 reuse되기 전에 prepareForReuse()을 통하여 매번 cell을 초기화해주면 된다. 예제 코드 tableview가 존재하고, 해당 tableview는 custom cell인 ReuseCell을 가지고 있다. 해당 tableview는 두 가지의 조건이 있다. row가 0일 경우 cell의 background color를 빨간색으로 설정하고,..
[iOS] TableView의 reloadData()란?
💥 reloadData()란? tableView의 인스턴스 메소드 테이블 뷰의 현재 보이는 전체 열(row), 섹션(section)을 업데이트할 때 사용한다. 특정 열, 섹션 등 부분적인 업데이트가 아닌, 전체 영역을 업데이트할 때 유리하다. 🌟 reloadData()의 과정 reloadData()호출 numberOfItemsInSection 메소드에서 cell의 갯수를 결정한다. cellForItemAt 메서드에서 cell을 화면에 보여질만큼의 셀을 생성한다. ‼️ 주의사항 tableView의 row를 제거하고, 삽일할 때는 사용하면 안된다❌ 일부만 업데이트를 할 경우, reloadRows(at:with:), performBatchUpdates(_:completion)을 사용한다. 해당 메소드는 UI를..
[iOS] iOS 프로젝트 파일 폴더링
iOS 프로젝트 파일 폴더링 정해진 법칙은 없기에, 속한 조직이나 나 자신이 보기 편하게 폴더링을 하는게 중요하다! 아래의 구조를 따른다. 📂 Resources SceneDelegate AppDelegate Assets Constants Extensions Fonts 📂 API관련 파일 📂 Storyboards launchScreen 📂 Sources 📂 ViewControllers 📂 Models 📂 Network 📂 Classes 📂 Protocols 📂 Cells 📂 Designs 📄 Info.plist