일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 프로그래머스
- Python3
- JS
- 토플
- 파이썬웹크롤링
- 리프2기
- 인프런강의
- 인프런오리지널
- nodeJS
- swift
- 노드JS
- 유학토플
- 인프런
- IOS프로그래밍
- 파이썬중급
- 토플공부수기
- 파이썬중급강의
- 자바스크립트
- 교환학생토플
- 파이썬
- 인프런파이썬
- SwiftUI
- 웹크롤링
- rxswift
- 우리를위한프로그래밍
- 인프런파이썬강의
- IOS
- uikit
- 스위프트
- 카카오톡채팅봇
- Today
- Total
목록swift (36)
먹고 기도하고 코딩하라
이번에 회사 앱 위젯 개선 작업을 했다. 위젯 작업은 원래 다른 분께서 하시던 작업이었으나, 그 분께는 다른 메인 작업이 있어 작업을 가져왔다.WidgetKit과 SwiftUI로 레이아웃을 만드는 방법만 안다면 위젯은 그렇게 어려운 작업은 아니다. 다만 이번에 오프라인 모드에서 이미지를 가져오는 작업이 조금 까다로웠어서 포스팅한다. 문제오프라인 모드에서는 기기에 저장된 이미지 path를 불러와서 썸네일을 보여줘야 한다.그런데, path가 정확하고(documents) 이미지도 실재하는데 위젯에 표현이 안 된다.원인WidgetKit은 경량화 app extension이다. WidgetKit에서는 로컬에 저장된 파일들을 마음대로 접근할 수 없다.그러니까 실제로 Documents 디렉터리에 저장이 돼 있어도 읽..
이번에 회사 앱이 iOS 15.0을 minimum deployment로 올리게 되었다. 여러 가지 이유가 있는데, 이유 중 하나는 StoreKit1이 iOS 18.0 이상 버전에서 deprecated된다는 사실이었다. Original API for In-App Purchase | Apple Developer DocumentationOffer additional content and services in your app using the Original In-App Purchase API.developer.apple.com 대신 Swift 기반의 IAP 방식을 사용해서 인앱 결제를 구현하도록 권유하고 있다. In-App Purchase | Apple Developer DocumentationOffer co..
UICollectionViewFlowLayout에는 prepare() 메소드와 layoutAttributesForElement(in rect: CGRect) → [UICollectionViewLayoutAttributes]? 라는 메소드가 있어 이것을 오버라이드할 수 있다.prepare : 현재 레이아웃을 업데이트하도록 레이아웃 객체에게 지시레이아웃 업데이트는 콜렉션뷰가 처음 콘텐츠를 보여줄 때와 뷰 변경으로 인해 레이아웃이 명시/암시적으로 유효성을 잃을 때 발생매 레이아웃 업데이트 동안 콜렉션뷰는 prepare()을 먼저 호출해 레이아웃 객체에게 다음 레이아웃 수행을 위한 준비를 하도록 함layoutAttributesForElement : 특정 직사각형 영역 내의 모든 셀과 뷰의 레이아웃 attrib..
원래 비동기 작업 처리에 RxSwift를 주로 이용해서 앱을 만들었는데, 올해부터는 Swift Concurrency를 주로 사용해서 비동기 작업을 하고 있다. 개인적으로 Combine은 기존에 RxCocoa를 사용하던 UI 작업이나 비동기 작업 결과를 가공하는 데에 쓰기 좋고, async-await은 통신 작업과 같이 비동기 작업에서의 RxSwift를 대체하는 느낌이 강하다고 생각한다.하반기 시작하면서 회사 앱에도 Swift Concurrency를 도입해서 기존 컴플리션 핸들러(!)를 사용해서 깊은 depth를 가진 코드를 변경하고자 통신부를 async-await 사용할 수 있도록 감싸는 작업을 했다. 기존 통신 로직은 이랬다.Requester를 만든다. 필요한 헤더, 베이스 URL, 쿼리, 바디 등은 ..
결론만 먼저 쓰자면, metatype이 되는 그 클래스의 init에 required를 붙여주면 해결되는 문제다.그런데 왜 그래야 할까? 이유는 맥락과 차근차근 설명하는 걸로~ 기존에 쓰던 통신 코드를 async-await처럼 사용할 수 있을까 고민하다가 기존 Requester 객체에서 complete 컴플리션 핸들러와 failed 컴플리션 핸들러를 continuation resume하는 것으로 변경하면 되겠다는 생각에 그렇게 수정했다. (추후 포스팅 예정)통신에 앞서, 먼저 필요한 옵션을 생성하도록 되어 있다. 이 옵션은 프로토콜을 준수한 구체 클래스를 생성해서 집어넣는다. 엔드포인트, 쿼리, 바디 등 여러 가지 옵션을 포함한다. 그런데 엔드포인트만 지정하는 기본 옵션이라면 API 클래스마다 이 옵션까지..
무지 기본적인 것에 무지한 관계로.. 뷰를 업데이트하는 레이아웃 메소드를 살펴본다. 뷰 레이아웃이 어떻게 이뤄지는지 알기 위해서는 일단 런루프를 조금 알아보는 게 좋겠다. 런루프 swift에는 런루프(run loop)라는 게 있다. 런루프는 Event-driven 프로그래밍에서 사용된다. 조금 추상적인 개념이지만 어떤 이벤트를 대기하면서 스레드를 좀 놀려놨다가 이벤트가 생기면 스레드에게 그것을 처리하게끔 시키는 스레드 관리 시스템이라고 보면 이해가 쉬울 것 같다. (polling이 아니라 notification을 기다리는 느낌이랄까) 그리고 메인 스레드에서 실행되는 런루프를 메인 런루프라고 부른다. 메인 런루프가 하는 주된 일은 앱 라이프사이클 주기 동안 계속 사용자 이벤트를 대기하고, 이벤트가 발생하면..
작업할 때 옵저버블을 관찰하는 스케줄러를 다른 스케줄러로 돌릴 때가 있다. .subscribe의 onNext에서 UI 변경 작업을 해줘야 할 때 메인으로 바꿔준다든가 할 때는 거의 .observe(on:)을 사용하곤 했다. .subscribe(on:)과 확실한 차이점은 어떤 것이 있어서 .observe(on:)을 썼을까 하면, 명쾌하게 이야기하기 힘들었다. 자주 쓰는 것이 아니면 잊어버리다 보니 이번 기회에 정리하고자 한다. 빠른 정리 1. .subscribe(on:) : Observable이 생성되는 스케줄러 변경 2. .observe(on:) : Observable을 구독하는, ObserverType의 스케줄러 변경 .subscribe(on:) - 생성 스케줄러 변경 .subscribe(on:)은 O..
최근에 새로운 사이드 프로젝트와 겸해서 다른 작은 프로젝트를 만들었는데, 다 만들고 나니 아차 싶었던 게 꽤 많이 보인다. 이래서 프로젝트엔 완성이 없고 방망이 깎듯이 계속 다듬고 깎아나가야 하는 듯하다. 불과 며칠 전에 한 프로젝트인데도 다시 리뷰하는데 아쉽다. 가장 아쉬운 것은 중복 값을 담지 않는 시퀀스를 담는 것으로 Array를 사용한 것이다. 거기다가 검색하는 데에 .contains를 사용했으니, 시간복잡도는 O(n)이 무조건 나오게 된다. (Array 특성상 contains를 하면 타겟 값을 찾아낼 때까지 모든 요소와 비교하기 때문에) Set을 썼다면 좋았을 텐데, 그거 고치는 거 얼마 걸리지도 않는데... 싶어 아쉬워하다가 오늘은 즉흥적으로 Set contains 시간복잡도가 왜 O(1)인지..