๐ฑ iOS
[Swift] ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ NetworkManager๋ง๋ค๊ธฐ (feat. Generic)
์ง๋๋ฒ์ ์ด๋ฐ ๊ธ์ ์ผ์๋๋ฐ, https://990427.tistory.com/112 [Swift] json value type์ด ๋ฌ๋ผ์ง๋ response์ ๋์ํ์ฌ API Responder๋ง๋ค๊ธฐ ์์ฆ Set์ด ๋ ๋์ ๊ฐ๋ฐ ์คํ์ผ,, ์ค๋ณต์ ๋ค ์ ๊ฑฐํด๋ฒ๋ฆฌ์ ์ง๊ธ ํ๊ณ ์๋ ํ๋ก์ ํธ์์ API๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ช ์ธํ์ต๋๋ค ๊ทธ๋์ ์ด๋ค api๋ฅผ ํธ์ถํ๋์ ๋ฐ๋ผ form์ ๋ณํ๋ ์์ง๋ง data์ ๊ฐ์ ํญ์ 990427.tistory.com ์ํ ์ฝ๋๋ฅผ ๋ฐ์ ์ ์๋ค๋ ๋ฌธ์ ์ ๋ ์์๊ณ , ๋ชจ๋๋ง๋ค ๋ค ๋ค๋ฅธ MoyaProvider๋ฅผ ์ฌ์ฉํ๋ค๋ณด๋๊น ์ ๋ฒ์ ๋ง๋ ํจ์์ ์ฐ์์ด ์ข.. ๋ณ๋ก๋๊น? ๊ทธ๋์ ๊ฐ์ ํด๋ณด์!๊ณ ์๊ฐํ๊ณ ์กฐ๊ธ๋ ์ ์ฐํ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก BaseNetworkManager๋ฅผ ๋ง๋ค๊ธฐ๋ก ํ์ต๋๋ค. Ba..
[UIKit] CustomDatePicker ๋ง๋ค๊ธฐ (3/3)
Rx๋ฅผ ๋ชจ๋ฅด์ ๋ค๋ฉด ์ดํดํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค ๐ฅน ๋๋์ด ๋ง์ง๋ง ๊ด๋ฌธ.. ๋ ,์์ ๊ด์ฐฐํ์ฌ ์ผ ์๋ฅผ ์ ํ์! ์ผ๋จ ๋๋ ์ง๊ธ ์ด๊ฑธ ๋ง๋๋ ์ค์ด๋ค ๋ ,์์ ์์กด์ฑ์ด ์์ง๋ง, '์ผ'์ ๋ ,์์ ์์กด์ฑ์ ๊ฐ์ง๊ฒ ๋๋ค. 1์์ 31์ผ๊น์ง, 2์์ 28์ผ๊น์ง ๋ญ์ด๋ฐ๊ฑฐ ~.. ๊ทธ๋์ '์ผ'์ ๋ ,์์ด ๋ฐ๋๋ฉด reset์ ํด์ฃผ์ด์ผ ํ๋ค. ์๋ฅผ๋ค์ด 2023๋ 1์31์ผ์ ๋ง๋ค์ด์ค ์ํ์์ '์'์ 2์๋ก ๋ฐ๊พธ๋ฉด 31์ผ์ ์๊ธฐ ๋๋ฌธ์!! ๊ทธ๋์ customPicker์์ ๋ญ๊ฐ๋ฅผ ์ ํํ์ ๋ ๊ด์ฐฐํ๋ ๋์์๊ฒ ์๋ ค์ค ์ ์๋๋ก Rx๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์ ์ฉํ๋ค. (1/3)์์ ๋ง๋ค์๋ CustomPickerButton์ ์ถ๊ฐํ ๋ถ๋ถ! public class CustomPickerButton: UIButton { var change..
[Swift] ์๋ฒ์ iOS ์ด๋ฏธ์ง ๋ณด๋ผ ๋ ์ฉ๋ ์ด์ & ํด๊ฒฐ
์ด๋ฏธ์ง ์ ๋ก๋ ๊ตฌํ์ค์ ์๊ธด ์ด์ form-data๋ก ์์ดํฐ ์ฌ์ง์ฒฉ์ ์๋ ์ด๋ฏธ์ง๋ฅผ ์๋ฒ๋ก ๋ณด๋ด๋ ค๋ฉด JPEG๋ก ๋ณํํด์ผ ํฉ๋๋ค ์์ดํฐ์์ ๊ธฐ๋ณธ์ ์ผ๋ก HEIF ํ์ฅ์๋ก ์ฌ์ง์ ์ ์ฅํ๋๋ฐ, ์ด๋ ํธํ์ฑ์ด ๋จ์ด์ง๊ธฐ ๋๋ฌธ์ ๋๋ค ์ด์จ๋ ์ฐ๋ฆฌ๋ PHPicker๋ฅผ ํตํด์ ์ฌ์ง์ฒฉ์ ์๋ ์ฌ์ง์ ๊ฐ์ ธ์ฌ ์ ์๊ณ , ์ด๋ฅผ jpeg๋ก ๋ณํํ๊ธฐ ์ํด jpegData๋ฅผ ์ฌ์ฉํฉ๋๋ค image.jpegData(compressionQuality: 1.0) ์ฌ์ค ๋ค์ 1.0์ ๊ธฐ๋ณธ๊ฐ์ด๋ผ๊ณ ์๊ฐํ๊ณ ์๋ฌด ์๊ฐ์์ด ์ผ๋๋ฐ ์๋๋งค ์ด์๊ฐ ์๊ธธ์ค์ด์ผ... Moya๋ฅผ ํตํด API ํต์ ์ ํ๋๋ฐ, ๊ณ์ ์ด๋ฐ ์๋ฌ๊ฐ ๋จ๋ ๊ฒ.. Failed to map data to a Decodable object. postman์ผ๋ก ์์ดํฐ ์ฌ์ง์ฒฉ์ ์๋ ์ฌ์ง ..
[UIKit] toast message ๋ง๋ค๊ธฐ
์ฑ์ ๋ง๋ค๋ค๋ณด๋ฉด toast msg๋ฅผ ๋์์ ์ ๋ณด๋ฅผ ์ฃผ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ ์์ฝ๊ฒ๋ iOS์๋ ๊ทธ๋ฐ ๊ธฐ๋ฅ์ด ์๋ค.. ์ง์ ๋ง๋ค์! ์ฐ์ UIView๋ฅผ ์์ํ๋ class๋ฅผ ๋ง๋ค์ด ์ค๋๋ค public class ToastMessage: UIView {} ์ ๋ ์๋ก ์ข ๋ฅ์ ํ ์คํธ ๋ฉ์ธ์ง๋ฅผ ๋ง๋ค๊ฑฐ์์ (x๋ ์ ์ธ) ๊ทธ๋์ ์ด๋ฐ ํ๋กํผํฐ์ enum์ด ํ์ํฉ๋๋ค public enum ToastType { case common, alert, info } var text = UILabel() var icon = UIImageView() var type : ToastType UI๋ ๊ฐ์ ์ทจํฅ๊ป ๋ง๋์๊ณ (์๋ต) ํ ์คํธ ๋ฉ์ธ์ง์ ํน์ง์ ์ ๊น ๋ด๋ค ์ฌ๋ผ์ง๋๊ฑฐ ์์์ ? ๊ทธ ๋ถ๋ถ์ ๊ตฌํํ๊ธฐ ์ํด animate๋ฅผ ์ฌ์ฉํ์ต๋๋ค an..
[Swift] json value type์ด ๋ฌ๋ผ์ง๋ response์ ๋์ํ์ฌ API Responder๋ง๋ค๊ธฐ
์์ฆ Set์ด ๋ ๋์ ๊ฐ๋ฐ ์คํ์ผ,, ์ค๋ณต์ ๋ค ์ ๊ฑฐํด๋ฒ๋ฆฌ์ ์ง๊ธ ํ๊ณ ์๋ ํ๋ก์ ํธ์์ API๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ช ์ธํ์ต๋๋ค ๊ทธ๋์ ์ด๋ค api๋ฅผ ํธ์ถํ๋์ ๋ฐ๋ผ form์ ๋ณํ๋ ์์ง๋ง data์ ๊ฐ์ ํญ์ ๋ฌ๋ผ์ง๋ค ์ผ๋จ json์ ํ์ฑํ struct๋ฅผ ๋ง๋ค์ด์ฃผ์ด์ผ ํ๋๋ฐ, ๋ชจ๋ api๋ง๋ค struct๋ฅผ ๋ง๋ค๊ฒ ๋๋ฉด ์ด๋ฐ์์ผ๋ก ๊ณ์ํด์ DTO struct์ ์ค๋ณต์ด ์ผ์ด๋๊ฒ ๋๋ค ์ค๋ณต์ด ๋๋ฌด ์ซ์ ๋.. ์ ๋ค๋ฆญ์ผ๋ก ๋ฌถ์! struct ResponseDTO : Decodable { var success : Bool var data : CommonDataDTO var error : ErrorDTO? } struct ErrorDTO : Decodable, Error { let code : Int let mes..
[RxSwift] ๊ฐ๋ ์ก๊ธฐ (Subscribe, Observable, Subject)
์ต๋ํ ๊ฐ๋จํ๊ฒ ์ค๋ช ํด๋ณด๋ RxSwift iOS ๊ณต๋ถํ๋ ์ฌ๋์ ๋ฌด์กฐ๊ฑด ๋ค์ด๋ดค์ RxSwift RxSwift๋ ReactiveX Swift์ธ๋ฐ์, reactiveX ? ๋์ถฉ ํด์ํ๋ฉด ์ต์ ๋ฒ๋ธ์ ์ฌ์ฉํด์ ๋น๋๊ธฐ๋ event-based๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒ์ด๋ค ์ต์ ๋ฒ๋ธ์ด ๋ญ๋ฐ ????? Observable ? ๋์ถฉ ํด์ํ๋ฉด - ์ต์ ๋ฒ๋ ์ต์ ๋ฒ๋ธ์ ๊ตฌ๋ ํ๋ค - ์ต์ ๋ฒ๋ ์ต์ ๋ฒ๋ธ์ด ๋ฐฉ์ถํ๋ items์ ๋ํด ๋ฐ์ํ๋ค - ์ต์ ๋ฒ๋ ๋๊ธฐํ์ง ์๊ณ , ๋ฐ์ํ ์ค๋น๋ฅผ ํ ์ด๋ ํ ํํ๋ก ๊ธฐ๋ค๋ฆฐ๋ค items์ด ์ด๋ค๊ฑด์ง๋ ๋ชฐ๋ผ๋ ์ผ๋จ ์ต์ ๋ฒ๋ ์ต์ ๋ฒ๋ธ์ด ๋ญ๊ฐ๋ฅผ ํ๋ฉด ๋ฐ์ํ๋!! ์ต์ ๋ฒ๊ฐ ๋ฌด์จ ํํ์ธ์ง๋ ๋ชฐ๋ผ๋ ์ผ๋จ ๋๊ธฐ ใดใด ์ฆ, sync ใดใด ๋ง์ ์ฉ์ด๋ค์ด ๋์ค๋๋ฐ Observer, Observable, Subscribe ๊ทผ๋ฐ ์ด..
[Swift] Custom Calendar ๋ฌ์ ๋ง์ง๋ง ๋ ๊ตฌํ๊ธฐ
์ด ๊ธ์ UI๋ฅผ ์ ์ธํ๊ณ ๋ ์ง ๊ณ์ฐ์ ํ๋ ๋ก์ง๋ง ๋ด๊ณ ์์ต๋๋ค Custom Calendar๋ฅผ ๋ง๋ค๋ค๋ณด๋ ํด๋นํ๋ ๋ฌ์ ๋ง์ง๋ง ๋ ์ด ์ธ์ ์ธ์ง ๊ณ์ฐํด์ผ ํ๋ค. ์๊ณ ๋ฆฌ์ฆ ์ฒ๋ผ ์ ๊ทผํ๋ฉด ์ค ๋ฌ๋ ๊ณ์ฐํด์ค์ผ ํ๊ณ ์๋ ์ธก๋ฉด์์๋ ๋นํจ์จ์ ์ด๋ผ๊ณ ์๊ฐํด์ foundation์์ ์๋ calendar๋ผ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค์๋ค! ๋จผ์ ๋ ์ง ๊ณ์ฐ์ ํ์ํ Calendar์ DateFormatter๋ฅผ ๋ง๋ค์ด์ฃผ์ let calendar = Calendar(identifier: .gregorian) let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" ์ฒซ ๋ ์ ๋ฌด์กฐ๊ฑด 1์ผ์ด๋๊น ์ง์ ์ ๋ ฅํด์ค๋ค let st = dateFormatter.da..
[UIKit] CustomDatePicker ๋ง๋ค๊ธฐ (2/3)
CustomPickerButton์ ๋ง๋ค์์ผ๋ DatePicker๋ก ์งํํด๋ณด์ ์๋ค์ํผ ๋๋ ์ด๊ฑธ ๋ง๋ค๊ธฐ๋ก ํ๋ค ๐ UI setting ๋ณ๊ฑฐ ์๋ค.. ๊ทธ๋ฅ ในใ UI setting code open class CustomDatePicker: UIView{ private var Titlelabel = UILabel() private var years = [String]() private var months = [String]() private var days = [String]() private let yearWidth : CGFloat = 126 private let monthWidth : CGFloat = 103 private let dayWidth : CGFloat = 103 private lazy ..
[UIKit] CustomDatePicker ๋ง๋ค๊ธฐ (1/3)
UIKit ๊ณต๋ถ๊ฒธ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ ๋์ค์ DatePicker๋ฅผ ์ปค์คํ ํด์ผ ํ๋ ์ํฉ๊ณผ ๋ง์ฃผํ๋ค. ๐ ๊ตฌํ๋ด์ฉ ์ผ๋จ ๊ธฐ๋ณธ ์ ๊ณต๋๋ DatePicker๋ฅผ ์ฌ์ฉํ ์๋ ์์๋ค ๊ทธ๋์ UIButton์ inputView์ pickerView๋ฅผ ๋ฃ์ด์ ๋ง๋ค๊ฒ์ด๋ค ์ผ๋ฐ์ ์ผ๋ก TextField์ inputView์ pickerView๋ฅผ ์ฌ์ฉํ๋๋ฐ ๋๋ TextField๊ฐ ํ์์์ด์ ๋์ฅ์ ์ ๊ฑธ์ด๋ณด๊ธฐ๋ก ํ๋ค.. ๐ UI setting ์์ ์ธ๊ธํ๋ CustomDatePicker์์ box ํ๋์ฉ์ CustomPickerButton์ด๋ผ๊ณ ํ๊ฒ ๋ค. // CustomPickerButton.swift public class CustomPickerButton: UIButton { private var uiView = UIV..
[SwiftUI] @State๋ฅผ ๊ฐ์ง๋ View์ ์ ๋ฐ์ดํธ
์ค๋์ @State์ ๋ํด์ ์กฐ๊ธ ๋ ๊น์ด ์๊ฒ ์์๋ณด๋ ค๊ณ ํด์! ์ผ๋จ @State๊ฐ ์ด๋ค ์ญํ ์ ํ๋์ง ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผํ๊ณ ์์ฃผ ๊ฐ๋จํ ์์ ๋ฅผ ๋ณผ๊ฒ์, ๋ชจ๋ฅด๋ฉด ์ด๊ฑฐ ๋ณด๊ณ ์ค๊ธฐ https://990427.tistory.com/64 [SwiftUI] ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ (1/5) @State ๋ฐ์ดํฐ๋ฐ์ธ๋ฉ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ(data binding)์ ์ ๊ณต์์ ์๋น์๋ก๋ถํฐ ๋ฐ์ดํฐ ์๋ณธ์ ๊ฒฐํฉ์์ผ ์ด๊ฒ๋ค์ ๋๊ธฐํํ๋ ๊ธฐ๋ฒ์ด๋ค. ๋ผ๊ณ ์ํค๋ฐฑ๊ณผ๊ฐ ๋งํ๋๋ฐ, ์ฝ๊ฒ๋งํด SwiftUI์์ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ view 990427.tistory.com ์๋ ์ฝ๋๋ changeItem ๋ฒํผ์ ๋๋ฌ text ๊ฐ์ ๋ณ๊ฒฝ์ํค๋ ์์ ์ ๋๋ค struct ContentView : View { @State var text = "default" va..