티스토리

내 머리에 push 중..
검색하기

블로그 홈

내 머리에 push 중..

pushedgun.tistory.com/m

App Developer

구독자
2
방명록 방문하기

주요 글 목록

  • git 원격 저장소에 개인정보를 실수로 올려버렸을 때 git filter-branch -f --prune-empty --index-filter "git rm -r --cached --ignore-unmatch path/fileName" HEAD 이걸로 해결하였다.. 참고로 path는 다음과 같이 지정해주었다. ./filefolder/fileName *나는 ./ 이걸 안써줘서 시간을 좀 날렸다.. 이런 방식으로.. 모든 커밋에서 해당 파일과 관련된 모든 정보를 지우는 명령어이다. 이렇게 수정 후 원격 저장소에 force 옵션으로 push해주면 된다. 상세한 정보는 GPT한테 물어봤다. -f 또는 --force: 필요한 경우 덮어쓰기를 강제합니다. 이 옵션을 사용하면 기존에 filter-branch에서 만들어진 백업이나 임시 파일을 덮어쓰기할 수 있습니다. -.. 공감수 0 댓글수 0 2024. 4. 2.
  • [Git] Git push f옵션 원격 저장소에 저장할 때, git push -f origin (저장소명) 위와 같이 설정하면 강제로 저장소에 push해준다. 필자는 잘못 원격저장소에 push해버린 commit 기록을 없애기 위해 사용하였다. 공감수 0 댓글수 0 2024. 3. 24.
  • [13일/총 32시간]교재 안사고 정보처리기사 필기 합격한 후기(2024년 1회) 그간 미루어두었던 정보처리기사 시험을 접수하였다. 네이버 부스트 캠프를 하며 탄탄한 CS지식의 필요성을 더욱 느꼈기 때문이다. 2/15 정보처리기사 필기에 합격하여 혹 도움이 될까싶어 후기를 공유하고자 한다. 1. 배경 지식 - 비전공과 전공 사이. 깊게 배우진 않았고 프로그래밍 개론 등 가벼운 과목을 수강하였었다. - 부트캠프 2회(윈도우 닷넷 전문가 과정, 네이버 부스트 캠프 웹・모바일) - 윈도우앱 개발 경력 약 9개월 2. 활용한 자료 및 반복 학습 수 교재는 따로 구매하지 않고, 인터넷에 검색하여 나온 자료들을 활용하였다. 정보처리기사 시나공 2023 요약집 4회독 3회분 기출문제 풀이 (푼 횟수) -20220424 (2번) -20210814 (2번) -20220305 (1번) 3. 구체적인 학.. 공감수 0 댓글수 1 2024. 2. 18.
  • [SwiftLint/SwiftFormat] 깔끔한 코드를 만들어보자. (ft. 에러 해결) 1. 개요 들여쓰기 칸 수, 공백 등.. 코드를 작성하는 스타일은 사람마다 다를 수 있다. 그런데 협업을 하는 경우에도 한 프로젝트 내에 사람들의 각기 다른 습관들이 나타난다면 코드를 읽기가 참 힘들어질 것이다. 그래서 이런 약속들을 swiftLint, swiftFormat을 사용하여 정해둔다. 물론, 협업을 하지 않는 경우에도 코드 내에 사용되지 않는 등 불필요한 코드들을 관리할 수 있다. 2. SwiftLint swiftLint는 정한 규칙을 어길 시, warning이나 error를 표시해주는 역할을 한다. 제공되는 규칙과 사용방법은 다음 링크에서 확인할 수 있다. Rule Directory Reference realm.github.io 참고로 필자는 프로젝트에서 다음과 같은 규칙을 정하였다. # 한.. 공감수 0 댓글수 0 2023. 11. 8.
  • URLSession 의존성 제거하기 1. 리뷰 final class APINetwork { func request(requestable: Requestable, type: T.Type) -> AnyPublisher { let request: URLRequest = requestable.asURLRequest() return URLSession.shared .dataTaskPublisher(for: request) .//생략.. .eraseToAnyPublisher() } } 위 코드에서 리뷰어님께 다음과 같은 리뷰를 받았다. 2. Session 프로토컬 생성 protocol Session { func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher } e.. 공감수 0 댓글수 0 2023. 10. 28.
  • [Swift] 정규표현식, 편리하게 쓰세요. (ft. name capture) 1. 정규표현식 func isOutOfRangePassword(passwordText: String) -> Bool { let rangeRegex = /^password:.{8,16}$/ if passwordText.prefixMatch(of: rangeRegex) == nil { return true } return false } 정규표현식을 사용하여 받은 문자열의 패턴을 파악하는 것은 흔히 사용되는 방법이다. 그런데 패턴 뿐만 아닌, 원하는 패턴의 문자열을 정규표현식을 사용하여 추출하는 것도 가능하다. 바로 예제를 보자. 2. name capture func isOutOfRangePassword(passwordText: String) -> Bool { let rangeRegex = /^password.. 공감수 0 댓글수 0 2023. 10. 28.
  • [swift] closure [weak self]를 남용하지 말자. 1. closure에서 self를 쓰면 무조건 순환참조? closure로 값을 넘겨주고, 그 안에서 self를 호출할 일이 있을 때 순환 참조를 우려하여 weak self를 종종 사용하였다. 그런데, 모든 closure라고 항상 self를 쓴다고 순환 참조가 발생하지 않는다. 2. non-escaping closure의 경우 위 그림과 같이 함수가 return 되며 closure도 함께 메모리에서 사라지기 때문에 순환참조를 우려할 필요가 없다. class A와, 그 안에서 함수와 함수에서 사용되는 closure 가 있다고 가정하자. 여기서 closure 안에 self를 사용하여도, self 안이 아닌 func 안에 closure이 존재하기에, func가 사라지면 closure도 사라지기에 순환참조가 발생.. 공감수 0 댓글수 1 2023. 10. 27.
  • [iOS] assertionFailure, 배포버전에선 터지지 않도록 하기 1. 개요 fatalError를 사용하면, 개발 뿐 아니라 배포버전에서도 Error가 난다. 그런데 개발 시에는 Error를 내고 싶지만, 배포할 땐 내지 않도록 하고 싶은 경우가 있을 것이다. 2. assertionFailure 이런 경우에 사용하기 좋다. 단, fatalError처럼 return을 무시해주진 못하니 구현을 해두어야 한다는 번거로움이 있다. https://developer.apple.com/documentation/swift/assertionfailure(_:file:line:) assertionFailure(_:file:line:) | Apple Developer Documentation Indicates that an internal sanity check failed. develo.. 공감수 0 댓글수 0 2023. 10. 26.
  • dequeueReusableCell과 dequeueConfiguredReusableCell, 뭐가 다를까? 1. dequeueReusableCell collectionView.dequeueReusableCell(withReuseIdentifier: ****, for: ****) 우리가 아는 것처럼 cell을 재사용하는데 사용한다. 참고) [iOS] CollectionView Xib 파일 생성하여 Custom Cell로 구현하기 1. Collection view 생성 2. Custom Cell에 대한 class 생성 3. Xib 파일 생성 4. File's Owner, Custom Class 란에 방금 생성한 custom cell의 class 입력 5. 재사용 식별자 등록(여기선 "cell" 로 등록, 원하는 아무 문자로 설 pushedgun.tistory.com cell에 값을 넣어주기만 하는 기능에서는 문제.. 공감수 0 댓글수 0 2023. 10. 26.
  • 사이트의 http 버전을 확인하는 방법 1. 개요 만든 network에 대한 테스트 코드를 작성하는 도중 성공한 응답에 대한 mock이 필요하게 되었다. 그런데 mock을 생성하려면 api를 요청할 사이트에 대한 http 버전 정보가 필요하였다. let successResponse = HTTPURLResponse(url: , statusCode: , httpVersion: , headerFields: ) 2. api를 요청할 사이트의 http 버전을 확인하는 방법 api를 요청할 사이트의 http 버전을 확인하는 방법은 curl -I 주소 위와 같은 형식으로 터미널에서 명령을 보내주면 알 수 있다. 여기선 토큰을 함께 주지 않아서 에러 메세지도 같이 반환되었지만, 어떤 HTTP 버전인지와 어떤 타입으로 자료를 주는지도 알 수 있다. 공감수 0 댓글수 0 2023. 10. 26.
  • [Swift] defer, 내부 코드를 매우 간단하게 만들고 싶을 때! 1. 더러운 switch 문 코드를 짜다, 다음과 같은 흉측한 switch 문이 만들어졌다. func idState(id: String) -> IDState { if isOutOfRangeID(id: id) { idState = false return .outOfRange } else if isDuplicateID(id: id) { idState = false return .duplicate } idState = true return .success } 똑같은 idState 코드가 몇 번이나 반복된다. idState = false 를 if문 위로 올려주는 방법도 있겠지만, 프로젝트에서 이 프로퍼티의 특성상 종료되는 순간에 확실한 bool 값을 가지도록 하여야 하였다. 2. defer 예전 NSLock을 .. 공감수 0 댓글수 0 2023. 10. 24.
  • [Swift] Opaque Type: Some을 붙여 타입캐스팅할 필요없이 구체 타입으로 사용하자. 1. 타입 캐스팅해서 쓰는 게 맞나...? protocol Shape { var color: Color { get, set } } class Square: Shape { var color: Color var text: String ..생략.. } // func get() -> Shape { //추상 타입으로 값을 리턴해주기에, shape에 있는 형태밖에 사용하지 못한다. let square = Square(..생략..) return square } //사용할 때 let a = get() a.color a.text//에러!! 위와 같이 이 추상화 protocol로 호출할 경우 해당 protocol의 인터페이스대로 사용할 수밖에 없다. 2. Some 사용하면, 구체 타입을 직접 사용할 수 있다!! 바로 예제.. 공감수 0 댓글수 0 2023. 10. 24.
  • [Swift] Completion Handler(ft. Escaping Closure) 원하는 타이밍에 비동기 처리를 할 수 있게 해준다. 이게 무슨 말일까?? 각설하고 바로 예제를 보자. 1. Completion Handler 예제 모든 method에 completion 인자를 추가해주면, completion Handler를 사용하는 인자로 바꿀 수 있다. func A(completion: () -> ()) { ...10초 걸리는 작업.. completion() ...10초 걸리는 작업.. } func B() -> () { ...5초 걸리는 작업.. } //Completion Handler A(completion: B) // -> A가 호출되고 10초 뒤, B가 비동기로 실행된다. 그림으로 표현하자면 다음과 같다. A 함수 내부에 completion()을 적어둔 시점에서 B가 호출되며, .. 공감수 1 댓글수 0 2023. 10. 22.
  • [Swift] Trailing Closure란? 아래와 같이 closure을 인자로 보낼 때, 직접 method를 넣어 보내지 않고 { }을 통해 보낼 수 있다. //아래와 같은 함수의 경우 func A(task:() -> ()) { ... } func B() { ... } //기본 A(task: B) //Trailing Closure //이렇게도 사용할 수 있다! A() { () -> () in B() } 공감수 0 댓글수 1 2023. 10. 22.
  • [iOS] designated init, convenience init 은 대체 뭘까?? 아주 간단히 요약하자면, 다음과 같다. 1. designated init(지정 생성자) 초기화에 반드시 필요한 생성자이다. 무조건 designated init이 불려야 객체가 생성된다. 2. convenience init(보조 생성자) 초기화에 반드시 필요하진 않다. 하지만, designated init이 가진 인자가 아닌 다른 인자로 초기화를 하고 싶을 때 사용한다. 그런데 방금 무조건 designated init이 불려야한다고 했기에, 이 생성자 내부에서 반드시 designated init을 불러야 한다. 다음은 인자가 없는 init을 가진 커스텀뷰를 만들고 싶을 때의 예이다. class CustomView: UIView { convenience init() { self.init(frame: .zer.. 공감수 0 댓글수 0 2023. 10. 22.
  • [iOS] NSCoding, 내 마음 속에.. 아니 Data에 저장하고 싶을 때 1. 저장, 불러오기 앱에서 만들었던 객체들을 Data로 저장하고 다시 불러오고 싶은 경우가 있을 것이다. 이런 경우 사용하는 것이 NSCoding 프로토컬이다. 2. Encode와 Decode NSCoding 프로토컬을 보면 Data로 저장할 때 쓰는 encoding과, Data에서 불러올 때 쓰는 init? method가 있다. 사용법은 필요한 타입에 이 프로토컬을 상속받아 사용하면 된다. 3. 기본 사용 예제 class Shape : NSObject, NSCoding { private var identifier : String ...생략... func encode(with aCoder: NSCoder) { aCoder.encode(identifier, forKey: "identifier") } re.. 공감수 0 댓글수 0 2023. 10. 22.
  • [iOS] required init?(coder: NSCoder) 이게 뭔데 자꾸 만들어줘 1. 뭔데 이건 항상 UIView를 상속받고, 쓰려고 하면 다음과 같이 required init?(coder: NSCoder)를 만들어준다. class CustomView: UIView { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } 이게 대체 뭐고 왜 필요한지 알아보자. 2. NSCoder? 알기 위해선, 인자로 받고 있는 NSCoder이 무엇인지 먼저 알아야할 필요가 있다. 2023.10.22 - [IOS] - [iOS] NSCoding, 내 마음 속에.. 아니 Data에 저장하고 싶을 때 [iOS] NSCoding, 내 마음 속에.. 아니 Data에 저장하고 싶을 때 1. 저장, 불러오.. 공감수 0 댓글수 0 2023. 10. 22.
  • [iOS, UIKit] UIView는 인자없이 초기화가 가능한데, 왜 UIView를 상속받으면 인자없이 초기화가 안될까? 1. 문제 상황 작업중 UIView를 상속받은 커스텀 뷰를 만드는 과정에서 super.init()을 호출할 경우 오류가 발생하여 UIView()는 어떤 이니셜라이저를 호출하는지 의문이 생겨 찾아보았다. class customView: UIView { init() { super.ini() //여기서 에러가 발생함. UIView는 UIView() 이렇게 초기화를 할 수 있었는데 대체 왜지?? } } 2. 혹시 UIView에 convenience init()이 있나? 구글링을 해보니 어느 블로그에서는 UIView()가 NSObject의 init()을 호출한다고 하였다. 그런데 아래와 같은 근거로, 이렇게 동작하지는 않는다고 판단하였다. superclass(NSObject)에서 subclass(UIView)의 .. 공감수 0 댓글수 1 2023. 10. 22.
  • [Swift] 프로퍼티 래퍼(Property Wrapper), 대체 어떻게 쓰는거지?? 다음과 같이 종종 '@'가 붙은 코드들을 볼 수 있다. class A { @Published a: String } 각설하고, 바로 알아보자. 1. 해당 프로퍼티에 접근할 때마다, 수행할 동작을 우리가 원하는 대로 커스텀 할 수 있다. 이렇게만 이야기하면 감이 잡히지 않으니 예시와 함께 보자. 2. 예시 a라는 속성에 어떤 수를 넣더라도 1이라는 숫자가 들어가게 하고 싶을 경우, 다음과 같은 프로퍼티 래퍼를 만들 수 있다. struct OnlySet1 { private (set) var a: Int var wrappedA: Int { get { return value } set { a = 1 } } init(initialA: Int) { self.a = 1 } } 이제 이 프로퍼티 래퍼를 사용하면, str.. 공감수 0 댓글수 0 2023. 10. 22.
  • [iOS] 어디서 문제가 생긴걸까?? Log를 찍어보자. guard let a = b else { return } 이런 코드의 경우 옵저버 바인딩에 실패한다면 어디서 오류가 발생하였는지 알기 힘들다. 그래서 return 전에 log를 찍어, 값을 추적해줄 필요가 있다. 1. os_log import OSLog os_log("에러 발생") 그런데 이를 쓰려면 모든 파일에 import OSLog 를 하여야한다. 따로 객체로 분리해주는 편이 좋을 것이다. 2. Logger : 에러 발생 부분 바로 알 수 있는 방법 OSLog에서 제공하는 logger 객체를 활용해보자. enum Log { func make() -> Logger { return Logger() } } logger 객체는 logger 객체가 생성된 부분에서의 위치로 이동해준다. guard let tit.. 공감수 0 댓글수 0 2023. 10. 5.
  • [Git] 추가하고 싶지 않은 파일이 있다면? gitignore! ⚠️ MAC 환경 기준으로 설명합니다. .DS_Store와 같은 원치 않은 파일들이 계속 git에 올라갈 때가 있다. 또, 딱히 올리고 싶지 않은 파일들도 함께 올라가는 경우가 종종 있다. 이 문제를 해결하기 위해, gitignore을 활용해보자. 1. 먼저 .gitignore 파일을 생성해준다. git을 사용하고 있는 최상단 폴더로 들어가서, command + shift + . 을 누르면 해당 파일이 생성된다. 2. 기본적으로 필요없는 파일들을 구성해주자 직접 gitignore 파일을 만들 수도 있으나, 아래 사이트를 활용하면 기본적으로 필요없는 파일을 제외시켜준다. https://www.toptal.com/developers/gitignore 다음과 같이 설정한 후, 뜨는 결과를 그대로 복사해서 1에.. 공감수 0 댓글수 0 2023. 10. 5.
  • [iOS] struct도 encoding을 해야한다. 1. 문제 상황 1-1) shape 객체를 아카이빙하려고 하였다. class Shape : NSObject, NSCoding { private var identifier : String private var point : Point private var size : Size } 1-2) 그런데 encode이 매번 실패하였다. 디버거로 확인해보니, 내가 만든 struct 타입에서 encode를 실패하는 것을 확인할 수 있었다. func encode(with aCoder: NSCoder) { aCoder.encode(identifier, forKey: "identifier") aCoder.encode(point, forKey: "point") // 실패 aCoder.encode(size, forKey: "s.. 공감수 0 댓글수 0 2023. 10. 1.
  • [iOS] 가로모드만 지원하도록 설정하는 방법 Portrait, UpsideDown 체크표시를 해제하면 앱을 가로모드로만 실행하도록 할 수 있다. + 아이패드 환경에선 멀티태스킹 모드를 지원하도록 설정한 경우 강제로 가로/세로 전환을 하지 못하도록 막았다고 함.. 참고한 블로그 https://jinsangjin.tistory.com/158 아이패드(iPad) 기능 지원 삽질기 (to 기존 앱) 기조 상용중인 앱에 아이패드 모드를 지원하게 되었습니다. 관련 작업을 하면서 새롭게 배운점과 느낀점들을 정리해보겠습니다. 1. frame 보다는 Auto-layout을 사용하자. 앱을 보면 팝업, 커스텀 키 jinsangjin.tistory.com 공감수 0 댓글수 0 2023. 9. 25.
  • [iOS] multiple scene 설정하기 1. TARGETS - General - Deployment Info - Supports multiple windows 으로 들어가기 2. Enable Multiple Windows Yes로 변경 3. 이제 아이패드 환경에서 여러 개를 띄워 사용 가능 공감수 0 댓글수 0 2023. 9. 21.
  • [iOS] CollectionView Xib 파일 생성하여 Custom Cell로 구현하기 1. Collection view 생성 2. Custom Cell에 대한 class 생성 3. Xib 파일 생성 4. File's Owner, Custom Class 란에 방금 생성한 custom cell의 class 입력 5. 재사용 식별자 등록(여기선 "cell" 로 등록, 원하는 아무 문자로 설정해도 됨) 6. 재사용할 형태로 만들고, 추가한 요소들 IBOutlet 연결 7. collectionView를 사용하는 class 내부 didLoad 밑에 custom cell의 class 이름(여기선 CardCollectionViewCell), 재사용 식별자(여기선 cell) 넣어서 얻은 nib name 으로 collectionView.register 등록 override func viewDidLoad().. 공감수 0 댓글수 0 2023. 9. 5.
  • [Swift, XCTest] XCTest에서 테스트할 모듈 import 해주기 이렇게 해당 모듈 안에 제대로 Unit Test bundle을 만들었는데, 만들기만 하고 아무런 처리를 안해준다면 위에서처럼 모듈 안에 있는 class나 struct 등.. 을 인식하지 못한다. 이런 경우 위에와 같이 @testable import 모듈명 을 추가해주어야한다. 혹은 테스트하고자하는 타입이 선언된 swift 파일에 가서, 우측란에 Target Membership에서 만든 Test란에 체크표시를 하는 방법도 있다. 공감수 0 댓글수 0 2023. 8. 31.
  • [Swift, XCTest] 프로젝트에 만들었던 unit test bundle 지우기 프로젝트에 Unit Test bundle 을 추가한 뒤에 무언가 문제가 생겨 지우고 싶을 때, 이렇게 지웠더니 깔끔하게 지워지지 않았다. 새로 Unit Test bundle 을 추가하려고 할 때, 계속 이런 경고창이 뜨면서 새롭게 Unit Test bundle 을 생성할 수 없었다.. 이렇게 프로젝트를 클릭하고, general -> TARGETS 란에서 지워야 깔끔하게 지워진다. 이렇게 지웠더니 새롭게 Unit Test bundle을 추가할 수 있다. 공감수 0 댓글수 0 2023. 8. 31.
    문의안내
    • 티스토리
    • 로그인
    • 고객센터

    티스토리는 카카오에서 사랑을 담아 만듭니다.

    © Kakao Corp.