iOS/Swift

    [iOS] Firebase Cloud Messaging - APN

    ๊ธฐ๋ก์šฉ 1. firebase project ๋งŒ๋“ค๊ธฐ https://console.firebase.google.com/u/3/?hl=ko 2. iOS ์•ฑ ์ถ”๊ฐ€ํ•˜๊ธฐ iOS๋ฅผ ๋ˆŒ๋Ÿฌ ์•ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค ๊ทธ๋Ÿฌ๋ฉด ์•ฑ ๋“ฑ๋ก ํ™”๋ฉด์ด ๋‚˜์˜ค๋Š”๋ฐ ์ด๋•Œ Apple ๋ฒˆ๋“ค ID๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•จ ์š”๊ฑด ์–ด๋Š ๊ฒƒ์ด๋ƒ๋ฉด ์˜ค๋ฅธ์ชฝ ์—‘์Šค์ฝ”๋“œ ์ฐฝ์—์„œ!! Signing & Capabilities ์•ˆ์— ์žˆ๋Š” Bundle Identifier ์ž…๋‹ˆ๋‹ค ๋‚˜๋จธ์ง€ ์•ฑ ๋‹‰๋„ค์ž„, App Store ID๋Š” ์„ ํƒ์‚ฌํ•ญ์ด๋‹ˆ ํŒจ์Šคํ• ๊ฒŒ์š” ๊ทธ๋Ÿฌ๋ฉด 2๋ฒˆ ๋‹จ๊ณ„ ๊ตฌ์„ฑ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ๊ฐ€ ๋‚˜์˜ค๊ณ , GoogleService-Info.plist ๋‹ค์šด๋กœ๋“œ ๋ฐ›์•„์„œ Xcode ํ”„๋กœ์ ํŠธ ์•ˆ์— ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š” ์ €๋Š” ์œ„ ์‚ฌ์ง„์ฒ˜๋Ÿผ Plists๋ผ๋Š” ํด๋”๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด ์—ฌ๊ธฐ์— Info.plist์™€ ํ•จ๊ป˜ ๋„ฃ์–ด ๋‘..

    [RxSwift] ARC, ๊ฐ•ํ•œ ์ฐธ์กฐ strong, ์•ฝํ•œ ์ฐธ์กฐ weak, ๊ฐ•ํ•œ ์ฐธ์กฐ ์ˆœํ™˜ ๋ฌธ์ œ

    Struct vs Class Struct ํƒ€์ž…๊ณผ Class ํƒ€์ž…์„ ๋น„๊ตํ•  ๋•Œ ๊ฐ€์žฅ ๋งŽ์ด ํ•˜๋Š” ๋ง โ†’ Struct๋Š” ๊ฐ’ ํƒ€์ž…, Class๋Š” ์ฐธ์กฐ ํƒ€์ž…! ๊ฐ’ ํƒ€์ž…: ์ „๋‹ฌํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ’์„ ๋ณต์‚ฌํ•ด์„œ ์ „๋‹ฌ ์ฐธ์กฐ ํƒ€์ž…: ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ฐธ์กฐ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์ ‘๊ทผ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ ์ ˆํ•œ ์‹œ์ ์— ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋˜์ง€ ์•Š์œผ๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์ž์›์„ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋จ. โ†’ ์Šค์œ„ํ”„ํŠธ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ARC๋ฅผ ์‚ฌ์šฉ! ARC์˜ ์ž‘๋™ ๊ทœ์น™์„ ๋ชจ๋ฅด๊ณ  ์‚ฌ์šฉํ•˜๋ฉด ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์˜์›ํžˆ ํ•ด์ œ๋˜์ง€ ์•Š์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—... ARC์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•œ๋‹ค. ARC * ์ž๋™ ์ฐธ์กฐ ์นด์šดํŒ…, Automatic Reference Counting => ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•ด ์ฃผ๋Š” ๋ฐฉ์‹ * ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์€ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์—์„œ..

    [RxSwift] Subject, .scan, RxCocoa, .bind ๊ฐœ๋…

    ๊ณฐํŠ€๊น€ ๋‹˜์˜ RxSwift 4์‹œ๊ฐ„์— ๋๋‚ด๊ธฐ (์ข…ํ•ฉํŽธ) ์˜์ƒ์„ ๋ณด๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ^~^ https://youtu.be/w5Qmie-GbiA ์ •๋ง ์ƒ์ดˆ๋ณด,, ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๋Š” ์ž…์žฅ์—์„œ ๊ฐ•์˜ ์˜์ƒ์„ ๋ณด๊ณ  ์˜์‹์˜ ํ๋ฆ„๋Œ€๋กœ ์ž‘์„ฑํ•œ ๊ธ€์ด๋‹ˆ ๋น„ํŒ์˜ ๋ˆˆ์œผ๋กœ ๊ธ€์„ ์ฝ์–ด ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค~~ ์˜ค๋ฅ˜ ์ง€์  ๋Œ€ํ™˜์˜! Subject Observable ๋ฐ–์—์„œ ๊ฐ’์„ ๋ฐ›์•„ ์™€์„œ ์ปจํŠธ๋กคํ•  ์ˆ˜ ์žˆ์Œ ์ข…๋ฅ˜ 4๊ฐœ(docs ์ฐธ๊ณ ) AsyncSubject Subcribe๊ฐ€ ์•„๋ฌด๋ฆฌ ๋งŽ์ด ๋“ค์–ด์™€๋„ Complete ์‹œ์ ์— ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰ ๋ฐ์ดํ„ฐ๋งŒ ๋ชจ๋‘์—๊ฒŒ ๋‚ด๋ ค ์คŒ BehaviorSubject ๊ธฐ๋ณธ๊ฐ’ ํ•˜๋‚˜ ๊ฐ€์ง€๊ณ  ์‹œ์ž‘, ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ Subscribeํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋‚ด๋ ค ์คŒ ์ค‘๊ฐ„์— ์ƒˆ๋กญ๊ฒŒ Subscirbe๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์˜ ๊ฐ’์„ ๋‚ด๋ ค ์คŒ ..

    [RxSwift] Observable์˜ ์ƒ๋ช… ์ฃผ๊ธฐ, ์ˆœํ™˜ ์ฐธ์กฐ์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ, subscribeOn, observeOn

    ์ •๋ง ์ƒ์ดˆ๋ณด,, ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๋Š” ์ž…์žฅ์—์„œ ๊ฐ•์˜ ์˜์ƒ์„ ๋ณด๊ณ  ์˜์‹์˜ ํ๋ฆ„๋Œ€๋กœ ์ž‘์„ฑํ•œ ๊ธ€์ด๋‹ˆ ๋น„ํŒ์˜ ๋ˆˆ์œผ๋กœ ๊ธ€์„ ์ฝ์–ด ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค~~ ์˜ค๋ฅ˜ ์ง€์  ๋Œ€ํ™˜์˜! Observable Life-Cycle 1. Create Observable ์ƒ์„ฑ ๋ฐ์ดํ„ฐ๊ฐ€ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜, ์–ด๋–ค ๋ช…๋ น์ด ๋™์ž‘ํ•˜์ง€ ์•Š์Œ โ†’ 2. Subscribe์—์„œ ๋™์ž‘! 2. Subscribe ์–ด๋– ํ•œ Observable์ด ๋™์ž‘ํ•จ 3. Next ๋ฐ์ดํ„ฐ ์ „๋‹ฌ 4. Completed ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ ๋ 4-1. Error ๋น„์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ ๋ 5. Disposed Dispose๋˜๋ฉด ๊ทธ Observable์€ ๋” ์ด์ƒ ์žฌ์‚ฌ์šฉ ๋ถˆ๊ฐ€ .debug() ๋กœ Observable ์ƒํƒœ ํ™•์ธ ๊ฐ€๋Šฅ ์ˆœํ™˜ ์ฐธ์กฐ์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ .subscribe(onNext: { i in s..

    [RxSwift] ์ด๊ฒŒ ๋งž๋‚˜? ์‹ถ์€ RxSwift ๊ฐœ๋… ์ •๋ฆฌ

    ๊ณฐํŠ€๊น€ ๋‹˜์˜ RxSwift 4์‹œ๊ฐ„์— ๋๋‚ด๊ธฐ (์ข…ํ•ฉํŽธ) ์˜์ƒ์„ ๋ณด๊ณ  ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค ^~^ https://youtu.be/w5Qmie-GbiA ์ •๋ง ์ƒ์ดˆ๋ณด,, ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๋Š” ์ž…์žฅ์—์„œ ๊ฐ•์˜ ์˜์ƒ์„ ๋ณด๊ณ  ์˜์‹์˜ ํ๋ฆ„๋Œ€๋กœ ์ž‘์„ฑํ•œ ๊ธ€์ด๋‹ˆ ๋น„ํŒ์˜ ๋ˆˆ์œผ๋กœ ๊ธ€์„ ์ฝ์–ด ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค~~ ์˜ค๋ฅ˜ ์ง€์  ๋Œ€ํ™˜์˜! [1๊ต์‹œ] ๊ฐœ๋…์žก๊ธฐ - RxSwift๋ฅผ ์‚ฌ์šฉํ•œ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ โœˆ๏ธ Rx์˜ ๋ชฉ์  ๋น„๋™๊ธฐ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๋ฐ์ดํ„ฐ(์–ธ์ œ ๋งŒ๋“ค์–ด์งˆ์ง€ ๋ชจ๋ฆ„)๋ฅผ completion์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๋ฆฌํ„ด ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•˜์—ฌ ์ข€ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ง„ ์œ ํ‹ธ๋ฆฌํ‹ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—… ๋„์ค‘ ์ทจ์†Œ ์‹œ ์œ ์šฉ ๋™๊ธฐ/๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ create, subscribe, disposable // MARK: RxSwift ์›ํ˜• ์‚ฌ์šฉ..

    [Swift] ํƒ€์ž…์บ์ŠคํŒ…, ๋‹ค์šด์บ์ŠคํŒ…, is, as๋ž€?

    Swift์˜ ํƒ€์ž…์บ์ŠคํŒ…์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•„์š”. ๐Ÿ˜Ž ๋จผ์ € ํด๋ž˜์Šค์˜ ์ƒ์† ๊ฐœ๋…๋ถ€ํ„ฐ ์ดํ•ดํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•˜๋Š”๋ฐ...... ์ด๋ ‡๊ฒŒ Coffee, Latte, Americano๋ผ๋Š” ํด๋ž˜์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์šฐ๋ฆฌ๋Š” ๋ผ๋–ผ์™€ ์•„๋ฉ”๋ฆฌ์นด๋…ธ๋ฅผ ๋ฌถ์–ด์„œ ์ปคํ”ผ๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•˜์ฃ !??!? ์ปคํ”ผ๋ผ๋Š” ๊ฐœ๋…์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๋ผ๋–ผ๋Š”, ์—ฌ๊ธฐ์—์„œ๋Š” ์ปคํ”ผ๋ฅผ ์ƒ์†๋ฐ›์•„ ๋ผ๋–ผ๊ฐ€ ํƒ„์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค! ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ปคํ”ผ๋ผ๋Š” ๊ฐœ๋…์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์•„๋ฉ”๋ฆฌ์นด๋…ธ๋„ ์ƒ์„ฑ! ๊ทธ๋Ÿฌ๋ฉด ์ปคํ”ผ๋Š” ๋ถ€๋ชจ Class, ๋ผ๋–ผ์™€ ์•„๋ฉ”๋ฆฌ์นด๋…ธ๋Š” ์ž์‹ Class๊ฐ€ ๋จ๋‹ˆ๋‹ค. '์ปคํ”ผ'๋Š” '์ƒท'์ด๋ผ๋Š” ํ•ญ๋ชฉ์„ ๊ฐ–๊ณ  ์žˆ๊ณ , ์ด๋ฅผ ์ƒ์†๋ฐ›์€ ์ž์‹๋“ค์ธ ๋ผ๋–ผ์™€ ์•„๋ฉ”๋ฆฌ์นด๋…ธ๋„ '์ƒท'์ด๋ผ๋Š” ํ•ญ๋ชฉ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šด๋‹ˆ๋‹ค~~ ์ดˆ๊ฐ„๋‹จ ์ƒ์† ๋—! class Coffee { let shot: Int init(shot: Int) ..

    [Swift] ๋‚ ์งœ๋ฅผ ๋ฌธ์ž๋กœ! Date to String

    func dateToString(_ today: Date) -> String{ let year = Calendar.current.component(.year, from: today) let month = Calendar.current.component(.month, from: today) let day = Calendar.current.component(.day, from: today) let weekdayInt = Calendar.current.component(.weekday, from: today) var weekday: String = "" switch weekdayInt { case 1: weekday = "SUN" case 2: weekday = "MON" case 3: weekday = "T..

    [Swift] ํŠน์ • ๋‚ ์งœ/์‹œ๊ฐ„ DateComponents to Date

    Calendar.current.date(from: DateComponents(year:2021, month: 7, day: 1)) * DateComponents๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ๋ชจ๋‘ ์˜ต์…”๋„์ด๋ผ ์›ํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ๋„ฃ์–ด์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ!

    [๋„คํŠธ์›Œํ‚น] iOS Swift Alamofire ์š”์ฒญ/์‘๋‹ตํ•˜๊ธฐ(form-dataํ˜•์‹)

    ์šฐ๋ฆฌ ์„œ๋ฒ„์— json ํ˜•์‹์œผ๋กœ ํฐ๋ฒˆํ˜ธ ๋„˜๊ฒผ๋”๋‹ˆ ์ž๊พธ ๋ณ€์ˆ˜ ๋ถ€์กฑ ์—๋Ÿฌ ์ฝ”๋“œ ๋œธ -> ์„œ๋ฒ„ํŒ€์— ๋ฌผ์–ด๋ด„ -> ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ ๋ณด๋‚ผ ๋•Œ json ๋ง๊ณ  form-data ํ˜•์‹์œผ๋กœ ๋ณด๋‚ด ๋‹ฌ๋ผ๊ณ  ํ•จ -> ๊ทธ๋Ÿฐ๋ฐ Alamofire์— form-data ํ˜•์‹์œผ๋กœ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ์žˆ์—ˆ๋‹ค!!!! ํ‰์†Œ ํ•˜๋˜ ๊ฒƒ์ฒ˜๋Ÿผ(line 8์— ์ฃผ์„ ์ฒ˜๋ฆฌํ•œ ๋ถ€๋ถ„) request๋ฅผ ๋ณด๋‚ด๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ, ์„œ๋ฒ„์— ์—…๋กœ๋“œํ•˜๋Š” ๊ฐœ๋…์ธ ๋“ฏ. ์•„๋ฌดํŠผ multipartFormData ํ™œ์šฉํ•ด์„œ ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ ๋„ฃ์—ˆ๋”๋‹ˆ ์ œ๋Œ€๋กœ ์š”์ฒญ์ด ์ „์†ก๋๋‹ค. ๐Ÿฅบ //MARK: SMS request // API ํ˜ธ์ถœ let paramForSMS:Parameters = ["userphonenum": phoneField.text] let url = "์—ฌ๊ธฐ์— url ์ฃผ์†Œ ..

    [UIKit] ๊ฐ„๋‹จํ•œ toast message, ํ™•์ธ ๋ฒ„ํŠผ๋งŒ ์žˆ๋Š” alert ์˜ˆ์ œ

    extension UIViewController { func alert(_ message: String, completion: (()->Void)? = nil) { DispatchQueue.main.async { let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) let okAction = UIAlertAction(title: "ํ™•์ธ", style: .cancel) { (_) in completion?() } alert.addAction(okAction) self.present(alert, animated: false) } } } ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ์•„๋ฌด๋ฐ์„œ๋‚˜ self.alert("์•Œ๋ฆผ๋ฉ”์‹œ์ง€!!!") ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ..