9월, 2020의 게시물 표시

[iOS] Kingfisher 둘러보기

이미지
[iOS] Kingfisher 둘러보기 이미지 서버에서 이미지를 가져다 표시해줄 때 항상 쓰던 라이브러리 입니다. 어떤 기능이 있는지 살펴보기 전부터 웹에서 주소로 이미지를 가져올 때는 항상 써서, 이미지를 불러오는 라이브러리 인 줄 알았습니다. 하지만 본래의 목적은 이미지 캐싱이라는 것을 알게 되었고, 이번기회에 어떤 기능이 있는지 살펴보겠습니다. 내용은 Cheat Sheet 를 참고했습니다. 이미지 로딩 저도 이 기능 때문에 사용하는 줄 알았던 이미지 로딩입니다. 사용법은 굉장히 간단합니다. 이미지 뷰를 포함해(NSImageView, UIButton and NSButton)에 Extension 으로 구현되에 있기 때문에 setImage 를 사용해 이미지를 설정하면 됩니다. import Kingfisher let url = URL(string: "https://example.com/image.png") imageView.kf.setImage(with: url) 내부의 동작과정은 다음과 같습니다. url.absoluteString 로 캐싱된 이미지가 있는지 확입합니다. 만약 이미지가 캐싱되어 있어서 찾으면(메모리, 디스크 중), imageView.image에 나타냅니다. 만약 찾지 못한다면, url로 요청을 날려 이미지를 다운받습니다. 다운받은 데이터를 UIImage object로 변환합니다. 변환한 이미지를 메모리나 티스크에 캐싱합니다. 이미지 뷰에 표시합니다. 이미지 다운로드 이미지뷰이 이미지를 설정할 때 캐싱이 되어있지 않으면 다운로드 합니다. case .network(let resource): let downloader = options.downloader ?? self.downloader let task = downloader.downloadImage( with: resource.downloadURL, options: opti...

dream iOS 아카데미에서 첫 4주 차 배운 내용들

이미지
dream iOS 아카데미에서 첫 4주 차 배운 내용들 맥북을 받고 기다리고 있는건 프로그래밍의 기초보다는 한 서비스를 만드는 방법의 시작이었습니다. Swift Playground 프로토 타이핑 iOS HIG Swift Playground 다운로드 링크 이 것 하나만 있으면 아이패드 본전을 뽑을 수 있다는? 강력한 프로그램 입니다. iOS만이 아니라 기초적인 프로그래밍적 사고를 할 수 있도록 도와주는 게임입니다. 각 스테이지를 클리어하면서 프로그래밍에 다가갈 수 있는 좋은 교육도구입니다. 저희도 공부할 때에 그냥 하세요 했던 것은 아니고 동영상을 참고할 수 있도록 첨부해주셨습니다. 친절하게도 유투브에 모두 공개가 되어있기 때문에 공유 드립니다. 스위프트 하이 채널 여러분도 코딩배우기 1부터 시작해 보시죠! 프로토 타이핑 프로그래밍과 별개로 나는 어떤 앱을 만들 것인가에 대한 생각을 했습니다. 페르소나, ADS 와 같은 것에 대해 공부했습니다. 그러면서 또한 나는 어떤 앱을 만들까 그려보기도 했습니다. 피그마, 스케치, Xds 가리지 않고 사용방법은 웹에 물어물어 익혀서 했습니다. 중요한건 나의 생각의 구체화 하는 것 이었으니까요. 실제 구현가능 여부는 중요하게 생각하지는 않았습니다. iOS HIG (Human Interface Guidelines) iOS앱 개발의 경전이라 불리며, 개발하기전에 꼭 꼭 두번, 세번 읽어야 한다고 하셨습니다. 사용자를 위한 디자인 가이드라고 생각하시면 됩니다. 저도 한 번만 빠르게 읽었는데 기회가 된다면 번역작업까지 할 수 있었으면 좋겠습니다. 양이 좀 많지만 막 너무 어려워서 시간을 들여야 하는 부분은 아니기 때문에 꼭 꼭 읽어보세요! HIG 링크 정리 이렇게 처음 한달은 앱 개발에 필요한 기초체력에 대핸 설명을 듣고 방향을 정하는 작업을 했습니다. 혹시 dreamin iOS Academy에 참여했더라면 나도 앱을 만들 수 있었...

[iOS] iOS14 UIPageControl 써보기

이미지
[iOS] iOS14 UIPageControl 써보기 기존의 UIPageControl과 다른 부분이 추가되어서 대응을 해야 할 부분이 있는지 살펴보았습니다. UIPageControl 소스코드에 들어가서 살펴보도록 하겠습니다. 여러분의 페이지 컨트롤이 클릭을 통해 이동이 가능하다면, 아마 iOS14 업데이트에서 영향을 받았을 확률이 큽니다. 주석의 내용들은 삭제 해 두었으니 궁금하신 분들은 한번 찾아가서 읽어봐도 좋을 듯 합니다. 새로운 상태, 스타일 UIPageControl의 새로운 상태와, 백그라운드 스타일이 추가되었습니다. 0은 아무런 인터랙션이 없는 상태, 1은 1칸을 움직이는 상태, 2는 꾹 누른상태에서 주르르륵 이동하는 상태 입니다. 배경같은 경우 automatic은 꾹 누르지 않았을 때는 투명 꾹 누르면 반투명인 상태가 됩니다. prominent이면 반투명, minimal이면 투명입니다. @available(iOS 14.0, *) public enum InteractionState : Int { case none = 0 case discrete = 1 case continuous = 2 } @available(iOS 14.0, *) public enum BackgroundStyle : Int { case automatic = 0 case prominent = 1 case minimal = 2 } } 프로퍼티들 backgroundStyle 은 위의 설명에 따른 페이지 컨트롤의 배경설정을 가능하게 합니다. interactionState 상태를 읽을 수 있게 해줍니다. allowsContinuousInteraction 연속적인 인터렉션이 가능하게 할 것인지에 대한 여부입니다. preferredIndicatorImage 커스텀 페이지 뷰를 만들 수...

[iOS] swift lint를 코코아 팟 없이 사용하기

이미지
[iOS] swift lint를 코코아 팟 없이 사용하기 스위프트로 프로그래밍을 하면서 swift 코딩스타일 에 맞춰서 코딩을 하도록 도와줄 장치를 찾아보니 swiftLint를 만나게 되었습니다. 사용 방법에 대한 설명을 공식문서 에 제일 잘 나와있기 때문에 첨부만 해 놓겠습니다. 기존의 프로젝트와는 다르게 코딩의 규칙은 설치되어 있어야 하기 때문에 $ brew install swiftlint 로 설치 해줍니다. Xcode를 실행해서 타겟에 새로운 "Run Script"을 눌러서 추가해 줍니다. if which swiftlint >/dev/null; then swiftlint else echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint" fi 설치 후 실행하면 에러나 워닝들이 빡! autocorrect 옵션을 추가해주면, 빌드 했을 때 autocorrect 해줍니다. if which swiftlint >/dev/null; then swiftlint autocorrect else echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint" fi 빈 파일을 추가해 줍니다. 이름은 반드시 .swiftlint.yml 여야 합니다. 그리고 추가한 파일 안에 규칙들을 적어놓습니다. 규칙 보러가기 # By default, SwiftLint uses a set of sensible default rules you can adjust: disabled_rules: # rule identifiers turned on by default to exclude from running - colon - co...

[swift] Self VS .self

이미지
[swift] Self VS .self 코딩을 하다 보니, Self.name 을 쓸 때고 있고, leeo.self도 있어서 self라는 키워드는 언제 어떻게 써야하는지에 대해 정리해 놓겠습니다. Self Self 라는 키워드 는 자기 자신의 동적 클래스를 가리킵니다. 아래의 코드를 보시면 Self는 클래스 자기 자신을 가리켜 Self. 으로 인스턴스의 프로퍼티나 메소드에 접근할 수 있는 것을 볼 수 있습니다. class Student { class var name: String { return "Leeo" } func printName() { print(Self.name) } } class Leeo: Student { override class var name: String { return "hyunho" } } let student = Student() student.printName() let leeo = Leeo() leeo.printName() .self .self 를 이해하려면 Metatype에 대해서 알아야 합니다. 이 글의 주제는 아니기 때문에 .self를 언제 사용하는지에 대해서만 간단히 정리하겠습니다. 아래의 결과가 모두 이해된다면 당신은 이미 .self에 대하여 알고 있는 것 입니다! 아니라면 Metatype에 대해서도 공부해 보시길 권해드립니다. let word = "testString" print(word is String) // true print(word is String.Type) // false print(type(of: word) is String.Type) // true print(type(of: word) == String.self) // true //print(type(of:...

[iOS] Firebase Realtime Database 에 데이터 넣어보기

