⭐️ 개발
[iOS] Alamofire, SwiftyJSON을 사용해서 HTTP 통신하기
SwiftyJSON과 Alamofire을 사용해서 Naver 번역 OPEN API를 가져와서 구현할 것임 SwiftyJSON은 Alamofire와 함께 쓸 수 있는데 HTTP 통신할 수 있게 도와주는 라이브러리로 유명하다. 어떻게 사용하는지 예시코드를 그대로 가져가서 사용하면 된다. Alamofire 5부터 AF가 사용되는 점, AF는 Session.default를 참조하는 것. func requestTranslatedData(text: String) { // URL에 다 담는 것이 아님 let url = EndPoint.translateURL // Header : 메타정보 // Body : 실질적인 데이터 // Naver 개발 가이드에서 제공하는 걸 보고 따라하자 let parameter = ["sou..
[Swift] Singleton Pattern
enum에서는 타입 프로퍼티만 사용할 수 있다. 초기화 자체가 안되기 때문에 저장 프로퍼티는 사용할 수 없다. struct에서는 초기화가 가능하다. 그래서 인스턴스 생성을 못하게 하기 위해서 접근 제한자를 초기화 구문 앞에 붙여서 막는 방법을 사용한다. struct StoryboardNames { // 접근제어를 통해 초기화를 막을 수 있음 private init() { } static let main = "Main" static let search = "Search" static let setting = "Setting" } 그러면 enum에서는 타입 프로퍼티 말고 case를 쓰면 안될까? 움,, 아무래도 case를 쓸 경우에는 rawValue를 중복해서 써줄 수 없다는 불편함이 있다. Singleto..
[Swift] ReusableViewProtocol로 뷰컨/셀 식별자 사용하기
기존에 tableViewCell이나 collectionViewCell의 reuseIdentifier를 사용하기 위해서는 문자열을 통해 접근해야 했다. 그렇다보니 발생하는 문제점은 휴먼에러.. 그니까 오타..!로 인해 찾지 못한다는 점 1. 타입 프로퍼티 각 클래스 파일에 작성하기 각 클래스마다 타입 프로퍼티를 만들어서 초기에 인스턴스를 생성해서 접근했다. 매번 클래스 만들 때마다 작성해줘야 하는 것과 각 클래스 파일에 들어가서 하나하나 체크해줘야 하는 게 번거롭다. 2. Constant 구조체 내에 모든 클래스의 타입 프로퍼티 모아두기 두 번째 방법으로는 Constant라는 구조체 파일에 모든 클래스의 타입 프로퍼티를 작성해서 접근하는 방식으로 만들어줬다. 이 방식의 장점은 모든 클래스들의 identif..
REST API 6원칙
REST API 6원칙 1. 자원에 대한 식별이 가능해야 함 2-1. HTTP - 비연결성 : 서버 통신이 필요할 때만 연결, 늘 연결되어 있는 건 아니니까! connectionless 같은 아이폰에서 계속 연결해도 할 일 끝나면 연결관계가 끝남 2-2. Stateless - 무상태성 : 응답이 다 완료가 되면 이 관계는 끝남. 그렇기 때문에 서버는 클라에 대한 정보를 가지고 있지 않음 그래서 웹에서는 세션과 쿠키, 앱에서는 토큰을 통해 회원관리를 하게 됨 기본적으로 서버는 사용자를 식별할 수 없는 무상태성을 갖고 있기 때문에 세션/쿠키/토큰을 갖고 있는 것 3. Cacheable : 캐싱기능, 오랜만에 페이지에 들어가면 로딩이 좀 됨, 다시 들어가면 빨리 뜨는데 그 이유가 캐싱 때문임. 사용자가 다시 ..
[리팩토링] 캐치미 프로젝트에서 프로퍼티 옵저버 적용하기
프로퍼티 옵저버나 연산 프로퍼티 같은 개념들은 사실 배우고 나서 실제 프로젝트에 적용을 하려고 노력하지 않으면 매번 체화시키기 어려운 것 같다. 현재 진행 중인 캐치미 프로젝트에 어떻게 적용시켰는지 기록해보려고 한다. 우선, 그 전에 프로퍼티 옵저버 중에서 didSet 개념을 다시 잡고 가자면 저장 프로퍼티를 관찰하고 있다가 값이 변경된 직후에 호출되는 거다. 어떻게 사용했냐면, 우선 어떤 방식으로 해당 코드가 돌아가야 하는지 살펴보면, 글을 10개(2단계는 10개, 3단계는 30개) 이상 작성하면 레벨이 올라가서 popupView(팝업창)의 levelData가 올라가고, catchuImageView의 캐츄 캐릭터가 업그레이드 된다. 위 코드가 LevelUpPopupVC에서 levelData와 catch..
[Swift] Class와 Struct 그리고 부스러기 개념들
Class / Struct 변수/상수가 클래스/구조체/열거형 등에 들어가면 프로퍼티라고 바뀌고, 함수는 메소드로 바뀜 그래서 프로퍼티랑 메소드는 멤버라고 부른다. 각각을 프로퍼티 멤버, 메소드 멤버라고 부른대!! 꺄! 흔히 알듯이, 클래스에 있는 프로퍼티와 메소드의 속성을 가진 걸 사용하기 위해 만들어주는 객체를 인스턴스라고 하고 이 인스턴스를 통해서 내부 프로퍼티와 메소드에 접근할 수 있다. 예를 들어, 붕어빵틀이라는 클래스가 있으면 슈붕이라는 인스턴스를 만들어서 내부 속재료 프로퍼티에 접근해서 슈붕.속재료 = "슈크림" 팥붕.속재료 = "팥" 이런식인 것처럼 말이지.. 여튼 슈붕과 팥붕은 붕어빵틀 클래스의 인스턴스다. 구조체와 클래스의 가장 큰 차이는 상속과 초기화 구문 제공..? 아닐까 싶다. 클래..
[Swift] 스위프트 성능 이해하기1 - Struct / Class
프로토콜 지향 프로그래밍 POP 참조타입을 조심해야 된다. 클래스는 참조타입이지. 그리고 참조타입을 잘못 쓰다가는 원본을 참조하는 여러 인스턴스가 까딱하면 원본 데이터를 변경해버리기 때문이다. 그래서! 애플은 구조체를 권장하는 거다. 물론 다른 이유도 있겠지.. 구조체로 이루어진 많은 내부 타입들은 프로토콜 채택을 통해 기능들을 구현한다. 매번 채택하고 내부 메소드와 프로퍼티를 구현하는 걸까? 그건 아니다. 어떻게 해결하냐? 바로 Extension을 통해 가능하다. Extension을 통해 초기 기능을 구현해둔다. 그리고 각각의 실제 구현부에서 적합하도록 기능을 구현한다. 스택은 가장 마지막에 들어온 게 가장 먼저 나가는 단순한 구조라서 메모리 할당이랑 해제가 편하다. 스택은 스택 포인터로 할당, 해제를..
[iOS] DataSource, Delegate | TextView Placeholder | WebKit
Dear apple UIKit Developer UITextView Placeholder 만들어조 plz... Thx.. TextView Placeholder 텍뷰 플레이스홀더는 기본적으로 제공되지 않는다. 도대체 그 이유를 알 수가 없어. 왜 제공을 안하는 건지..;;여하튼! 그래서 눈속임으로 만들어주는 건데 대강 사용하는 건 UITextViewDelegate 프로토콜을 채택해 프로토콜 메소드를 통해서 기능을 구현해주면 된다. 내부에서 텍스트뷰가 편집이 시작될 시점과 편집이 끝나는 시점과 관련된 메소드를 잘 활용해서 플레이스 홀더 기능을 하게끔 텍스트뷰의 텍스트의 색상값과 텍스트값을 주면 된다. UIButton, UITextField > Action이 가능 UITextView, UISearchBar, ..
[iOS] PickerView
PickerView 몇 개의 휠을 보여줄 거니? -> 2개의 휠을 보여주겠다. 하나의 휠에 몇 개의 row를 보여줄 거니? -> 첫 번째 휠이라면 10개의 row를, 두 번째 휠이라면 20개의 row를 보여줄 것이다. 전체적으로 보자면 이렇다. 그리고 꼭 델리게이트 위임처리를 해줘야 한다. UIPickerViewDelegate, DataSource는 부분은 아래처럼 써줄 수 있다. 세 번째 didSelectRow는 선택되면 어떤 동작을 할 건데? -> textField에 값을 줄게! 보통 이렇게 구현을 하고, 나의 경우는 같은 파일에서 하단에 extension을 통해서 코드를 분리해주는데 extension 파일을 분리해서 만드는 것도 가능한데, 현업에서 많이 보이는 코드 스타일은 하단에 배치해주는 경우가..
[iOS] 프로토콜
프로토콜은 준수해준 곳, 채택해준 곳에서 실질적으로 구현한다. 선택적인 구현이 가능하다. 채택 개수에 제한이 없다. 어떤 프로토콜을 채택했냐에 따라 코드가 그려진다. - 프로토콜 내에서 옵셔널 요소는? @objc optional : 선택적 요청, Optional Requirement이라고 부른다. 프로토콜을 채택할 건데 안쓸 수 있는 아이들이 있기 때문에 optional 키워드를 붙이는 것이다. 옵셔널 요소를 포함하고 있다면 프로토콜 자체도 @objc(오브젝트 코드)를 붙여줘야 한다. @objc protocol ViewPresentableProtocol { func configureView() @objc optional func configureLabel() @objc optional func confi..
[iOS] '처음으로' 돌아가는 코드 | SceneDelegate에서 분기처리해주는 코드
특정 화면에서 특정 버튼을 누르면 앱을 다시 켠 것처럼 돌아갈 수 있게 해주는 코드이다. SceneDelegate를 쓸 수 있게 해주는 부분이고, 스토리보드를 사용한 부분이다. 만약 내가 이미 기존 사용자라면 UserDefaults를 사용해 값을 저장해두고, SceneDelegate에서 다음과 같이 분기처리를 해두고 처음 시작 화면을 바꿀 수도 있다. 우리가 기존에 사용하는 변수, 상수는 메모리 상에서 유지되기 때문에 화면전환을 통해 뷰컨이 메모리에서 제거되면 해당 변수, 상수의 데이터도 함께 사라진다. 근데 이 UserDefaults는 다르다. 프로그램의 실행이 종료되어도 사라지지 않는다. UserDefaults는 주로 가벼운 단일 데이터를 저장하기에 적합하다. 이를 통해서 자동 로그인, 앱 첫 실행 ..
[Swift] Property Observer - didSet / willSet
7/27 수요일 사실 프로퍼티 옵저버가 제일 .. 어떻게 언제 써먹어야 하는지 이해가 안간다... 변경 후 작업을 수행해서 UI를 업데이트하거나 변경 내용을 저장하는 didSet을 주로 사용한다고 한다.. willSet은 사실 많이 사용하진 않고, 속성이 변경되기 전에 프로그램 상태를 알아야 할 때 사용한다.. Property Observer 프로퍼티 옵저버, 말 그대로 저장 프로퍼티에서 사용되고, 값을 관찰하다가 변경되었을 때 호출된다. didSet, willSet이 있는데 willSet - 변경되기 직전에 didSet - 변경되고난 직후에 구조체에 dream이라는 인스턴스 저장 프로퍼티에서 사용되고 있는 걸 볼 수 있다. 초기값을 Designer라고 준 상태에서 해당 프로퍼티에 접근하기 위해 새 인스..
[Swift] 타입/인스턴스 - 저장/연산 프로퍼티
7/26 TIL 헷갈리고도 헷갈리는 프로퍼티의 세계에 대해 공부한 걸 바탕으로 주저리주저리 읊어볼까 한다. 머리에 정립이 안되니 너무 헷갈려서.. 일단 읊어보면 이해되지 않을까? Property 구조체와 클래스 내에서 변수와 상수를 프로퍼티라고 부른다. 이 프로퍼티는 우선 타입 프로퍼티랑 인스턴스 프로퍼티로 나뉜다. (지금 말하는 이 두 프로퍼티들은 저장 프로퍼티의 특성을 띄는데 편의상 키워드는 생략하고 부르겠다.) 타입 프로퍼티와 인스턴스 프로퍼티 IceCream이라는 클래스가 있고 IceCream이라는 클래스 타입 내에 flavor라는 프로퍼티에 접근하고 싶다면 우리는 인스턴스를 생성해야 가능하다. var myIceCream = IceCream() myIceCream.flavor = "엄마는외계인" ..
[Swift] 타입 프로퍼티 왜 씀?
타입프로퍼티? 항상 tableViewCell이나 collectionViewCell 만들면 무의식적으로 반복해서 가장 먼저 만들어주던 코드 static let identifier = "BookTableViewCell" 이걸 왜 했던 걸까? 분명 그 당시에는 이유를 알고 있었는데.. 명확하게 설명 못하는 걸 보면 몰랐떤 것이지.. 아무튼 그 이유를 오늘 다시 알게 돼서 내 말로 정리를 하자면, 테이블뷰/컬렉션뷰를 만들어 줄 때 cellForRowAt 그러니까, 테블뷰/컬렉션뷰에 사용할 셀을 재사용해주는 과정에서 셀의 identifier을 문자열로 가져오는 경우가 있다. 이렇게... 그런데 이렇게 하다보면 휴먼에러로.. 오타가 나는 경우가 있고, 이걸 방지하기 위해서 타입 프로퍼티를 통해 해당 셀의 ident..
[iOS] cell shadow + cornerRadius 같이 주는 방법
쉐도우는 뷰 경계를 넘어서서 퍼져나가는 거라서 masksToBounds를 true로 해주면 적용이 안된다. 반면에 cornerRadius는 false로 해줘야 한다. 그래서 둘은 동상이몽임. 근데 같이 주고 싶은 경우에는 어떻게 해야 하나? 오늘 과제를 구현하면서 방법을 구글링하게 됐다. 매번 해도 매번 까먹는 거.... cell에 shadow를 넣고, contentView에 cornerRadius를 주면 된다. shadowRadius : 블러의 정도 : 값이 커질수록 퍼짐 shadowOffset : 그림자의 위치 - CGSize shadowOpacity : 그림자 모양 투명도 : 값이 커질수록 진해짐 shadowPath : 그림자모양 (커스텀이 가능)