이미지
[iOS] FirebaseDatabase 파이어 베이스를 이용해서 데이터 저장하고 읽어오기 앱을 만들다보니, 데이터를 저장하고 저장된 데이터를 읽어서 보여주어야 하는 상황에 놓이게 되었습니다. 처음에는 변수나 더미 데이터를 만들어서 저장하고 불러왔지만, 결국에는 서버를 셋팅 해야하나 라는 고민을하게 되었습니다. 그러다가 발견한 파이어 베이스의 기능 중 하나인 Database를 간단하게 사용한 방법에 대해 정리해 놓겠습니다. install 파이어 베이스를 사용하기 위해서는 패키지를 설치 해 줘야합니다. 공식 문서를 보고 설치하면 어렵지 않습니다. 귀찮으신 분들을 위해 간략히 적어놓자면, Xcode의 SwiftPackageManager를 사용해 https://github.com/firebase/firebase-ios-sdk.git 를 추가하면 됩니다. 그 중에서도 FirebaseDatabase 를 꼭 설치해주세요. Firebase에서 새 프로젝트를 만드신 후에 iOS프로젝트를 추가 해 줍니다. 설명을 따라 진행하면 어렵지 않게 완료할 수 있습니다. 핵심은 번들ID를 잘 입력 해주는 것과 GoogleService-Info.plist 파일을 잘 다운받아 내 프로젝트에 넣어주는 것 입니다. Data firebaseDatabase는 JSON 형식의 데이터를 지원합니다. 간단히 JSON을 설명 드리면, 키 - 밸류 로 이루어진 데이터 포맷입니다. 우리는 간단한 JSON형식의 데이터를 작성해 볼것 입니다. 예제 데이터는 아래와 같이 생겼습니다. { user { age : 31, married : false name : "hyunho" } } Data Write 데이터 베이스가 비어있으니 일단 쓰는 기능부터 구현해 보겠습니다. import Firebase let testItemsReference = Database.database().referen...

[Xcode] 디버깅 입문

이미지
[Xcode] 디버깅 입문 Xcode 디버깅 입문 코딩을 하다가 버그를 발견하거나 내가 원하는 결과가 나오지 않을 때면, 프린트 문을 써서 문제를 해결하곤 했는데 디버깅 툴 이라는 것을 발견한 후로 잘 쓰면 생산성을 향상 시킬 수 있을 것 같아서 정리 해 놓습니다. Xcode에 있는 디버깅 도구를 활용해 버그를 잡아봅시다. BreakPoint 브레이크 포인트는 실행중인 앱을 일시정지 하는 포인트 입니다. 사용 법은 매우 간단합니다. Xcode 소스코드의 왼쪽에 있는 라인 넘버를 클릭하면 파란 화살표가 생깁니다. 브레이크 포인트가 생성된 것 입니다. 이제 앱을 실행시키면, 브레이크 포인트에서 앱이 일시정지 되는 것을 볼 수 있습니다. 다시 앱을 동작하게 하는 방법도 간단합니다. 디버깅 창 중간의 삼각형 모양의 화살표를 눌러주면 다시 실행됩니다. 만약 브레이크 포인투가 두개라면 다음 브레이크 포인트에서 일시정지합니다. 브레이크 포인트를 다시 한번 클릭하면, 비활성화됩니다. 토글 형태이기 때문에 활성화, 비 활성화 하면서 브레이크 포인트를 사용할 수 있습니다. 브레이크 포인트는 오른쪽으로 드래그 하면 제거됩니다. 위 아래 방향으로 드래그 해서 옮길 수 있습니다. 디버깅 창에서 브레이크 포인트와 같은 파란색 화실표 버튼을 누르면, 한번에 모든 브레이크 포인트를 활성화, 비활성화 시킬 수 있습니다. Xcode의 왼쪽 네비게이터에서 브레이크 포인트 모양의 아이콘을 누르면 현재 설정된 브레이크 포인트들을 한번에 볼 수 있습니다. 디버깅 중 일시 정지된 브레이크 포인트에서 현재 변수 상태를 확인할 수 있습니다. 가리키고 있는 브레이크 포인트에서 변수에 어떤 값이 할당되어있는지 확인 할 수 있습니다. 이 창을 통해 내가 기대하고 있는 값이 제대로 들어가 있는지 확인하면 문제를 해결하는데 큰 도움이 됩니다. Control flow 앱의 사용 흐름을 체크 하는데 모든 라인에 일일이 브레이크 포인트를 걸어주어...

[swift] Type Method (class func vs static func)

이미지
[swift] Type Method instance vs class vs static 클래스를 사용할 때에 static이 붙은 메소드를 사용하지 못해서 문득 아 얘를 언제 쓰는지 모르고 있구나 라는 생각에 정리해 두겠습니다. func 라는 키워드는 함수를 만들 때 많이 들 보셨을 것이라고 생각합니다. 오늘은 이 앞에 붙는 키워드들의 종류와 그 이유에 대해 알아보고 정리하겠습니다. 아무것도 붙지 않음 func instanceFunc() {} class가 붙음 class func classFunc() {} static이 붙음 static func staticFunc() {} How to make Func 아무것도 붙지 않은 함수는 평범하게 아래와 같이 사용이 가능합니다. class Student { func instanceFunc(){ print("instance func leeo") } class func classFunc() { print("class func leeo") } static func staticFunc() { print("static func leeo") } } let student = Student() student.instanceFunc() Student.classFunc() Student.staticFunc() // instance func from Parents // class func from Parents // static func from Parents 그렇다면 다른 두 키워드 class , static 은 언제 쓰는 것이고 어떤 장점이 있는 걸까요? 이 두 키워드는 클래스가 만든 인스턴스에서 사용하는것이 아닌 클래스 자체에서 사용하는 메소드입니다. 이 두개를 타입 메소드라고 부르는데 어떤 의미냐 하면, 인스턴...

[swift] if 문에서 콤마와 && 연산자의 차이점

이미지
[swift] if 문에서 콤마와 && 연산자의 차이점 코딩을 하다가 Bool? 타입의 변수에 true값이 왔는지를 체크하다가 우연히 찾게된 코드를 보고 이해하기 위해서 정리 해놓습니다. 원래 사용했던 코드는 아래와 같았습니다. let result: Bool? if let result = result { if result { print("result is true") } else { print("result is false") } } else { print("result is nil") } 옵셔널일 때 값이 있는지 없는지를 검증하고 나서 그 안의 값을 사용하는 코드를 짰었습니다. 하지만 실제로 false일 때의 경우에는 아무런 행동을 하지 않았기 때문에 else라인은 비어있었습니다. 논리 적으로 아래 코드와 같이 써서 사용할 수 있을 줄 알았는데 동작하지 않았습니다. if let result = result && result { print("result is true") } if let으로 옵셔널을 제거 해 준 후에 사용할 수 있기 때문입니다. 검색을 통해 찾아보니 이럴 때 comma를 이용해 코드를 명확하게 짤 수 있었습니다. let result: Bool? = false if let result = result , result { print("result is true") } else { print("result is nil or false") } 막상 짜 놓고 보니 &&와 comma가 왜 다른지 이 구문이 어떻게 동작하는지에 대해 잘 모르고 있었기에 정리 해 놓겠습니다. 공식 문서 의 if Statement 부분을 참고해보니 이런 내용이 있었습니다. if Stat...

[git] git의 마지막 커밋 메시지 수정하기

이미지
[git] git의 마지막 커밋 메시지 수정하기 git을 쓰다가 보면 한참 커밋을 하고나서 푸쉬를 하고나니 의미없는 커밋 메시지가 많아서 커밋메시지를 위한 커밋 메시지를 커밋 하게되었습니다. 아무 의미 없는 커밋을 하나 늘리기는 싫어서 방법을 찾아보니 rebase를 쓰면 가능한 것을 찾았지만, 원래 기능이 아니기 때문에 다른 방법을 소개하려고 합니다. 아래와 같은 명령어를 입력합니다. git commit --amend 마지막 커밋 메시지가 뜨면서, 수정 후 저장할 수 있습니다. -m옵션을 주어 새로운 커밋 메시지를 바로 입력할 수 있습니다. git commit --amend -m "new message" push 하면 되지 않습니다. 왜냐하면 origin의 HEAD 보다 브랜치의 최신 커밋이 아니기 때문에 거절됩니다. 그러므로 우리는 강제로 push 해주어야 합니다. git push --force 하지만 이 때 주의해야 할 점이 있습니다. 누군가 이미 push 한 브랜치를 force push 하게 된다면, 같은 브랜치에 다른 이력이 쌓여 추후에 문제가 발생할 수 있습니다. force push 를 한다면 이렇게 꼬일 수 있는 상황에 대해서도 염두해 두어야 합니다.

[git] git의 upstream과 origin 헷갈리는 사람 손!

이미지
[git] git의 upstream과 origin git의 upstream과 origin upstream과 downstream 사전적인 의미를 파악해보면, upstream 이 상류, downstream 이 하류입니다. 물이 상류에서 하류로 흐르듯이 pull 하는 주최가 downstream 당하는 쪽이 upstream 입니다. 내 레포에서 다른 레포를 풀 해서 작업하고 있다면 다른 레포가 업스트림이 되겠군요! otherRepository(upstream) -> (git pull) myRepository(downstream) 이미지 출처 : https://aktiasolutions.com/upstream-kanban-business-agility/ upstream과 origin 그렇다면 업스트림과 오리진은 어떤 차이가 있는지 정리 하겠습니다. 보통은 다른 레포를 포크해서 내 레포를 만들어 놓고 내 레포를 클론, 풀 해서 작업합니다. 이때 가장 근본이 되는 레포를 upstream 이라고 부릅니다. 내가 fork해서 가져온 레포를 origin이라고 부릅니다. 그러므로 내가 로컬에 클론 해 놓고 작업할 때, origin/master에서 가져올지, upstream/master에서 가져와야 할지 생각해서 가져와야겠죠? otherRepository(upstream) -> (fork) myRepository(origin) otherRepository(upstream) -> (git pull) myRepository(local) myRepository(origin) -> (git pull) myRepository(local)